How to use ClientWebSocket to connect to SignalR Server
LGinC opened this issue · comments
How to do it
What exactly are you trying to accomplish? You basically need to write and read the HubProtocol yourself (see https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md)
@davidfowl I want to use WechatMiniProgram's websocket client connect to my SignalR Server. Connect failed because of a protocol in WechatMiniProgram's websocket
WebSocket connection to 'wss://myhost/signalr' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
request header is
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8
Cache-Control:no-cache
Connection:Upgrade
content-type:application/json
Host:ch.gaobukeji.com
Origin:http://127.0.0.1:64307
Pragma:no-cache
Referer:https://servicewechat.com/wx97e2e9ad40b3fb68/devtools/page-frame.html
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:F8gYwhkOIdGzuwlltPx6Lg==
Sec-WebSocket-Protocol:protocol1
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.23 Mobile Safari/537.36 wechatdevtools/1.02.1804251 MicroMessenger/6.5.7 webview/
it's seem to server must return a response with 'Sec-WebSocket-Protocol:protocol1' in header
@davidfowl I want to use WechatMiniProgram's websocket client connect to my SignalR Server. Connect failed because of a protocol in WechatMiniProgram's websocket
Why not use the regular SignalR client? What's special about the WechatMiniProgram's websocket library?
@davidfowl yes, there is just a websocket client in WechatMiniProgram
I'm suspicious that this will even work. It seems like the websocket client is using subprotocols (in this case protocol1, whatever that is). You can set the subprotocol on the server side with something like this:
app.UseSignalR(routes =>
{
routes.MapHub<AppHub>("/app", options =>
{
options.WebSockets.SubProtocolSelector = requestedProtocols =>
{
return requestedProtocols.Count > 0 ? requestedProtocols[0] : null;
};
});
});
The code above will select the first of the requested subprotocols in the list. You can try that and see if you make any progress
@davidfowl
.net core signalr
there is no member called SubProtocolSelector
How to get the request's SubProtocol
@davidfowl
cool, let SubProtocol = "protocol1", and connect success.
@davidfowl oh.....
What Happened? I can't send message
there is no member called SubProtocolSelector
You're using 1.0.0-preview2-final, the newest version is 1.0.0-rc1-final and the API has changed.
What Happened? I can't send message
SignalR has a protocol and it looks like the wechat websocket client you are using has it's own protocol that is incompatible so it will not work.
Please read the hub protocol specification outlined here https://github.com/aspnet/SignalR/blob/dev/specs/HubProtocol.md. This is what you need to implement to use Hubs.
@davidfowl I find the confing in function ConfigureServices in startup.cs
services.AddSignalR(options => { // Faster pings for testing options.KeepAliveInterval = TimeSpan.FromSeconds(5); }).AddJsonProtocol(options => { //options.PayloadSerializerSettings.Converters.Add(JsonConver); //the next settings are important in order to serialize and deserialize date times as is and not convert time zones options.PayloadSerializerSettings.Converters.Add(new IsoDateTimeConverter()); options.PayloadSerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Unspecified; options.PayloadSerializerSettings.DateParseHandling = DateParseHandling.DateTimeOffset; });
and client send handshakeRequest
{ "protocol": "json", "version": 1 }
but server cannot parse the request
ERROR 2018-05-22 10:40:38,635 [3 ] oft.AspNetCore.Sockets.ConnectionManager - Failed disposing connection a4589209-d77e-408e-b54d-0efd29dc4a79.
System.IO.InvalidDataException: Unable to parse payload as a negotiation message.
at Microsoft.AspNetCore.SignalR.Internal.Protocol.NegotiationProtocol.TryParseMessage(ReadOnlySpan1 input, NegotiationMessage& negotiationMessage) at Microsoft.AspNetCore.SignalR.HubConnectionContext.<NegotiateAsync>d__56.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.SignalR.HubEndPoint
1.d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)