簡體   English   中英

WebSockets錯誤關閉

[英]WebSockets error on close

我是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上會出現此問題。

我解決了這個問題。 在我的處理程序中,我有一條要從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;
        }
    }
}

編輯:由於這只是我正在工作的一個示例,我就這樣保留了,但是在生產環境中,我可能需要添加不同的代碼來處理不同的關閉原因。 這樣,如果由於錯誤而關閉,則可以與正常關閉不同地進行處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM