2017-03-02 95 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; 
     } 
    } 
} 

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

相关问题