关闭时 WebSockets 错误

Posted

技术标签:

【中文标题】关闭时 WebSockets 错误【英文标题】:WebSockets error on close 【发布时间】:2017-03-02 14:20:53 【问题描述】:

我是 WebSockets 的新手,正在尝试我在网上找到的一个示例。简单的示例让服务器鹦鹉返回我在文本框中输入的任何内容。有一个按钮可以将文本发送到服务器,还有一个按钮可以关闭与服务器的连接。

这里是 WebSocketHandler 的代码:

<%@ WebHandler Language="C#" Class="WebSocketHandler" %>

using System;
using System.Text;
using System.Web;
using System.Web.WebSockets;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;

public class WebSocketHandler : IHttpHandler 

public void ProcessRequest (HttpContext context) 
    if (context.IsWebSocketRequest) 
        context.AcceptWebSocketRequest(DoTalking);
    


public bool IsReusable 
    get 
        return false;
    


public async Task DoTalking(AspNetWebSocketContext context) 
    WebSocket socket = context.WebSocket;

    while (true) 
        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

        if (socket.State == WebSocketState.Open) 
            string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            userMessage = "You sent: " + userMessage + " at " + DateTime.Now.ToLongTimeString();
            buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));
            await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
         else 
            break;
        
    

这是客户端上的 JQuery:

var socket;
$(document).ready(function () 
socket = new WebSocket("ws://localhost:61530/WebSocketHandler.ashx");

socket.onopen = function (evt) 
    $("#serverMessage").append("<h3>Connection Opened with the Echo server.</h3>");
;

socket.onmessage = function (evt) 
    $("#serverMessage").append("<h3>" + evt.data + "</h3>");
;

socket.onerror = function (evt) 
    $("#serverMessage").append("<h3>Unexpected Error</h3>");
;

socket.onclose = function (evt) 
    $("#serverMessage").append("<h3>Connection closed</h3>");


$("#btnSend").click(function () 
    if (socket.readyState === WebSocket.OPEN) 
        socket.send($("#txtMsg").val());
     else 
        $("#serverMessage").append("<h3>The underlying connection is closed</h3>");
    
);

$("#btnStop").click(function () 
    socket.close();
);
);

向服务器发送消息并获得响应一切正常。问题是当我单击按钮关闭 websocket 时。单击该按钮时,它首先触发 onerror 事件,然后触发 onclose 事件。谁能告诉我为什么会这样和/或我做错了什么? 提前致谢。

注意:我已经在 IE、Edge、Firefox、Chrome 和 Opera 上尝试过。该问题仅出现在 IE、Edge 和 Firefox 上。

【问题讨论】:

【参考方案1】:

我发现了问题所在。在我的处理程序中,我有一行可以跳出 while 循环,我必须添加一个 CloseAsync() 调用以确保套接字以正常关闭的方式关闭。以下是修改后的 DoTalking 功能,可在所有浏览器上正常运行:

public async Task DoTalking(AspNetWebSocketContext context) 
    WebSocket socket = context.WebSocket;

    while (true) 
        ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
        WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, CancellationToken.None);

        if (socket.State == WebSocketState.Open) 
            string userMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count);
            userMessage = "You sent: " + userMessage + " at " + DateTime.Now.ToLongTimeString();
            buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(userMessage));
            await socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
         else 
            // The following line is the line I had to add to correct the problem
            await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Socket closed", CancellationToken.None);
            break;
        
    

编辑:由于这只是我正在工作的一个示例,所以我就这样离开了,但是在生产环境中,我可能需要添加不同的代码来处理不同的关闭原因。这样,如果它因错误而关闭,我可以与正常关闭不同的方式处理它。

【讨论】:

以上是关于关闭时 WebSockets 错误的主要内容,如果未能解决你的问题,请参考以下文章

对 Microsoft WebSockets 命名空间感到困惑

允许在 websockets 中删除消息

Windows Phone 8 中的 Websockets 客户端支持

如何在 laravel 应用程序中使用 docker 容器启动运行 websockets

“在收到握手响应之前连接已关闭”尝试使用 websockets 将 Angular 与 Spring 连接时

如何在WebSocket上实现Ajax