forked from takayukii/example-socket.io-emitter-redis
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
127 lines (114 loc) · 3.58 KB
/
Copy pathserver.js
File metadata and controls
127 lines (114 loc) · 3.58 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
import os from 'os';
import process from 'process';
import Koa from 'koa';
import serve from 'koa-static';
import bodyParser from 'koa-bodyparser'
import RedisHelper from './redis-helper';
const REDIS_HOST = 'localhost';
const REDIS_PORT = 6379;
const app = new Koa();
const router = require('koa-router')();
app.use(serve('./public'));
app.use(router.routes());
/**
* Server
*/
const port = process.argv[2];
const server = app.listen(port);
console.log(`Listening ${port}...`);
/**
* Redis
*/
const redis = require('redis').createClient;
const emitter = require('socket.io-emitter')({
host: REDIS_HOST,
port: REDIS_PORT
});
const redisAdapter = require('socket.io-redis')({
host: REDIS_HOST,
port: REDIS_PORT,
pubClient: redis(REDIS_PORT, REDIS_HOST),
subClient: redis(REDIS_PORT, REDIS_HOST)
});
const helper = new RedisHelper({
client: redis(REDIS_PORT, REDIS_HOST),
process: `${os.hostname()}.${process.pid}`
});
helper.init(`*::proc::${helper.process}::*`);
/**
* Socket.io
*/
const io = require('socket.io').listen(server);
io.adapter(redisAdapter);
/**
* Events
*/
io.on('connection', (socket) => {
console.log('[SOCKET] connection', 'socket', socket.id);
socket.on('disconnect', async () => {
console.log('[SOCKET] disconnect', 'socket', socket.id);
await disconnect(helper, socket.id);
});
socket.on('change_room', async (req) => {
const {roomId} = req;
console.log('[SOCKET] change_room', 'socket', socket.id);
await disconnect(helper, socket.id);
linkSocketAndRoom(helper, socket.id, roomId);
})
});
/**
* Routing
*/
router.post('/message', bodyParser(), async (ctx, next) => {
const {token, roomId, message} = ctx.request.body;
console.log('[POST] /message', roomId, message);
await fetchSocketIdsByRoomId(helper, roomId)
.then(socketIds => {
console.log(`> sockets in the room '${roomId}'`, socketIds);
ctx.body = `<p>Sent message to socket ids [${socketIds.join(', ')}]</p>`;
socketIds.forEach((socketId) => {
emitter.to(socketId).emit('push_message', `${message} - ${new Date()}`);
});
})
.catch(err => {
console.log(err);
ctx.body = err;
});
})
// ------------------
async function disconnect(helper, socketId) {
console.log('> disconnect()', socketId);
const roomIds = await fetchRoomIdsBySocketId(helper, socketId)
console.log('> roomIds', roomIds);
roomIds.forEach(roomId => {
unlinkSocketAndRoom(helper, socketId, roomId);
})
}
// socket - room
function linkSocketAndRoom (helper, socketId, roomId) {
console.log('> linkSocketAndRoom()', socketId, roomId);
helper.set(`socket::${socketId}::proc::${helper.process}::room`, roomId);
// key をユニークにするため、key の中にも socketId を含ませる(room は複数の socket を持てる)
helper.set(`room::${roomId}::socket::${socketId}::proc::${helper.process}::socket`, socketId);
}
function unlinkSocketAndRoom (helper, socketId, roomId) {
console.log('> unlinkSocketAndRoom()', socketId, roomId);
helper.del(`socket::${socketId}::proc::${helper.process}::room`);
helper.del(`room::${roomId}::socket::${socketId}::proc::${helper.process}::socket`);
}
// room(s) <- socket
async function fetchRoomIdsBySocketId (helper, socketId) {
console.log('> fetchRoomIdsBySocketId()', socketId);
if (!socketId) {
return [];
}
return await helper.fetch(`socket::${socketId}::*::room`);
}
// sockets <- room
async function fetchSocketIdsByRoomId (helper, roomId) {
console.log('> fetchSocketIdsByRoomId()', roomId);
if (!roomId) {
return [];
}
return await helper.fetch(`room::${roomId}::*::socket`);
}