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

EDIT:これは私も働いていた一例に過ぎだったので、私はちょうどそのようにそれを残したが、本番環境では、私はおそらくだろうさまざまなクロージャの理由を処理するために異なるコードを追加する必要があります。そうすれば、エラーのためにクローズしていた場合、通常のクロージャとは違って処理できます。

関連する問題