【问题标题】:WebSocket Server isn't firing the handshakeWebSocket 服务器没有触发握手
【发布时间】:2013-12-25 05:05:43
【问题描述】:

我正在尝试在 Unity 中使用简单的 HTML WebSocket,但套接字不会接收来自服务器的握手。

如果我的代码有问题,请告诉我。

index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title>Test</title>
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript">
            var noSupportMessage = "Your browser cannot support WebSocket!";
            var ws;

            function appendMessage(message) {
                $('body').append(message);
            }

            function connectSocketServer() {
                var support = "MozWebSocket" in window ? 'MozWebSocket' : ("WebSocket" in window ? 'WebSocket' : null);

                if (support == null) {
                    appendMessage("* " + noSupportMessage + "<br/>");
                    return;
                }

                appendMessage("* Connecting to server ..<br/>");
                // create a new websocket and connect
                ws = new window[support]('ws://127.0.0.1:13000/websession');

                // when data is comming from the server, this metod is called
                ws.onmessage = function (evt) {
                    appendMessage("# " + evt.data + "<br />");
                };

                ws.onerror = function(evt){
                    appendMessage("# " + evt.data + "<br />");  
                };

                // when the connection is established, this method is called
                ws.onopen = function () {
                    appendMessage('* Connection open<br/>');
                    $('#messageInput').attr("disabled", "");
                    $('#sendButton').attr("disabled", "");
                    $('#connectButton').attr("disabled", "disabled");
                    $('#disconnectButton').attr("disabled", "");
                };

                // when the connection is closed, this method is called
                ws.onclose = function () {
                    appendMessage('* Connection closed<br/>');
                    $('#messageInput').attr("disabled", "disabled");
                    $('#sendButton').attr("disabled", "disabled");
                    $('#connectButton').attr("disabled", "");
                    $('#disconnectButton').attr("disabled", "disabled");
                }
            }

            function sendMessage() {
                if (ws) {
                    var messageBox = document.getElementById('messageInput');
                    ws.send(messageBox.value);
                    messageBox.value = "";
                }
            }

            function disconnectWebSocket() {
                if (ws) {
                    ws.close();
                }
            }

            function connectWebSocket() {
                connectSocketServer();
            }

            window.onload = function () {
                $('#messageInput').attr("disabled", "disabled");
                $('#sendButton').attr("disabled", "disabled");
                $('#disconnectButton').attr("disabled", "disabled");
            }

    </script>
    </head>
    <body>
        <input type="button" id="connectButton" value="Connect" onclick="connectWebSocket()"/> <input type="button" id="disconnectButton" value="Disconnect" onclick="disconnectWebSocket()"/> <input type="text" id="messageInput" /> <input type="button" id="sendButton" value="Send" onclick="sendMessage()"/> <br />
    </body>
</html>

Unity TCPServer.cs

using UnityEngine;
using System.Threading;
using System.Net.Sockets;
using System.IO;
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Collections.Generic;

class TCPServer : MonoBehaviour
{
    public static List<SocketClient> ClientList = new List<SocketClient>();
    Thread mThread;

    void Start()
    {
        ThreadStart ts = new ThreadStart(Main);
        mThread = new Thread(ts);
        mThread.Start();
        print("Thread done...");
    }

    void Update(){
    }


    public static void Main()
    { 

        TcpListener socketServer = null;

        try
        {
            // Set the TcpListener on port 13000.
            Int32 port = 13000;
            IPAddress localAddr = IPAddress.Parse("127.0.0.1");

            // TcpListener server = new TcpListener(port);
            socketServer = new TcpListener(localAddr, port);

            print("Server has started on " + localAddr.ToString() + ":" + port.ToString() + "." + Environment.NewLine + "Waiting for a connection...");

            // Start listening for client requests.
            socketServer.Start();

            // counter
            int counter = 0;

            // Enter the listening loop.
            while(true) 
            {
                // check for any incoming pending connections
                // create new socket client for new connection
                TcpClient socketConnection = socketServer.AcceptTcpClient();

                counter++;

                DateTime now = DateTime.Now;

                //write message to console to indicate new connection
                print("New Client Connected - " + now.ToString("MM/dd/yyyy h:mm:ss tt"));

                // create new client object for this connection
                new SocketClient(socketConnection);
            }
        }
        catch(SocketException e)
        {
            print("SocketException: " + e);
        }
        finally
        {
            // Stop listening for new clients.
            socketServer.Stop();
        }


        print("Hit enter to continue...");
        Console.Read();
    }

    public static void CloseClient(SocketClient whichClient)
    {
        ClientList.Remove(whichClient);
        whichClient.Client.Close();

            // dispose of the client object
        whichClient.Dispose();
        whichClient = null;
        print("Client Disconnected");
    }

    public static void SendTextToClient(SocketClient sc, string text)
    {
        StreamWriter writer = new StreamWriter(sc.Client.GetStream());
            // check if client is still connected, then send the text string
        try
        {
            if (sc.Client.Connected)
            {
                writer.WriteLine(text);
                writer.Flush();
                writer = null;
            }
        }
        catch
        {
            CloseClient(sc);
        }

    }

    public static void LOG(string a ){
        print(a);
    }

    public static void SendBroadcast(string text)
    {
        StreamWriter writer;
            // loop through the array and send text to all clients
        foreach (SocketClient client in ClientList)
        {
            if (client.Client.Connected)
            {
                try
                {
                    writer = new StreamWriter(client.Client.GetStream());
                    writer.WriteLine(text);
                    writer.Flush();
                    writer = null;

                }
                catch
                {
                    CloseClient(client);
                }
            }
        }
    }


}

class SocketClient
{
    public TcpClient Client;
    StreamReader reader;
    StreamWriter writer;


    public SocketClient(TcpClient client)
    {
        Client = client;
        Thread clientThread = new Thread(new ThreadStart(StartClient));
        clientThread.Start();
    }


    private void StartClient()
    {
        TCPServer.ClientList.Add(this);

            // create a reader for this client
        reader = new StreamReader(Client.GetStream());
            // create a writer for this client
        writer = new StreamWriter(Client.GetStream());

        var headers = new Dictionary<string, string>();

        string line = "";
        while ((line = reader.ReadLine()) != string.Empty)
        {
            if (!string.IsNullOrEmpty(line))
            {
                var tokens = line.Split(new char[] { ':' }, 2);
                if (!string.IsNullOrEmpty(line) && tokens.Length > 1)
                {
                    headers[tokens[0]] = tokens[1].Trim();
                }
            }
        }

        String secWebSocketAccept = ComputeWebSocketHandshakeSecurityHash09(headers["Sec-WebSocket-Key"]);

            // send handshake to this client only
        writer.WriteLine("HTTP/1.1 101 Switching Protocols");
        writer.WriteLine("Upgrade: websocket");
        writer.WriteLine("Connection: Upgrade");
        writer.WriteLine("WebSocket-Origin: http://localhost");
        writer.WriteLine("WebSocket-Location: ws://127.0.0.1:13000/websession");
        writer.WriteLine("Sec-WebSocket-Accept: " + secWebSocketAccept);
        writer.WriteLine("Sec-WebSocket-Protocol: chat");
        writer.WriteLine("");
        writer.Flush();

        TCPServer.SendBroadcast("New Client Connected");

        Thread clientRun = new Thread(new ThreadStart(RunClient));
        clientRun.Start();
    }

    public static String ComputeWebSocketHandshakeSecurityHash09(String secWebSocketKey)
    {
        const String MagicKEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        String secWebSocketAccept = String.Empty;

            // 1. Combine the request Sec-WebSocket-Key with magic key.
        String ret = secWebSocketKey + MagicKEY;

            // 2. Compute the SHA1 hash
        SHA1 sha = new SHA1CryptoServiceProvider(); 
        byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));

            // 3. Base64 encode the hash
        secWebSocketAccept = Convert.ToBase64String(sha1Hash);

        return secWebSocketAccept;
    }


    private void RunClient()
    {
        try
        {
            string line = "";
            while (true)
            {
                line = reader.ReadLine();
                if (!string.IsNullOrEmpty(line))
                {
                    if(!string.IsNullOrEmpty(line.Trim(' '))){
                        TCPServer.SendBroadcast(line);
                    }
                }
            }
        }
        catch
        {
            TCPServer.CloseClient(this);
        }
    }

    public void Dispose()
    {
        System.GC.SuppressFinalize(this);
    }
}

【问题讨论】:

    标签: c# javascript html websocket unity3d


    【解决方案1】:

    WebSocket 不是原始 TCP。你需要一个 WebSocket 服务器。

    如果您选择 WebSocket 服务器,您可以通过对您的服务器运行 AutobahnTestsuite(在模糊客户端模式下)来检查它是否符合 WebSocket 协议标准 (IETF RFC6455)。这将为您提供遇到问题的详细报告,例如 this(包括有线日志)。

    披露:我是 Autobahn 的原作者,为 Tavendo 工作。

    【讨论】:

    • 某种方式将 html 与 tcp 连接起来?,在 websocket + tcp 中,连接有效,但握手未触发..
    • 无法从网页中的 JavaScript 发出原始 TCP 连接。这只能在 Web 浏览器扩展中实现。
    【解决方案2】:

    C# + Unity3d + HTML WebSocket

    这很好用,

    https://github.com/sta/websocket-sharp

    无论如何,谢谢,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多