Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect to a socket.io server from a Node.js server using the 'ws' package

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 (via ws) results in the following stack trace:

    { Error: Parse Error
        at Socket.socketOnData 
        at emitOne 
        at Socket.emit 
        // ... 
    }
    
like image 387
Orbit Avatar asked Apr 26 '18 08:04

Orbit


People also ask

Which is better Socket.IO or WS?

Both WebSocket vs Socket.io are popular choices in the market; let us discuss some of the major Difference Between WebSocket vs Socket.io: It provides the Connection over TCP, while Socket.io is a library to abstract the WebSocket connections. WebSocket doesn't have fallback options, while Socket.io supports fallback.

How do I connect to a WebSocket?

In order to communicate using the WebSocket protocol, you need to create a WebSocket object; this will automatically attempt to open the connection to the server. The URL to which to connect; this should be the URL to which the WebSocket server will respond.


2 Answers

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. 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 incorrect please comment and i'll edit the post.

like image 93
Plee Avatar answered Oct 04 '22 20:10

Plee


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 well-supported in browsers and is quite standard. Socket.IO is rarely necessary and could add some overhead.

like image 35
ethnanon Avatar answered Oct 04 '22 20:10

ethnanon