aspnet / SignalR-samples

Samples for ASP.NET Core SignalR

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to use ClientWebSocket to connect to SignalR Server

LGinC opened this issue · comments

commented

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)

commented

@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?

commented

@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

commented

@davidfowl
image
.net core signalr
there is no member called SubProtocolSelector

How to get the request's SubProtocol

commented

@davidfowl
cool, let SubProtocol = "protocol1", and connect success.

commented

@davidfowl oh.....
image
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.

commented

@davidfowl

tim 20180518153247
I use the ClientWebSocket to connect my server.

image

but it disconnect when I send message
image

do I need format my message?

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.

commented

@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.HubEndPoint1.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)

commented

resolve it in this