-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathsocket.io-server.js
154 lines (103 loc) · 3.4 KB
/
socket.io-server.js
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// require socket.io module
const port = 9000;
const io = require('socket.io')(port);
// stores user states per room
const states = {};
// stores published messages per room
const history = {};
// saves state to ```states``` variable
const saveState = function(channel, uuid, state) {
// since this is per channel, create channel object if doesn't exist
if(!states[channel]) {
states[channel] = {};
}
// save state to the channel based on user uuid
states[channel][uuid] = state;
// return given state
return state;
}
// saves published messages to ```history``` variable
const saveHistory = function(channel, uuid, data) {
// create an array for this channel if it doesn't exist
if(!history[channel]) {
history[channel] = [];
}
// push the newest uuid and data to the front of the array
history[channel].unshift({uuid: uuid, data: data});
// if we have more than 100 messages for this channel, remove the first
if(history[channel].length > 100) {
history[channel].pop();
}
// return the entire history
return history[channel];
}
let socketChannels = {};
// when a new rltm.js user connects
io.on('connection', function (socket) {
// when the user calls rltm.join() this is called
socket.on('channel', function (channel, uuid, state) {
// have the socket join the channel
socket.join(channel);
// save the initial state sent with the user
saveState(channel, uuid, state);
// send the 'join' event to everyone else in the channel
io.to(channel).emit('join', channel, uuid, state);
socketChannels[socket.id] = socketChannels[socket.id] || [];
socketChannels[socket.id].push({
channel: channel,
uuid: uuid
});
});
// user sets the state
socket.on('setState', function (channel, uuid, state, fn) {
// save the set state into the server memory
saveState(channel, uuid, state);
// tell all other users state was set
io.to(channel).emit('state', channel, uuid, state);
fn();
});
// user emits a message
socket.on('publish', function (channel, uuid, data, fn) {
// save the message to the history array in memory
saveHistory(channel, uuid, data);
// tell all other users of the new message
io.to(channel).emit('message', channel, uuid, data);
fn();
});
// user wants to know whos online
socket.on('whosonline', function (channel, data, fn) {
// respond with what we know about the current users for this channel
if(!states[channel]) {
fn({});
} else {
fn(states[channel]);
}
});
// user wants the history for this channel
socket.on('history', function (channel, fn) {
// respond with history array if it exists
if(!history[channel]) {
fn([]);
} else {
fn(history[channel]);
}
});
// user disconnects manually
socket.on('leave', function(uuid, channel, fn) {
if (states[channel] && states[channel][uuid]) {
delete states[channel][uuid];
}
// call tell socket.io to disconnect
socket.leave(channel);
fn();
});
socket.on('disconnect', function() {
socketChannels[socket.id].forEach(function(data) {
if (states[data.channel] && states[data.channel][data.uuid]) {
delete states[data.channel][data.uuid];
}
io.to(data.channel).emit('disconnect', data.channel, data.uuid);
});
});
});
console.log('rltm.js - socket.io server running on port', port)