27
votes

Trying to use socket.io-client to connect to a websocket server that is written in Go. I've successfully connected using the node WebSocket library (npm). So the working Websocket code looks like:

  goSocketPort = 6060
  url = "ws://localhost:#{goSocketPort}/streamresults/"
  ws = new WebSocket(url)

  ws.on('open', ->
    log "socket opened"
  )

  ws.on('message', (message) ->
      console.log('received: %s', message)
    #log "Socket message: #{JSON.stringify message}"
  )

Pretty easy and it works -- the socket on the other end sends messages on a set frequency. But I initially tried with socket.io-client (npm) and just couldn't get it to go. It certainly lists websocket as its first-preference transport, but damn if I can get it to connect:

socket = ioClient.connect("#{url}", {port: goSocketPort, transports: ['xhr-polling', 'websocket']}) 

socket.on("connect", (r) ->
  log "connected to #{url}"
)

The connection never happens, so none of the on events are fired and the code exits right away. I've tried: leaving the port off the url and adding it in the options, leaving off the transports option (which means "all" according to the docs) and using an http url. Is socket-io.client not capable of connecting to a "standard" websocket?

2
Have you looked at your network traffic? Socket.io attempts a http handshake before deciding which transport to use; you're probably not responding to the handshake req correctly. - Aaron Dufour
So you're thinking I'll need to add code to my socket server to get it to work with the socket.io client? - jcollum
You might be better off not using the socket.io client - what are you using it for? - Aaron Dufour
Getting messages over a websocket on a periodic (minutes) basis. More than anything I'm curious why this is easy using WebSocket but apparently not easy using Socket-io.client, since I thought SIO was a wrapper for Websocket. - jcollum
Socket.io is a fairly heavy wrapper. It does transport negotiation, handles a half-dozen or so transports, message types, pings, etc. You're probably going to have to implement large portions of the socket.io server in order to use the client. Why not just use bare WebSockets? - Aaron Dufour

2 Answers

45
votes

Based on our chat, it looks like you were misled by this quote:

The socket.io client is basically a simple HTTP Socket interface implementation. It looks similar to WebSocket while providing additional features and leveraging other transports when WebSocket is not supported by the user's browser.

What this means is that it looks similar to WebSocket from the perspective of client/server code that interacts with the Socket.io client/server. However, the network traffic looks very different from a simple WebSocket - there's an initial handshake in addition to a more robust protocol built on top of WebSocket once that's connected. The handshake is described here and the message protocol here (both are links to the Socket.IO protocol spec).

If you're writing a WebSocket server, you're better off just using the bare WebSocket interface rather than the Socket.io client, unless you intend to implement all of the Socket.io protocol.

1
votes

Not sure if this was the case at the time, but socket.io's website now states this directly in the docs.

Although Socket.IO indeed uses WebSocket as a 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.

https://socket.io/docs/