I have a very simple node app that uses socket.io. When I connect to the server from an external client it works fine. However, when I attempt to render UI using a browser, the server crashes on TypeError from Receiver.unmask.
My server code:
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
const PORT = process.env.PORT || 8080;
app.use(express.static('public/dashboard'));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/public/dashboard/index.html');
});
io.on('connection', (client) => {
console.log('Client connected');
client.on('disconnect', () => console.log('Client disconnected'));
});
// broadcast PING to all connected sockets
// hoping to hear back from bots
setInterval(() => io.emit('PING', new Date().toTimeString()), 5000);
http.listen(PORT, function(){
console.log(`listening on *:${PORT}`);
});
UI code:
bunch of HTML and JS
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
Error on node server side:
socket.io:socket socket connected - writing packet +4ms
socket.io:socket joining room Ipoywx491U9SrqRxAAAA +1ms
socket.io:client writing packet {"type":0,"nsp":"/"} +1ms
socket.io-parser encoding packet {"type":0,"nsp":"/"} +2s
socket.io-parser encoded {"type":0,"nsp":"/"} as 0 +0ms
engine:socket sending packet "message" (0) +10ms
socket.io:socket joined room Ipoywx491U9SrqRxAAAA +4ms
engine upgrading existing transport +16ms
engine:socket might upgrade socket transport from "polling" to "websocket" +1ms
[my_workspace]/node_modules/ws/lib/Receiver.js:306
if (mask != null && buf != null) bufferUtil.unmask(buf, mask);
^
TypeError: Cannot read property 'unmask' of undefined
at Receiver.unmask ([my_workspace]/node_modules/ws/lib/Receiver.js:306:46)
at Receiver.finish ([my_workspace]/node_modules/ws/lib/Receiver.js:505:25)
at Receiver.expectHandler ([my_workspace]/node_modules/ws/lib/Receiver.js:493:33)
at Receiver.add ([my_workspace]/node_modules/ws/lib/Receiver.js:103:24)
at Socket.realHandler ([my_workspace]/node_modules/ws/lib/WebSocket.js:825:20)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
at TCP.onread (net.js:548:20)
Error in UI:
engine.io-client:socket probe transport "websocket" opened +132ms
universalModuleDefinition:1 engine.io-client:polling polling got data ArrayBuffer +3ms
universalModuleDefinition:1 engine.io-client:socket socket receive: type "message", data "0" +1ms
universalModuleDefinition:1 socket.io-parser decoded 0 as {"type":0,"nsp":"/"} +0ms
universalModuleDefinition:1 engine.io-client:polling polling +5ms
universalModuleDefinition:1 engine.io-client:polling-xhr xhr poll +0ms
universalModuleDefinition:1 engine.io-client:polling-xhr xhr open GET: http://localhost:8080/socket.io/?EIO=3&transport=polling&t=LfNIZqL&sid=LZfZtocuqb1C9V0fAAAA +1ms
universalModuleDefinition:1 engine.io-client:polling-xhr xhr data null +1ms
universalModuleDefinition:1 engine.io-client:socket probe transport "websocket" failed because of error: transport closed +20ms
VM445:2 GET http://localhost:8080/socket.io/?EIO=3&transport=polling&t=LfNIZqL&sid=LZfZtocuqb1C9V0fAAAA net::ERR_CONNECTION_REFUSED
(anonymous) @ VM445:2
i.create @ universalModuleDefinition:2
i @ universalModuleDefinition:2
o.request @ universalModuleDefinition:2
o.doPoll @ universalModuleDefinition:2
n.poll @ universalModuleDefinition:2
n.onData @ universalModuleDefinition:2
(anonymous) @ universalModuleDefinition:2
n.emit @ universalModuleDefinition:2
i.onData @ universalModuleDefinition:2
i.onLoad @ universalModuleDefinition:2
hasXDR.r.onreadystatechange @ universalModuleDefinition:2
universalModuleDefinition:1 engine.io-client:socket socket error {"type":"TransportError","description":0} +13ms
universalModuleDefinition:1 socket.io-client:manager error +5ms Error: xhr poll error
at o.n.onError (universalModuleDefinition:2)
at i.<anonymous> (universalModuleDefinition:2)
at i.n.emit (universalModuleDefinition:2)
at i.onError (universalModuleDefinition:2)
at universalModuleDefinition:2
universalModuleDefinition:1 engine.io-client:socket socket close with reason: "transport error" +8ms
Using Node v6.8.1, socket.io 1.7.3 that uses [email protected].
Is this a known issue or am I missing something obvious?
Do you have bufferutil as dependency? If so make sure to use bufferutil@1, bufferutil@2 is compatible only with ws@>=2.0.2.
That was it! Thanks @lpinca
This is really annoying. Why isn't bufferutils a dependency instead of a devDependency?
For the simple reason that binary module don't work everywhere. Adding it as dependency could cause the whole installation of the project fail. It's an optional dependency. But even adding it as optional dependency, if the compilation fails the whole installed dies. So the only solution is to have users install it manually if they want to use the binary addons.
Thanks for your prompt response!
Maybe I should open a new issue. I run into this on a clean install of express and socket.io. I wasn't aware that this lib was being used under the hood, and even less aware that there was an option for binary addons.
For some reason bufferUtils is undefined (the fallback did not work, same stack trace as the OP). I suspect that another package installed bufferutils@2 and somehow that caused the error. But this definitely should not break.
@eordano the problem is that engine.[email protected] has a pinned version of ws.
If they upgrate to version [email protected] the issue should disappear.
Thanks! I'll ping them.
"ws": "2.2.3"
Client connected -> error:
C:\Projects\NodeJs\WebStormProjects\WebSockets\node_modulesengine.io\node_modulesws\lib\Receiver.js:306
if (mask != null && buf != null) bufferUtil.unmask(buf, mask);
"dependencies": {
"bufferutil": "3.0.0",
"express": "4.15.2",
"socket.io": "1.7.3",
"utf-8-validate": "3.0.1",
"ws": "2.2.3"
}
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var PORT = process.env.PORT || 3000;
// Routing
app.use(express.static(__dirname + '/public'));
server.listen(PORT, function () {
console.log('Server listening at port %d', PORT);
});
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('disconnect', () => console.log('Client disconnected'));
setInterval(() => socket.emit('time', new Date().toTimeString()), 1000);
});
@YuliyF [email protected] depends on [email protected] which depends on [email protected].
Ping them on https://github.com/socketio/engine.io/pull/495 to have this fixed.
I've that in my package.json:
"optionalDependencies": {
"bufferutil": "^3.0.2",
"utf-8-validate": "^3.0.3"
}
and "ws": "^3.0.0" in dependencies
It still doesn't working
@anamanuel if your other dependencies like engine.io require an incompatible ws version it doesn't matter what you set. You should check what engine.io version you are using.
@lpinca the version of engine.io is - "version": "1.8.2"
But I don't have this dependency added to package.json
Yes, that doesn't work you need 1.8.4 or use bufferutil@1 and utf-8-validate@2.
Adding engine.io to your dependencies doesn't solve anything as it is a dependency of one or more of your other dependencies (karma).
Remove the optionalDependencies completely or use
"optionalDependencies": {
"bufferutil": "^1.0.0",
"utf-8-validate": "^2.0.0"
}
solved
Could you guys help me out with this? I have bufferutil@^4.0.1 and ws@^7.3.1 installed. Node version is 12.6.2
Other info and _package.json_ is here
Most helpful comment
Adding
engine.ioto your dependencies doesn't solve anything as it is a dependency of one or more of your other dependencies (karma).Remove the
optionalDependenciescompletely or use