I have a Node.js server which utilizes the popular ws
package for using web sockets. I'd like to use this library to connect to an third party server which is running socket.io.
If I were to use socket.io on my server, the connection code would be something like this:
const socket = socketIo('https://api.example.com/1.0/scores')
I've attempted to connect to the same service using the ws
package, and modifying the url:
const wsClient = new WebSocket('wss://api.example.com/1.0/scores');
but this results in the following:
Error: Unexpected server response: 200
Question: What needs to be done to connect to a third party server running socket.io from a server running the ws
package?
Additional Info:
- I've noticed in my searches that some people have suggested appending
/socket.io/?EIO=3&transport=websocket
to the end of the url. This does not throw the same error as above (> Error: Unexpected server response: 200
) nor throw any visible error, but does not appear to work (no data is received from the remote server). Using
new WebSocket('ws://api.example.com/1.0/scores?EIO=3&transport=websocket');
to open the connection (viaws
) results in the following stack trace:{ Error: Parse Error at Socket.socketOnData at emitOne at Socket.emit // ... }
2 Answers
Answers 1
Because Socket.IO doesn't guarantee that there will be a WebSockets server hosted like you're seeming to expect, you should instead use their standard client package.
npm i socket.io-client
Then use the package in your code:
const ioClient = require('socket.io-client')('https://example.com/1.0/scores')
The full docs for socket.io-client are available on their GitHub repo.
Note: Honestly, though, it's just better at this point to use WebSockets instead if possible. WebSockets has become very well supported in browsers and is quite standard. Socket.IO is rarely necessary and is just bulky.
Answers 2
The socket.io api utilizes websockets but it also has a lot of other functions built on top of it in order to do things such as HTTP handshakes, session ids, and it can even handle fail overs to other protocols when needed.
You got half of the issue so far. Adding the line socket.io/?EIO=3&transport=websocket
you're specifying parameters for the socket.io server to take.
EIO=3
specifies the version number for engine.io in which socket.io is using. In this case you are saying engine.io version = 3
transport=websocket
specifies which transport protocol to use. As i said earlier, socket.io uses other protocols in cases such as fail overs. This portion forces socket.io to use websocket as the preferred protocol.
Now the next half is the WebSocket api itself. WebSocket allows for Extensions which includes different kinds of compression that are commonly used when sending data. Which I believe is what is causing your Parse Error
Try this (found here):
const WebSocket = require('ws'); const ws = new WebSocket('ws://server/socket.io/?EIO=3&transport=websocket', { perMessageDeflate: false });
By setting perMessageDeflate: false you are specifying "Do not compress data". Since as i said this is a WebSocket Extension there are different variations as well. Try these instead if it doesn't work
- x-webkit-deflate-frame
- perframe-deflate
As a disclaimer this information is from the research that I have done. Im not a "socket.io specialist" so if there's anything i got wrong or missed please tell me and i'll edit the post.
0 comments:
Post a Comment