2013-01-31 137 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连接的库。

相关问题