2017-03-02 96 views
0

我是WebSockets的新手,正在嘗試一個我在網上找到的示例。簡單的例子讓服務器鸚鵡返回我在文本框中輸入的任何內容。有一個按鈕可將文本發送到服務器,並有一個按鈕用於關閉與服務器的連接。關閉時出現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上。

回答

2

我想出了問題。在我的處理程序中,我有一條線來擺脫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; 
     } 
    } 
} 

編輯:由於這只是一個例子,我是,雖然工作時,我剛剛離開它這樣,但在生產環境中,我可能會需要添加不同的代碼來處理不同的關閉原因。這樣,如果由於錯誤而關閉,我可以以與正常關閉不同的方式處理它。

相關問題