0

I have created a WebSocket server using socket.io. I have the following code

const express = require('express');
const socket = require('socket.io');

const app = express();

app.get('/socketTest', async (request, response) => {
  io.sockets.in('testRoom1').emit('message', 'my message sample1');
  response.send('Sample message sent via websocket');
});

const server = app.listen(3000, () => {});
const io = socket(server, {});

io.use(function(socket, next) {next();}).on('connection', function(client) {
  client.on('subscribe', function(room) {
    client.join(room.toLowerCase());
  })
  client.on('unsubscribe', function(room) {
    client.leave(room.toLowerCase());
  })
});

But after deploying my server on the different cluster, I didn't get the messages in the client properly.

So, I have added a Redis adapter using socket.io-redis library.

const express = require('express');
const socket = require('socket.io');
const redisAdapter = require('socket.io-redis');

const app = express();

app.get('/socketTest', async (request, response) => {
  io.sockets.in('testRoom1').emit('message', 'my message sample1');
  response.send('Sample message sent via websocket');
});

const server = app.listen(3000, () => {});
const io = socket(server, {});
io.adapter(redisAdapter({host: 'localhost', port: 6379}));

io.use(function(socket, next) {next();}).on('connection', function(client) {
  client.on('subscribe', function(room) {
    client.join(room.toLowerCase());
  })
  client.on('unsubscribe', function(room) {
    client.leave(room.toLowerCase());
  })
});

I got an error when trying to send a message from the server to clients.

http://localhost:3000/socketTest?roomname=testRoom1

(node:15304) UnhandledPromiseRejectionWarning: TypeError: callback is not a function
    at Encoder.encode (E:\testProject\node_modules\socket.io-parser\index.js:135:5)
    at RedisAdapter.broadcast (E:\testProject\node_modules\socket.io-redis\node_modules\socket.io-adapter\dist\index.js:102:45)
    at RedisAdapter.broadcast (E:\testProject\node_modules\socket.io-redis\dist\index.js:267:15)
    at Namespace.emit (E:\testProject\node_modules\socket.io\lib\namespace.js:234:16)
    at E:\testProject\index.ts:38:21
    at Generator.next (<anonymous>)
    at E:\testProject\index.ts:8:71
    at new Promise (<anonymous>)
    at __awaiter (E:\testProject\index.ts:4:12)
    at E:\testProject\index.ts:36:52

Any idea about this error? Is anything I have missed?

Abdul Manaf
  • 4,933
  • 8
  • 51
  • 95
  • Why do you say: " got an error when trying to send a message through WebSocket." You can't use a webSocket connection to a socket.io server. – jfriend00 Mar 05 '21 at 16:58
  • The issue with io.sockets.in('testRoom1').emit('message', 'my message sample1'); – Abdul Manaf Mar 05 '21 at 16:59
  • Did you implement both of the things listed here: https://socket.io/docs/v3/using-multiple-nodes/index.html. You will need a sticky session to use socket.io with nodejs clusters. – jfriend00 Mar 05 '21 at 19:18
  • Also, please do not use the terms webSocket and socket.io interchangeably. They are NOT the same. A socket.io connection runs on top of a webSocket transport, but only a socket.io client can connect to a socket.io server. The first sentence of your question looks confused in that regard. I don't know if that's causing a problem or you just used the wrong term in your question. – jfriend00 Mar 05 '21 at 19:20

1 Answers1

0

This construct:

io.use(function(socket, next) {})

is not correct. This is middleware. If you call io.use() and want regular processing to continue, you have to call next() in the body of the function you are passing it. Since you're not apparently doing anything at all with this, you should probably just remove it.

If you wanted to actually use this middleware:

io.use(function(socket, next) {
    // do something here, then call next()
    next();
});

Without calling next(), you're stalling every incoming connection.

jfriend00
  • 683,504
  • 96
  • 985
  • 979