2012-11-22 87 views
4

我正在使用最新版本的Chrome(websocket版本13)進行測試。Websocket服務器,客戶端無法握手

這裏的位於我簡單的客戶端頁面在http://127.0.0.1/folder/default.aspx

<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'); 
    }; 
    socket.onmessage = function(msg) { 
     alert(msg); 
    }; 
</script> 

這是我的監聽器(C#)

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)) 
    { 
     writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake"); 
     writer.WriteLine("Upgrade: WebSocket"); 
     writer.WriteLine("Connection: Upgrade"); 
     writer.WriteLine("WebSocket-Origin: http://127.0.0.1"); 
     writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); 
     writer.WriteLine(""); 
    } 
    Console.WriteLine("Finished"); 
} 

當我運行的服務器,然後加載客戶端頁面,只說:"connection closed"

請問有人能告訴我如何讓握手正確執行嗎?據我從文檔和以前的問題中可以看出,我發回客戶端的響應看起來是正確的。

+0

你有沒有通過代碼加強了嗎?它是否停在某個點 –

+0

我已經走過了,但有點不確定我應該在尋找什麼。所有的代碼似乎都按照我預期的那樣運行。 –

+0

另外 - 是不是「交換協議」的狀態?有很多事情在迴應中看起來不正確。 –

回答

2

您還沒有計算安全哈希值。客戶端向您發送一個數字,並且在規範中還有另一個硬編碼的數字。您需要按照規範中的說明合併它們,並將其作爲標題返回。

這表明您的服務器實際上是一個網絡套接字服務器。

RFC6455

注意,你可能還需要考慮是否除RFC實現Hixie 76。

3

基於您的代碼,這應該工作(至少鉻)

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://127.0.0.1"); 
     writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); 
     if (!String.IsNullOrEmpty(responseKey)) 
      writer.WriteLine("Sec-WebSocket-Accept: " + responseKey); 
     writer.WriteLine(""); 

     writer.Flush(); 

     SendString(stream, "This code works!!!!"); 
     SendString(stream, "This code also works!!!! ".PadRight(300, '.') + "\r\nEND"); 
    } 
    Console.WriteLine("Finished"); 
} 


void SendString(Stream s, string str) 
{ 
    var buf = Encoding.UTF8.GetBytes(str); 
    int frameSize = 64; 

    var parts = buf.Select((b, i) => new { b, i }) 
        .GroupBy(x => x.i/(frameSize - 1)) 
        .Select(x => x.Select(y => y.b).ToArray()) 
        .ToList(); 

    for (int i = 0; i < parts.Count; i++) 
    { 
     byte cmd = 0; 
     if (i == 0) cmd |= 1; 
     if (i == parts.Count - 1) cmd |= 0x80; 

     s.WriteByte(cmd); 
     s.WriteByte((byte)parts[i].Length); 
     s.Write(parts[i], 0, parts[i].Length); 
    } 

    s.Flush(); 
} 

PS:使用

socket.onmessage = function(msg) { 
    alert(msg.data); 
}; 

看到服務器發送消息的內容。

1

的StreamReader和StreamWriter在處置被關閉底層流(的NetworkStream)。所以客戶端頁面僅顯示「連接關閉」

相關問題