创建"的Hello World"例如的WebSocket [英] Create "Hello World" WebSocket example

查看:241
本文介绍了创建"的Hello World"例如的WebSocket的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的节目感谢你的答案和@Maksims Mihejevs的code的新版本。

This is my new version of the program thanks to your answers and the code of @Maksims Mihejevs.

using System;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        static Socket serverSocket = new Socket(AddressFamily.InterNetwork, 
        SocketType.Stream, ProtocolType.IP);
        static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

        static void Main(string[] args)
        {            
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
            serverSocket.Listen(128);
            serverSocket.BeginAccept(null, 0, OnAccept, null);            
            Console.Read();
        }

        private static void OnAccept(IAsyncResult result)
        {
            byte[] buffer = new byte[1024];
            try
            {
                Socket client = null;
                string headerResponse = "";
                if (serverSocket != null && serverSocket.IsBound)
                {
                    client = serverSocket.EndAccept(result);
                    var i = client.Receive(buffer);
                    headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0,i);
                    // write received data to the console
                    Console.WriteLine(headerResponse);

                }
                if (client != null)
                {
                    /* Handshaking and managing ClientSocket */

                    var key = headerResponse.Replace("ey:", "`")
                              .Split('`')[1]                     // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
                              .Replace("\r", "").Split('\n')[0]  // dGhlIHNhbXBsZSBub25jZQ==
                              .Trim();

                    // key should now equal dGhlIHNhbXBsZSBub25jZQ==
                    var test1 = AcceptKey(ref key);

                    var newLine = "\r\n";

                    var response = "HTTP/1.1 101 Switching Protocols" + newLine
                         + "Upgrade: websocket" + newLine
                         + "Connection: Upgrade" + newLine
                         + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
                         //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
                         //+ "Sec-WebSocket-Version: 13" + newLine
                         ;

                    // which one should I use? none of them fires the onopen method
                    client.Send(System.Text.Encoding.UTF8.GetBytes(response));

                    var i = client.Receive(buffer); // wait for client to send a message

                    // once the message is received decode it in different formats
                    Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));                    

                    Console.WriteLine("\n\nPress enter to send data to client");
                    Console.Read();

                    var subA = SubArray<byte>(buffer, 0, i);
                    client.Send(subA);
                    Thread.Sleep(10000);//wait for message to be send


                }
            }
            catch (SocketException exception)
            {
                throw exception;
            }
            finally
            {
                if (serverSocket != null && serverSocket.IsBound)
                {
                    serverSocket.BeginAccept(null, 0, OnAccept, null);
                }
            }
        }

        public static T[] SubArray<T>(T[] data, int index, int length)
        {
            T[] result = new T[length];
            Array.Copy(data, index, result, 0, length);
            return result;
        }

        private static string AcceptKey(ref string key)
        {
            string longKey = key + guid;
            byte[] hashBytes = ComputeHash(longKey);
            return Convert.ToBase64String(hashBytes);
        }

        static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
        private static byte[] ComputeHash(string str)
        {
            return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str));
        }
    }
}

的Javascript:

<!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">
        function connect() {
            var ws = new WebSocket("ws://localhost:8080/service");
            ws.onopen = function () {
                alert("About to send data");
                ws.send("Hello World"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!!
                alert("Message sent!");
            };

            ws.onmessage = function (evt) {
                alert("About to receive data");
                var received_msg = evt.data;
                alert("Message received = "+received_msg);
            };
            ws.onclose = function () {
                // websocket is closed.
                alert("Connection is closed...");
            };
        };


    </script>
</head>
<body style="font-size:xx-large" >
    <div>
    <a href="#" onclick="connect()">Click here to start</a></div>
</body>
</html>

当我运行code我能够从客户端和服务器发送和接收数据。唯一的问题是,当它们arive到服务器的消息进行加密。下面是如何在程序运行的步骤:

When I run that code I am able to send and receive data from both the client and the server. The only problem is that the messages are encrypted when they arive to the server. Here are the steps of how the program runs:

请注意来自客户端的消息的加密方式。

Note how the message from the client is encrypted.

推荐答案

的WebSockets的协议依赖于TCP流连接。尽管是的WebSockets基于协议的消息。

WebSockets is protocol that relies on TCP streamed connection. Although WebSockets is Message based protocol.

如果你想实现自己的协议,那么我建议使用最新的稳定规范(18/04/12为) RFC 6455
该规范包含有关握手和取景所有必要的信息。还有大部分的描述从浏览器端,以及从服务器端表现的场景。
强烈建议遵循什么建议,你告诉code的实施过程中对服务器端。

If you want to implement your own protocol then I recommend to use latest and stable specification (for 18/04/12) RFC 6455. This specification contains all necessary information regarding handshake and framing. As well most of description on scenarios of behaving from browser side as well as from server side. It is highly recommended to follow what recommendations tells regarding server side during implementing of your code.

在几句话,我会形容,像这样的WebSockets工作:

In few words, I would describe working with WebSockets like this:


  1. 创建服务器套接字(适用的System.Net.Sockets)将其绑定到特定的端口,并保持与异步接受连接的听着。这样的事情:

  1. Create server Socket (System.Net.Sockets) bind it to specific port, and keep listening with asynchronous accepting of connections. Something like that:

Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
serverSocket.Listen(128);
serverSocket.BeginAccept(null, 0, OnAccept, null);


  • 您应该具有的接受功能OnAccept将实现握手。在未来它有可能成为另一个线程,如果系统是为了处理每秒连接的数量巨大。

  • You should have accepting function "OnAccept" that will implement handshake. In future it has to be in another thread if system is meant to handle huge amount of connections per second.

    private void OnAccept(IAsyncResult result) {
    try {
        Socket client = null;
        if (serverSocket != null && serverSocket.IsBound) {
            client = serverSocket.EndAccept(result);
        }
        if (client != null) {
            /* Handshaking and managing ClientSocket */
        }
    } catch(SocketException exception) {
    
    } finally {
        if (serverSocket != null && serverSocket.IsBound) {
            serverSocket.BeginAccept(null, 0, OnAccept, null);
        }
    }
    }


  • 连接建立后,你必须做的握手。基于规范 1.3开放握手,连接成功后,您会收到一些信息基本HTTP请求。例如:

  • After connection established, you have to do handshake. Based on specification 1.3 Opening Handshake, after connection established you will receive basic HTTP request with some information. Example:

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Origin: http://example.com
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13

    这例子是基于协议13.熊记版本,旧版本有一些差异,但大多是最新版本的跨平台兼容性。不同的浏览器可能会送你一些额外的数据。例如浏览器和操作系统的详细信息,缓存等。

    This example is based on version of protocol 13. Bear in mind that older versions have some differences but mostly latest versions are cross-compatible. Different browsers may send you some additional data. For example Browser and OS details, cache and others.

    根据提供握手细节,则必须生成应答线,他们大多是相同的,但将包含Accpet头-密钥,是基于提供仲丁基的WebSocket-密钥。在规范中1.3是清楚地描述如何产生反应的关键。
    这里是我的功能,我一直在使用V13:

    Based on provided handshake details, you have to generate answer lines, they are mostly same, but will contain Accpet-Key, that is based on provided Sec-WebSocket-Key. In specification 1.3 it is described clearly how to generate response key. Here is my function I've been using for V13:

    static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
    private string AcceptKey(ref string key) {
        string longKey = key + guid;
        SHA1 sha1 = SHA1CryptoServiceProvider.Create();
        byte[] hashBytes = sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(longKey));
        return Convert.ToBase64String(hashBytes);
    }
    

    握手答案看起来像:

    Handshake answer looks like that:

    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

    但接受有重点的基础上,从我之前提供的客户端和方法AcceptKey提供关键是生成一个。同时,要确保接受关键的最后一个字符后你把两个新的生产线为\\ r \\ n \\ r \\ n。

    But accept key have to be the generated one based on provided key from client and method AcceptKey I provided before. As well, make sure after last character of accept key you put two new lines "\r\n\r\n".

    实现自己的WebSockets协议肯定有一些好处和伟大的经验,你会得到以及超过协议是自我控制的。但是你必须花一些时间做这件事,并确保实现高度可靠的。

    Implementing own WebSockets protocol definitely have some benefits and great experience you get as well as control over protocol it self. But you have to spend some time doing it, and make sure that implementation is highly reliable.

    在同一时间,你可能在准备看看使用,谷歌(再次)有足够的解决方案。

    In same time you might have a look in ready to use solutions that google (again) have enough.

    这篇关于创建&QUOT;的Hello World&QUOT;例如的WebSocket的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆