2013-01-31 164 views
0

我是WebSocket API的初學者。我試圖在本地連接到我的服務器,但我正在獲取連接關閉消息。誰能告訴我我做錯了什麼?WebSocket連接正在關閉

這是我的代碼:

服務器

using System.Net.Sockets; 
using System.Net; 
using System.IO; 
using System; 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var listener = new TcpListener(IPAddress.Loopback, 8181); 
    listener.Start(); 
    while (true) 
    { 
     Console.WriteLine("Listening..."); 
     using (var client = listener.AcceptTcpClient()) 
     using (var stream = client.GetStream()) 
     using (var reader = new StreamReader(stream)) 
     using (var writer = new StreamWriter(stream)) 
     { 

      string line = null, key = "", responseKey = ""; 
      string MAGIC_STRING = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
      while (line != "") 
      { 
       line = reader.ReadLine(); 
       if (line.StartsWith("Sec-WebSocket-Key:")) 
       { 
        key = line.Split(':')[1].Trim(); 
       } 
      } 

      if (key != "") 
      { 
       key += MAGIC_STRING; 
       using (var sha1 = SHA1.Create()) 
       { 
        responseKey = Convert.ToBase64String(sha1.ComputeHash(Encoding.ASCII.GetBytes(key))); 
       } 
      } 

      // send handshake to the client 
      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"); 
      if (!String.IsNullOrEmpty(responseKey)) 
       writer.WriteLine("Sec-WebSocket-Accept: " + responseKey); 
      writer.WriteLine(""); 
      Console.ReadLine(); 
      writer.Flush(); 

     }//using 
     Console.WriteLine("Finished"); 
    }//while 

    } 
} 

客戶

 <!DOCTYPE HTML> 
     <html> 
     <head><title></title> 
      <script type="text/javascript"> 

     function WebSocketTest() { 
      var msg = document.getElementById("msg"); 
      if ("WebSocket" in window) { 
      msg.innerHTML="WebSocket is supported by your Browser!"; 
     // Let us open a web socket 
     var ws = new WebSocket("ws://localhost:8181/websession"); 
     ws.onopen = function() { 
      // Web Socket is connected, send data using send() 
      msg.innerHTML="connection open"; 
      //ws.send("Message to send"); 
      //msg.innerHTML="Message is sent..."; 
     }; 
     ws.onclose = function() { 
      // websocket is closed. 
      msg.innerHTML = "Connection is closed..."; 
     }; 

     ws.onerror = function(error){ 
      console.log('Error detected: ' + error); 
     }; 
     ws.onmessage = function (evt) { 
      var received_msg = evt.data; 
      msg.innerHTML="Message is received..."; 
     }; 

    } 
    else { 
     // The browser doesn't support WebSocket 
     msg.innerHTML="WebSocket NOT supported by your Browser!"; 
    } 
    } 
    </script> 
    </head> 
     <body> 
     <div id="sse"> 
     <a href="javascript:WebSocketTest()">Run WebSocket</a><br /> 
     <p id="msg"></p> 
     </div> 
     </body> 
      </html> 

任何解決方案,將不勝感激,謝謝您:)

+0

我已經添加了一些信息,但順便說一句:在Windows 8(和類似的服務器上),有*內置*網絡套接字客戶端庫支持。 –

+0

順便說一句:即使你得到了正確的迴應:如果你關閉了監聽器('listener.Stop()'),你可能會殺死所有的客戶端。 –

回答

0

釷at在任何規範下都不是有效的網絡套接字響應。最初的網絡套接字響應總是要求你將一些數字作爲響應頭的一部分,以證明你是一個網絡套接字服務器。要讀取和寫入哪些頭文件,以及要做什麼,取決於web-sockets的版本(hibi/hixie 76/rfc)。它實際上看起來像您的服務器正在使用客戶端的標頭。

例如,RFC6455(13)響應將開始:

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket 
Connection: Upgrade 
Sec-WebSocket-Accept: {crunch some numbers} 

。注意,Hixie-76響應是不同的,並且有在上述比特,我已刪去。

RFC6455 specification

爲了證明握手被接收時,服務器必須採取兩個信息 件,它們組合成一個響應。第一個 信息片段來自| Sec-WebSocket-Key |頭字段 在客戶端握手:

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== 

對於該頭字段,服務器具有取的值(如存在於 報頭字段,例如,base64編碼[RFC4648]版本減去任何 領先前後空白),並與 全局唯一標識符(GUID,[RFC4122])「258EAFA5-E914-47DA- 95CA-C5AB0DC85B11」字符串的形式,這是不太可能受到 網絡端點不理解可以使用串聯此WebSocket協議。 A 然後在服務器的 握手中返回此串聯的SHA-1散列(160位)[FIPS.180-3],base64編碼(請參閱 [RFC4648]的第4部分)。

+0

我讀了你的文章和wld我問你一個忙,告訴我如何編輯我的服務器代碼,使其工作 – Sora

+1

@Sora如果你想從頭開始編寫自己的服務器,然後閱讀我鏈接的規範並實施它;然後閱讀所有其他規範,因爲並非所有的瀏覽器都使用RFC規範 - 特別是Hixie-76是非常不同的。這是相當多的代碼;如果你想使用內置的東西,使用'HttpListener'和'AcceptWebSocketAsync'(在每個連接返回的上下文中);也有第三方庫支持網絡套接字 –

+0

我編輯了我的問題,並添加Sec-WebSocket-Key到服務器,但仍然無法獲得連接開放信息我不明白什麼是什麼我做錯了 – Sora

0

JavaScript代碼連接到Web服務器後。 C#遍歷所有使用語句,並將所有行打印到文件中,之後所有使用語句都關閉,因此生成的客戶端被處理,從而關閉連接。
解決此問題的一個快速(但很髒)的修復是在使用語句結尾處添加「Console.Readline」。儘管如此,你的過程會一直持續下去!
有關接受客戶端的TcpClients的更多信息,請轉至msdn
請注意,在那裏給出的示例一次只允許一個連接。
最後的評論:像Marc建議的那樣,存在用於接受websocket連接的庫。

相關問題