我有一个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无法正确处理。
任何想法如何解决这个问题?
答案 0 :(得分:0)
修复是指定AcceptWebSocketAsync中的子协议(即AcceptWebSocketAsync(&#34; MQTT&#34;)。