web-dev-qa-db-ja.com

Websocketサーバー:Webソケットのonopen関数は呼び出されません

C#Webソケットサーバーを実装しようとしていますが、いくつかの問題があります。 JavaScriptを使用してページをホストするWebサーバー(ASP.NET)を実行しており、WebソケットサーバーはC#コンソールアプリケーションとして実装されています。

クライアント(javascriptを実行しているChrome)からの接続試行を検出し、クライアントからハンドシェイクを取得することもできます。しかし、クライアントは私が送り返すハンドシェイクを受け入れないようです(Webソケットのonopen関数が呼び出されることはありません)。

The Web Socket protocol を読んでいますが、何が間違っているのかわかりません。サーバーコードの一部を次に示します。

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8181);
listener.Bind(ep);
listener.Listen(100);
Console.WriteLine("Wainting for connection...");
Socket socketForClient = listener.Accept();
if (socketForClient.Connected)
{
    Console.WriteLine("Client connected");
    NetworkStream networkStream = new NetworkStream(socketForClient);
    System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
    System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);

    //read handshake from client:
    Console.WriteLine("HANDSHAKING...");
    char[] shake = new char[255];
    streamReader.Read(shake, 0, 255);

    string handshake =
       "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" +
       "Upgrade: WebSocket\r\n" +
       "Connection: Upgrade\r\n" +
       "WebSocket-Origin: http://localhost:8080\r\n" +
       "WebSocket-Location: ws://localhost:8181\r\n" +
       "\r\n";

    streamWriter.Write(handshake);
    streamWriter.Flush();

ポート8080のWebサーバーとポート8181のWebソケットサーバーの両方をローカルホストで実行しています。

異なるエンコーディング(ASCII、バイト、Hex)でハンドシェイクを送信しようとしましたが、これは違いを生じないようです。接続が完全に確立されることはありません。 javascriptは次のようになります。

var ws;
var Host = 'ws://localhost:8181';
debug("Connecting to " + Host + " ...");
try {
 ws = new WebSocket(Host);
} catch (err) {
 debug(err, 'error');
}
ws.onopen = function () {
 debug("connected...", 'success');
};
ws.onclose = function () {
 debug("Socket closed!", 'error');
};
ws.onmessage = function (evt) {
 debug('response: ' + evt, 'response');
};

chromeが情報を送信するはずなのに、エラーはC#サーバーにあると推測していますが、前述のようにonopen関数は呼び出されません。

それで、私の質問:これを達成した人はいますか?そして、原因:コードに明らかなエラーがありますか(尋ねるのはあまり望んでいないことです)

61
Jon List

おそらくエンコードの問題です。これが私が書いたC#サーバーです。

class Program
{
    static void Main(string[] args)
    {
        var listener = new TcpListener(IPAddress.Loopback, 8181);
        listener.Start();
        using (var client = listener.AcceptTcpClient())
        using (var stream = client.GetStream())
        using (var reader = new StreamReader(stream))
        using (var writer = new StreamWriter(stream))
        {
            writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake");
            writer.WriteLine("Upgrade: WebSocket");
            writer.WriteLine("Connection: Upgrade");
            writer.WriteLine("WebSocket-Origin: http://localhost:8080");
            writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession");
            writer.WriteLine("");
        }
        listener.Stop();
    }
}

そして、localhost:8080でホストされている対応するクライアント:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <script type="text/javascript">
      var socket = new WebSocket('ws://localhost:8181/websession');
      socket.onopen = function() {
        alert('handshake successfully established. May send data now...');
      };
      socket.onclose = function() {
        alert('connection closed');
      };
    </script>
  </head>
  <body>
  </body>
</html>

この例では、ハンドシェイクのみを確立します。ハンドシェイクが確立されたら、データを受け入れ続けるために、サーバーを微調整する必要があります。

47
Darin Dimitrov

UTF8エンコーディングを使用してテキストメッセージを送信してください。

C#によって実装されるオープンソースのwebsocketサーバーがあり、直接使用できます。

http://superwebsocket.codeplex.com/

私のオープンソースプロジェクトです!

24
Kerry Jiang

.NET Framework 4.5では、Windows Communication FoundationでWebSocketのサポートが導入されています。 WebSocketは、標準のHTTPポート80および443を介した双方向通信を可能にする効率的な標準ベースのテクノロジーです。標準のHTTPポートを使用すると、WebSocketは仲介者を通じてWebを介して通信できます。 WebSocketトランスポートを介した通信をサポートするために、2つの新しい標準バインディングが追加されました。 NetHttpBindingおよびNetHttpsBinding。 WebSocket固有の設定は、WebSocketSettingsプロパティにアクセスすることにより、HttpTransportBinding要素で構成できます。

それでもSOAP

http://msdn.Microsoft.com/en-us/library/hh674271(v = vs.110).aspx

3
Dave Hillier