-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsocket.js
More file actions
140 lines (118 loc) · 5.02 KB
/
Copy pathsocket.js
File metadata and controls
140 lines (118 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { Poll } from "./models/poll.js";
import { Vote } from "./models/vote.js";
export function setupIO(io) {
io.use(async (socket, next) => {
try {
const { pollId, userId } = socket.handshake.query || {};
if (!pollId || !userId) {
console.error('Missing pollId or userId in handshake');
return next(new Error("Missing pollId or userId"));
}
const poll = await Poll.findById(pollId);
if (!poll) {
console.error(`Poll not found: ${pollId}`);
return next(new Error("Poll not found"));
}
if (poll.isPrivate) {
const isAllowed = poll.allowedUsers.includes(userId) ||
poll.createdBy.toString() === userId;
if (!isAllowed) {
console.error(`Access denied for user ${userId} to poll ${pollId}`);
return next(new Error("Access Denied"));
}
}
socket.poll = poll;
socket.userId = userId;
next();
} catch (error) {
console.error('Socket middleware error:', error);
next(error);
}
});
io.on("connection", async (socket) => {
try {
const poll = socket.poll;
const userId = socket.userId;
const roomId = poll._id.toString();
// User ${userId} connected to poll ${roomId}
// Join the poll room
await socket.join(roomId);
// User ${userId} joined room: ${roomId}
// Send initial poll data
const votes = await Vote.find({ pollId: poll._id });
const totalVotes = votes.length;
const results = poll.options.map((option, index) => {
const optionVotes = votes.filter(v => v.optionIndex === index).length;
return {
option,
votes: optionVotes,
percentage: totalVotes > 0 ? (optionVotes / totalVotes) * 100 : 0
};
});
// Send initial results to the newly connected client
socket.emit('initialResults', {
pollId: roomId,
results,
totalVotes,
hasVoted: votes.some(v => v.userId === userId)
});
// Handle vote submission
socket.on('vote', async (data) => {
try {
const { optionIndex } = data;
// Check if user already voted
const existingVote = await Vote.findOne({
pollId: poll._id,
userId: userId
});
if (existingVote) {
return socket.emit('voteError', {
message: "You already voted on this poll"
});
}
// Create new vote
await Vote.create({
userId,
pollId: poll._id,
optionIndex
});
// Get updated votes and results
const updatedVotes = await Vote.find({ pollId: poll._id });
const updatedTotalVotes = updatedVotes.length;
const updatedResults = poll.options.map((option, index) => {
const optionVotes = updatedVotes.filter(v => v.optionIndex === index).length;
return {
option,
votes: optionVotes,
percentage: updatedTotalVotes > 0 ? (optionVotes / updatedTotalVotes) * 100 : 0
};
});
// Broadcast to all clients in the room
const voteData = {
pollId: roomId,
results: updatedResults,
totalVotes: updatedTotalVotes,
voterId: userId,
voterOptionIndex: optionIndex
};
// Broadcasting vote:
io.to(roomId).emit('vote', voteData);
} catch (error) {
console.error('Error processing vote:', error);
socket.emit('voteError', {
message: error.message || 'Failed to process vote'
});
}
});
// Handle disconnection
socket.on('disconnect', () => {
// User ${userId} disconnected from poll ${roomId}
});
} catch (error) {
console.error('Connection error:', error);
socket.emit('error', {
message: error.message || 'Connection error'
});
}
});
}