问题
I'm trying to use elephant.io to send event from my PHP script to my nodejs server. Performing tests with this library I've noticed that the handshake was not happening as expected.
After reading the specs about client-server handshake with socket.io, I've tested a simple handshake request to my nodejs server:
POST "http://acme.local:3700/socket.io/1"
But this is returning the following JSON message:
{
"code": 0,
"message": "Transport unknown"
}
I'm not sure if this error is due to the version of socket.io I'm using (v1.0.2) or if the handshake request is simply malformed.
回答1:
The problem is socket.io v1.0.x revamped its transport layer. In 0.9.x, socket.io tries to establish a websocket connection firstly and fall back to polling if websocket is blocked, timeout, etc. So you can download a websocket configuration string like "sid:interval_time:timeout_time:..." from schema://addr:port/socket.io/1/.
However, in v.1.0.x, the client has to establish a polling transportation first, which is widely supported, then upgrade to websocket. And the transport configuration is formatted in json via: schema://addr:port/socket.io/?transport=polling. The json object looks like {"sid":"xxx", "upgrade":["websocket",..],"pingInterval":xxx,"pingTimeout":xxx}.
So any client works for v0.9.x can't communicate with v1.0.x. There is a temporary fix for elephant.io: https://github.com/Wisembly/elephant.io/pull/53/files#diff-8f2bc4c2d1b3889bc393b67f296edbc5R97 . However I can't get it to work.
Presumably all 3rd-party clients for socket.io v1.0.x nowadays are full-port of its JavaScript code. I tried to fix socketio4net according to the elephant.io post above but failed.
Update on 08/26.
Here's what I got:
How to communicate with socket.io v1.0 server:
GET http[s]://host:port/socket.io/?transport=polling
Server responds a JSON config string in response body with some unknown characters as header.
Warning for c-style char* useres: this string begins with '\0'.
The string looks like: \0xxxx {"sid":"xxx", "upgrades":["websocket","polling",..], pingInterval:xxxx, pingTimeout:xxxx}.
sid: seesion id for websocket connection.
upgrades: available transport method. Please make sure "websocket" is one of them.
pingInterval & pingTimeout: ping server every pingInterval and check for pong within pingTimeout.
Establish websocket connection at ws[s]://host:port/socket.io/?transport=websocket&sid=sid
Send string "52" to socket.io server upon successful connection.
Listen on server message, waiting for string "40" to confirm websocket link between client and server.
Send any other commands you setup on sever.
Note:
v1.0 changed its message transport format to engine.io_type + socket.io_type + real_message_in_json. (I don't know where endpoint in v0.9 kicks in.)
engine.io message type:
- open =0
- close =1
- ping =2
- pong =3
- message =4
- upgrade =5
- noop =6
socket.io message type:
- connect = 0
- disconnect = 1
- event = 2
- ack = 3
- error = 4
- binary_event = 5
- binary_ack = 6
So, "52" means UPGRADE_EVENT and "40" is MESSAGE_CONNECT. Typically, server messages start with "42", which is MESSAGE_EVENT. PING and PONG don't require a socket.io message. I wonder if UPGRADE works like that too.
Get a working websocket client and you are good to go!
P.S. elephant.io 3.0 is on the way, which supports v1.0.
回答2:
Reverting to socket.io v0.9.x
fix the issue.
Apparently the handshake changed in v1.0.x
but I cannot find any documentation yet
回答3:
I got the same problem and this is my solution:
io.connect('localhost', {transport:'polling'});
来源:https://stackoverflow.com/questions/23987640/socket-io-handshake-return-error-transport-unknown