仅使用Chrome使用子协议

时间:2017-06-11 01:55:03

标签: c# google-chrome websocket asp.net-core .net-core

我有一个MQTT客户端/代理实现,客户端是基于浏览器的websockets,服务器是带有Kestrel&的ASPNetCore 1.1。 Websockets(0.1.0)。

作为MQTT规范的一部分,我使用" MQTT"来启动一个websockets连接。作为子协议,服务器在建立websockets连接时查找。

使用以下方法建立JavaScript连接:

var wsMQTT = new WebSocket(g.protocol + "//" + g.serverName + ":" + net.WSPORT, "MQTT");
wsMQTT.binaryType = "arraybuffer";

以下是Chrome错误(基本上超时,因为没有从服务器返回):

Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received. 

这是用于处理websocket连接的ASPNetCore中间件:

    public async Task Invoke(HttpContext context)
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            CancellationToken ct = context.RequestAborted;
            WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();

            MQTT.Broker MQTTClient = new MQTT.Broker(_host, webSocket, context.Connection.RemoteIpAddress.ToString(), context.Connection.RemotePort.ToString(), _MQTTUser, _MQTTPass);
            MQTTClient.TimeoutEvent += CloseWSSess;                                         // When MQTT stack sees ping/resp timeout, shut down WS

            if (context.WebSockets.WebSocketRequestedProtocols.Count == 1 &&
context.WebSockets.WebSocketRequestedProtocols[0].Substring(0, 4) == "MQTT")
            {
                _host.WriteLog(LOGTYPES.INFORMATION, "Received new MQTT WebSocket connection from " + context.Connection.RemoteIpAddress);

                // receive loop
                while (!ct.IsCancellationRequested && webSocket.State == WebSocketState.Open)
                {
                    var response = await ReceiveBin(MQTTClient, ct);
                }
            }
            else
            {
                CloseWSSess(MQTTClient, "Invalid WebSockets subprotocol requested from client [" + context.Connection.RemoteIpAddress.ToString() + "]. Session aborted.");
            }
        }
        else
        {
            await _next.Invoke(context);                // Not a web socket request
        }
    }

这是来自ASP Core的错误堆栈(它不会被困在websockets库中):

Connection id "0HL5GB806MGNU": An unhandled exception was thrown by the application.
System.IO.IOException: Unexpected end of stream at Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.<EnsureDataAvailableOrReadAsync>d__38.MoveNext()

适用于IE,Edge和Firefox,如果我从客户端连接中删除子协议,则不会崩溃ASP Core。所以我怀疑Chrome建立的连接与其他浏览器的连接方式略有不同,ASP Core Websockets无法正确处理。

任何想法如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

修复是指定AcceptWebSocketAsync中的子协议(即AcceptWebSocketAsync(&#34; MQTT&#34;)。