0

我是 WebSockets 的新手。我阅读了很多关于这个主题的信息,我正在尝试构建一个简单的服务器来处理握手部分,但仍然无法让我的服务器正常工作。客户端发送请求,服务器将响应发送回客户端,但不会触发 WebSocket 的 onopen 事件。但是如果我关闭服务器,websocket 对象会触发它的 onclose 事件。

我从 chrome 得到的请求是:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.0.164:3215
Origin: http://lalala
Sec-WebSocket-Key: MyUY7duPdE1WbGXPOslYzw==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame

我发回的回复:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 4IVZgO4OosW/b7upp7Qbh2q6a4I=

我在服务器中使用的代码:

static void Main(string[] args)
    {
      var listener = new TcpListener(IPAddress.Parse("192.168.0.164"), 3215);
      listener.Start();
      Console.WriteLine(">> Started.");
      var client = listener.AcceptTcpClient();
      Console.WriteLine(">> Accepted.");
      while (true)
      {
        try
        {
          var stream = client.GetStream();
          var bytes = new byte[client.ReceiveBufferSize];
          stream.Read(bytes, 0, client.ReceiveBufferSize);
          var data = Encoding.ASCII.GetString(bytes);

          Console.WriteLine(data.Remove(data.IndexOf("\0\0\0")));
          var code = data.Remove(0, data.IndexOf("Sec-WebSocket-Key:") + 19);
          code = code.Remove(code.IndexOf("==") + 2);
          var response = string.Format(@"HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: " + GetServerResponseKey(code));
          Console.WriteLine(response);
          var encodedResponse = Encoding.UTF8.GetBytes(response);
          stream.Write(encodedResponse, 0, encodedResponse.Length);
        }
        catch (IOException)
        {
          Console.WriteLine(">> Client Disconnected.");
          Console.ReadKey();
          return;
        }
      }
    }

    private static string GetServerResponseKey(string key)
    {
      var keyForHash = String.Concat(key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");

      var encoding = new UTF8Encoding();
      var temp = encoding.GetBytes(keyForHash);

      var hashProvider = new SHA1CryptoServiceProvider();
      var keyForBase64 = hashProvider.ComputeHash(temp);

      return Convert.ToBase64String(keyForBase64);

    }

和客户端脚本:

 <script type="text/javascript">

        var socket;
        function connect()
        {
          socket = new WebSocket('ws://192.168.0.164:3215');
          setTimeout(bindEvents, 1000);
          setReadyState();
        }

        function bindEvents() {
            socket.onopen = function() {
                alert('handshake successfully established. May send data now...');
                setReadyState();
            };
            socket.onclose = function() {
                alert('connection closed');
            };
        }

        function setReadyState() {
          console.log('ws.readyState: ' + socket.readyState);
        }
        connect();

    </script>

还有一些问题:

1-有没有办法找出我的浏览器使用的协议?

2-Chrome 21 使用哪种协议?

4

1 回答 1

1

您的响应需要遵循 HTTP 请求/响应的规则,并且在每个标头和末尾的一对之间有一个回车 + 换行符。我不会在响应中使用新行,而是对它们进行转义:

“标头1\r\n标头2\r\n标头3\r\n\r\n”

“Sec-WebSocket-Version: 13”标头表明浏览器正在使用协议的第 13 版,即IETF 6455

于 2012-09-13T18:33:40.573 回答