socket.io
socket.io copied to clipboard
uWebSockets.js not working with msgpack parser
Describe the bug
Combining a uWebSockets.js app using the io.attachApp() with the msgpack parser (socket.io-msgpack-parser) does not work. Under the following conditions I'm experiencing different behavior:
- When connecting the client and not specifying the
transportsoption, the upgrade will work to connect but the messages are only base64 encoded rather than binary - When connecting the client and specifying
transports: ['websocket']only, the connection handshake cannot complete and continuous reconnections are attempted by the client. The messages do appear to be binary however.
To Reproduce
Please fill the following code example:
Socket.IO server version: 4.6.1
Socket.IO msgpack Parser version: 3.0.2
uWebSockets.js version: uWebSockets.js@uNetworking/uWebSockets.js#v20.20.0
Server
import { Server } from "socket.io";
import { App } from "uWebSockets.js";
import customParser from 'socket.io-msgpack-parser';
const io = new Server();
const app = new App();
io.attachApp(app, {
serveClient: false,
parser: customParser,
cors: environment.cors,
maxHttpBufferSize: 3.2e8,
});
io.on("connection", (socket) => {
console.log('connected:', socket.id);
setTimeout(() =>
socket.emit('hello', { say: 'hello world!'}),
2000,
);
socket.on('error', err => console.error('socket:', err));
socket.on('disconnecting', (reason, desc) => console.log({ reason, desc }));
socket.on('disconnect', (reason, desc) => console.log('disconnect:', { reason, desc }));
});
io.on('error', console.error);
app.listen(3000, (token) => {
if (!token) {
console.warn("port already in use");
} else {
console.log('open for business!! :rocket:');
}
});
Socket.IO client version: 4.6.1
Socket.IO msgpack Parser version: 3.0.2
Client
import { io } from "socket.io-client";
import customParser from 'socket.io-msgpack-parser';
const socket = io("ws://localhost:3000/", {
withCredentials: true,
parser: customParser,
// transports: ["websocket"] // uncomment for websocket-only transport
});
socket.on("connect", () => {
console.log(`connect ${socket.id}`);
});
socket.on('disconnect', (reason, desc) => console.log({ reason, desc }));
Expected behavior
Whether specifying transports option or not on the client, the socket will connect, perform the handshake successfully and messages will be passed back and forth in binary encoding.
Platform:
- Device: MacBook Pro 2020 M1
- OS: MacOS Ventura 13.2.1
- Browser: Chrome
Additional context
The Client will repeatedly print transport close disconnect logs but the Server logs nothing.
When I close the browser tab the client is executing in, then I will see the disconnect log on the Server.
The parser works with plain socket.io.Server and when wrapping the built-in Node.js HttpServer in my testing.
Hi! I think that's because the parser option is ignored when calling attachApp(). Could you please try with:
import { Server } from "socket.io";
import { App } from "uWebSockets.js";
import customParser from 'socket.io-msgpack-parser';
- const io = new Server();
+ const io = new Server({
+ serveClient: false,
+ parser: customParser,
+ cors: environment.cors,
+ maxHttpBufferSize: 3.2e8,
+ });
const app = App();
- io.attachApp(app, {
- serveClient: false,
- parser: customParser,
- cors: environment.cors,
- maxHttpBufferSize: 3.2e8,
- });
+ io.attachApp(app);
Something is wrong with the types though, let me check.
thanks @darrachequesne - how did you figure out the parser option is ignored when calling attachApp()? Is it getting lost in the initialization of the engine.io engine?
Before submitting the issue, I saw these lines in index.ts:450-458 and concluded it doesn't matter which way I pass the options, either via Server constructor or the attachApp() function.
Also to ensure it wasn't a difference, I tested both ways of initializing the Server and only posted the code sample that was the last one I tried.
@darrachequesne I was able to get it to work with a different parser using the suggestion in this issue https://github.com/skgdev/socket.io-msgpack-javascript/issues/15
but only when using websocket only (no upgrade) does it encode binary from the server
It seems there is an issue in the parser here: https://github.com/skgdev/socket.io-msgpack-javascript/issues/15
The client sends { type: 0, data: undefined, nsp: '/' } but the server decodes { type: 0, data: null, nsp: '/' } and closes the connection because data should either be undefined or an object.
Related: https://github.com/socketio/socket.io/pull/4675