In an effort to be able to send binary data while utilizing Socket.IO's RPC functionality, I thought that I could use both Socket.IO and the WS module on the same server. Rather than opening up completely separate servers to make both connections, I am wondering if I can utilize the same HTTP server.
Is it possible to use only one server created with http.createServer()
for both Socket.IO and WS at the same time? To be clear, I anticipate creating both a Socket.IO connection and a regular WebSocket connection from the client. The following code creates protocol errors on the client side, presumably because both Socket.IO and WS are attempting to handle the connection.
var http = require('http');
var server = http.createServer(app);
server.listen(3000);
// Socket.IO
var io = require('socket.io').listen(server);
io.sockets.on('connection', function (socket) {
// ...
}
// ws
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({server: server});
wss.on('connection', function (ws) {
// ...
}
Although Socket.IO indeed uses WebSocket for transport when possible, it adds additional metadata to each packet. That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a plain WebSocket server either.
Yes, this is possible. To do this, pass your websocket URL to the socket.io client directly, like this: var socket = io('wss://example.com/');
Socket.IO is way more than just a layer above WebSockets, it has different semantics (marks messages with name), and does failovers to different protocols, as well has heartbeating mechanism. More to that attaches ID's to clients on server side, and more. So it is not just a wrapper, it is full-featured library.
A server can open WebSocket connections with multiple clients—even multiple connections with the same client. It can then message one, some, or all of these clients. Practically, this means multiple people can connect to our chat app, and we can message some of them at a time.
It turns out that this is possible with some configuration. The trick is to tell Socket.IO not to destroy non-Socket.IO WebSocket connection requests, and then to put Socket.IO and WS on separate paths. Here is some messy example code, but it works while reusing the Socket.IO session ID for the secondary connection.
var server = http.createServer(app);
server.listen(3000);
var WebSocketServer = require('ws').Server
var io = require('socket.io').listen(server);
io.set('destroy upgrade', false);
io.set('transports', ['websocket']);
io.sockets.on('connection', function (socket) {
var wss = new WebSocketServer({
server: server,
path: '/anythingYouWant/' + socket.id
});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
console.log(message);
});
});
});
As of 2016 I simply could assign the websocket module ws a path
var wss = new WebSocketServer({ server: server, path: '/ws' }); //do not interfere with socket.io
No need to alter the socket.io side at all
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With