Closed grahambunce closed 3 years ago
By default, the library will always try to connect to the server. OnReconnecting will be triggered when reconnecting; OnReconnectError will be triggered when reconnecting fails;
In your example, you registered the OnReconnectAttempt handler, is it triggered?
If it is triggered, you can set Reconncetion = false
for options, and the library will throw an exception after the connection fails.
Otherwise, you need to use a debugging tool like Fiddler to do some debugging. If you can provide the server code and delete the irrelevant code, I can help you find the problem quickly.
@doghappy No, the OnReconnectAttempt handler isn't triggered - none of the events I've subscribed to are. The call is made to ConnectAsync and then the whole app appears to freeze (unless it's just waiting for something) and the ConnectAsync never returns.
By server code, do you mean the socket.IO server we have running in node.js? If so then I'm not sure I can look into that, it's managed by another team in the company who we do not have access to.
In fiddler I can see this:
Request:
GET https://[redacted]/socket.io/?EIO=4&transport=polling&franchise_id=1&language_code=en HTTP/1.1
Host: [redacted]
Accept-Encoding: gzip, deflate
Response:
HTTP/1.1 200 OK
Server: nginx/1.19.1
Date: Fri, 17 Sep 2021 07:41:24 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 104
Connection: keep-alive
Set-Cookie: sddswsroute=1631864485.143.787.550324; Expires=Sun, 19-Sep-21 07:41:24 GMT; Max-Age=172800; Path=/; HttpOnly
Access-Control-Allow-Origin: *
Set-Cookie: io=wOuAvDB9Jj6yE0VrAL8N; Path=/; HttpOnly
97:0{"sid":"wOuAvDB9Jj6yE0VrAL8N","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":30000}2:40
and then nothing else afterwards, even if I leave it several minutes.
This is running under a .NET 5.0 background worker process in a console app.
I can be sure that your server uses socket.io v2.x.
If you don’t have permission to upgrade server socket.io, try using SocketIOClient v2.3.1, But it only supports ws, not http polling
private readonly SocketIO _client = new SocketIO("https://[redacted], new SocketIOOptions()
{
Query = new Dictionary<string, string>()
{
{ "franchise_id",FranchiseId.ToString()},
{"language_code","en"},
},
EIO = 3
});
@doghappy I've downloaded the latest code and am debugging through the client - I've replaced the sample code with my own to debug. This crashes - the code wasn't locking up after all - my exception handling failed to trap the error :(
I've also been told that my server was 2.2.0, so you are right, I need to use version 2.2.3 of the client.
In case it matters, the failing code is "TransportRouter", "ConnectAsync", line 80, i.e.
public async Task ConnectAsync()
{
...
int index = text.IndexOf('{');
string json = text.Substring(index);
var info = System.Text.Json.JsonSerializer.Deserialize<HandshakeInfo>(json);
The response it's dealing with is
97:0{"sid":"2pGY5F4FBQDDeVyiALts","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":30000}2:40
This gets converted to
{"sid":"2pGY5F4FBQDDeVyiALts","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":30000}2:40
which then forces the JSON parser to fall over with:
'2' is invalid after a single JSON value. Expected end of data. LineNumber: 0 | BytePositionInLine: 96.
I can fix this by changing/adding:
int index = text.IndexOf('{');
int lastIndexOf = text.LastIndexOf("}");
string json = text.Substring(index,(lastIndexOf - index) + 1);
This may not be necessary for a 3.x or 4.x server but just in case I wanted to record it
97:0{"sid":"2pGY5F4FBQDDeVyiALts","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":30000}2:40
This text contains 2 socket.io messages
97: message length
so first message is:
0: open
The second message is
2:40
2: message length 40: connected
This message format means that you are using socket.io-server v2.x and use http polling to send/receive messages.
Although you have modified the code, you will encounter other problems.
I can be sure that your server uses socket.io v2.x.
If you don’t have permission to upgrade server socket.io, try using SocketIOClient v2.3.1, But it only supports ws, not http polling
private readonly SocketIO _client = new SocketIO("https://[redacted], new SocketIOOptions() { Query = new Dictionary<string, string>() { { "franchise_id",FranchiseId.ToString()}, {"language_code","en"}, }, EIO = 3 });
Essentially, socket.io-server v2 uses engin.io v3, and socket.io-server v3/v4 uses engin.io v4.
They are very different
thanks for the feedback. We will use the older version of the package
97:0{"sid":"2pGY5F4FBQDDeVyiALts","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":30000}2:40
This text contains 2 socket.io messages
97: message length
so first message is:
0: open
The second message is
2:40
2: message length 40: connected
This message format means that you are using socket.io-server v2.x and use http polling to send/receive messages.
Although you have modified the code, you will encounter other problems.
I can be sure that your server uses socket.io v2.x. If you don’t have permission to upgrade server socket.io, try using SocketIOClient v2.3.1, But it only supports ws, not http polling
private readonly SocketIO _client = new SocketIO("https://[redacted], new SocketIOOptions() { Query = new Dictionary<string, string>() { { "franchise_id",FranchiseId.ToString()}, {"language_code","en"}, }, EIO = 3 });
i have the same error, what should i do?? if i use version 2.3.1, socket doesn't have HTTPclient property, which is where i need to add HTTPClientHanlder,
I think you have converted the json response wrong, please let me know if there are any changes, thanks :)
The latest version already supports socket.io server v2.x
@doghappy sorry, I’m confused. The latest package did not work with my socket io v2 server but the older package worked fine first time.
Are you saying that you think the latest package should work with a v2 server? Because it didn’t and, I think, the documentation suggests that the latest package only supports v3 and v4 servers
Did you specify the EIO option? If your server is using socket.io server v2.x, please explicitly set it to 3
var client = new SocketIO(connectionInfo.Uri, new SocketIOOptions
{
EIO = 3
});
By default, the client uses websocket to transmit data. If your server does not open websocket, you can also change the client's Transport option and set it to Polling
I'm not really sure how to debug this to provide more information but:
We are trying to access a Socket.IO server - the usual URL we use from our node.js app is: https://[reacted]/socket.io/?franchise_id=ZZ&language_code=en&EIO=3&transport=websocket
i.e. we are fixing the server version to 3 and forcing websockets.
We need a C# client now so, using the following code:
and
I can see from the HTTP Client logs I've injected the following:
So the call is being made, upgraded (I think) to WebSockets but then the " await _sdds.ConnectAsync();" code never exits and the OnConnected event never fires.
It's as if the code has deadlocked but I'm not sure what additional information I can provide to prove this.
if I add an additional query string "&transport=websockets" then this forces a 400 error (because the framework automatically adds a "&transport=polling" and we obviously can't have this twice) but then this invokes the "OnReconnected" event repeatedly.