Unity使用WebSocket(基于BaseHTTP插件)

20 篇文章 2 订阅

服务器:使用c#写的,用来持续给一个端口发数据

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

namespace WebSocketServer
{
    class Program
    {
        static string byte_to_string(byte[] b)
        {
            string s = "";
            foreach (byte _b in b)
            {
                s += _b.ToString();
            }
            return s;
        }
        static void Main(string[] args)
        {
            int port = 1818;
            byte[] buffer = new byte[1024];

            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);
            Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                listener.Bind(localEP);
                listener.Listen(10);

                Console.WriteLine("等待客户端连接....");
                Socket sc = listener.Accept();//接受一个连接  
                Console.WriteLine("接受到了客户端:" + sc.RemoteEndPoint.ToString() + "连接....");

                //握手  
                int length = sc.Receive(buffer);//接受客户端握手信息  
                sc.Send(PackHandShakeData(GetSecKeyAccetp(buffer, length)));
                Console.WriteLine("已经发送握手协议了....");

                while (true)
                {
                    Thread.Sleep(1000);
                    //主动发送数据
                    string lines = "{\"info\":[{\"area\":11,\"x\":80,\"y\":50},{\"area\":5,\"x\":76,\"y\":48}]}";
                    Console.WriteLine("发送数据:“" + lines + "” 至客户端....");
                    sc.Send(PackData(lines));
                }

                //接受客户端数据  
                Console.WriteLine("等待客户端数据....");
                length = sc.Receive(buffer);//接受客户端信息  
                string clientMsg = AnalyticData(buffer, length);
                Console.WriteLine("接受到客户端数据:" + clientMsg);

                //发送数据  
                //string sendMsg = "您好," + clientMsg;
                //Console.WriteLine("发送数据:“" + sendMsg + "” 至客户端....");
                //sc.Send(PackData(sendMsg));

                Console.WriteLine("演示Over!");
                Console.Read();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

        }

        /// <summary>  
        /// 打包握手信息  
        /// </summary>  
        /// <param name="secKeyAccept">Sec-WebSocket-Accept</param>  
        /// <returns>数据包</returns>  
        private static byte[] PackHandShakeData(string secKeyAccept)
        {
            var responseBuilder = new StringBuilder();
            responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);
            responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);
            responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);
            responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);
            return Encoding.UTF8.GetBytes(responseBuilder.ToString());
        }

        /// <summary>  
        /// 生成Sec-WebSocket-Accept  
        /// </summary>  
        /// <param name="handShakeText">客户端握手信息</param>  
        /// <returns>Sec-WebSocket-Accept</returns>  
        private static string GetSecKeyAccetp(byte[] handShakeBytes, int bytesLength)
        {
            string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);
            string key = string.Empty;
            Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n");
            Match m = r.Match(handShakeText);
            if (m.Groups.Count != 0)
            {
                key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();
            }
            byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));
            return Convert.ToBase64String(encryptionString);
        }

        /// <summary>  
        /// 解析客户端数据包  
        /// </summary>  
        /// <param name="recBytes">服务器接收的数据包</param>  
        /// <param name="recByteLength">有效数据长度</param>  
        /// <returns></returns>  
        private static string AnalyticData(byte[] recBytes, int recByteLength)
        {
            if (recByteLength < 2) { return string.Empty; }

            bool fin = (recBytes[0] & 0x80) == 0x80; // 1bit,1表示最后一帧    
            if (!fin)
            {
                return string.Empty;// 超过一帧暂不处理   
            }

            bool mask_flag = (recBytes[1] & 0x80) == 0x80; // 是否包含掩码    
            if (!mask_flag)
            {
                return string.Empty;// 不包含掩码的暂不处理  
            }

            int payload_len = recBytes[1] & 0x7F; // 数据长度    

            byte[] masks = new byte[4];
            byte[] payload_data;

            if (payload_len == 126)
            {
                Array.Copy(recBytes, 4, masks, 0, 4);
                payload_len = (UInt16)(recBytes[2] << 8 | recBytes[3]);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 8, payload_data, 0, payload_len);

            }
            else if (payload_len == 127)
            {
                Array.Copy(recBytes, 10, masks, 0, 4);
                byte[] uInt64Bytes = new byte[8];
                for (int i = 0; i < 8; i++)
                {
                    uInt64Bytes[i] = recBytes[9 - i];
                }
                UInt64 len = BitConverter.ToUInt64(uInt64Bytes, 0);

                payload_data = new byte[len];
                for (UInt64 i = 0; i < len; i++)
                {
                    payload_data[i] = recBytes[i + 14];
                }
            }
            else
            {
                Array.Copy(recBytes, 2, masks, 0, 4);
                payload_data = new byte[payload_len];
                Array.Copy(recBytes, 6, payload_data, 0, payload_len);

            }

            for (var i = 0; i < payload_len; i++)
            {
                payload_data[i] = (byte)(payload_data[i] ^ masks[i % 4]);
            }

            return Encoding.UTF8.GetString(payload_data);
        }


        /// <summary>  
        /// 打包服务器数据  
        /// </summary>  
        /// <param name="message">数据</param>  
        /// <returns>数据包</returns>  
        private static byte[] PackData(string message)
        {
            byte[] contentBytes = null;
            byte[] temp = Encoding.UTF8.GetBytes(message);

            if (temp.Length < 126)
            {
                contentBytes = new byte[temp.Length + 2];
                contentBytes[0] = 0x81;
                contentBytes[1] = (byte)temp.Length;
                Array.Copy(temp, 0, contentBytes, 2, temp.Length);
            }
            else if (temp.Length < 0xFFFF)
            {
                contentBytes = new byte[temp.Length + 4];
                contentBytes[0] = 0x81;
                contentBytes[1] = 126;
                contentBytes[2] = (byte)(temp.Length & 0xFF);
                contentBytes[3] = (byte)(temp.Length >> 8 & 0xFF);
                Array.Copy(temp, 0, contentBytes, 4, temp.Length);
            }
            else
            {
                // 暂不处理超长内容    
            }

            return contentBytes;
        }

    }
}
客户端:

这个是用来进行数据的接收

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using BestHTTP;
using BestHTTP.WebSocket;

public class WabData
{
    /// <summary>  
    /// The WebSocket address to connect  
    /// </summary>  
    private readonly string address = "ws://192.168.199.208:1818";

    /// <summary>  
    /// Default text to send  
    /// </summary>  
    private string _msgToSend = "Hello World!";

    /// <summary>  
    /// Debug text to draw on the gui  
    /// </summary>  
    private string _text = string.Empty;

    /// <summary>  
    /// Saved WebSocket instance  
    /// </summary>  
    private WebSocket _webSocket;

    private Queue<DataInfo> _msgQueue = new Queue<DataInfo>();

    public Queue<DataInfo> MsgQueue { get { return _msgQueue; } } 
    public WebSocket WebSocket { get { return _webSocket; } }
    public string Address { get { return address; } }
    public string Text { get { return _text; } }

    public string MsgToSend
    {
        get { return _msgToSend; }
        set
        {
            _msgToSend = value;
            SendMsg(value);
        }
    }

    public void OpenWebSocket()
    {
        if (_webSocket == null)
        {
            // Create the WebSocket instance  
            _webSocket = new WebSocket(new Uri(address));

            if (HTTPManager.Proxy != null)
                _webSocket.InternalRequest.Proxy = new HTTPProxy(HTTPManager.Proxy.Address, HTTPManager.Proxy.Credentials, false);

            // Subscribe to the WS events  
            _webSocket.OnOpen += OnOpen;
            _webSocket.OnMessage += OnMessageReceived;
            _webSocket.OnClosed += OnClosed;
            _webSocket.OnError += OnError;

            // Start connecting to the server  
            _webSocket.Open();
        }
    }

    public void SendMsg(string msg)
    {
        // Send message to the server  
        _webSocket.Send(msg);
    }

    public void CloseSocket()
    {
        // Close the connection  
        _webSocket.Close(1000, "Bye!");
    }

    /// <summary>  
    /// Called when the web socket is open, and we are ready to send and receive data  
    /// </summary>  
    void OnOpen(WebSocket ws)
    {
        Debug.Log("-WebSocket Open!\n");
    }

    /// <summary>  
    /// Called when we received a text message from the server  
    /// </summary>  
    void OnMessageReceived(WebSocket ws, string message)
    {
        DataInfo datainfo = JsonUtility.FromJson<DataInfo>(message);
        if (datainfo != null) _msgQueue.Enqueue(datainfo);
    }

    /// <summary>  
    /// Called when the web socket closed  
    /// </summary>  
    void OnClosed(WebSocket ws, UInt16 code, string message)
    {
        Debug.Log(string.Format("-WebSocket closed! Code: {0} Message: {1}\n", code, message));
        _webSocket = null;
    }

    /// <summary>  
    /// Called when an error occured on client side  
    /// </summary>  
    void OnError(WebSocket ws, Exception ex)
    {
        string errorMsg = string.Empty;
        if (ws.InternalRequest.Response != null)
            errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message);

        Debug.Log(string.Format("-An error occured: {0}\n",ex != null ? ex.Message : "Unknown Error " + errorMsg));
        _webSocket = null;
    }
}

//{"info":[{"area":11,"x":80,"y":50},{"area":5,"x":76,"y":48}]}
[System.Serializable]
public class DataInfo
{
    public Data[] info;
}

[System.Serializable]
public class Data
{
    public int area;
    public int x;
    public int y;
}
这个是用来获得上面存储的数据:

using System;
using UnityEngine;
using BestHTTP;
using BestHTTP.WebSocket;  

public class WebSocketSimpet : MonoBehaviour {

    #region Private Fields

    /// <summary>  
    /// The WebSocket address to connect  
    /// </summary>  
    string _address;  

    /// <summary>  
    /// Default text to send  
    /// </summary>  
    string _msgToSend;

    /// <summary>  
    /// Debug text to draw on the gui  
    /// </summary>  
    string _text;

    /// <summary>  
    /// GUI scroll position  
    /// </summary>  
    Vector2 _scrollPos;

    private WabData _wabData;

    #endregion

    #region Unity Events

    void Start()
    {
        _wabData = new WabData();
        _address = _wabData.Address;
        _msgToSend = _wabData.MsgToSend;
        _text = _wabData.Text;
    }

    void Update()
    {
        if (_wabData.MsgQueue.Count > 0)
        {
            DataInfo info = _wabData.MsgQueue.Dequeue();
            string json = JsonUtility.ToJson(info);
            Debug.Log(json);
        }
    }

    void OnDestroy()
    {
        if (_wabData.WebSocket != null)
            _wabData.WebSocket.Close();
    }

    void OnGUI()
    {
        _address = GUILayout.TextField(_address);

        if (_wabData.WebSocket == null && GUILayout.Button("Open Web Socket"))
        {
            _wabData.OpenWebSocket();

            _text += "Opening Web Socket...\n";
        }

        if (_wabData.WebSocket != null && _wabData.WebSocket.IsOpen)
        {
            if (GUILayout.Button("Send", GUILayout.MaxWidth(70)))
            {
                _text += "Sending message...\n";

                // Send message to the server  
                _wabData.WebSocket.Send(_msgToSend);
            }

            if (GUILayout.Button("Close"))
            {
                // Close the connection  
                _wabData.WebSocket.Close(1000, "Bye!");
            }
        }
    }

    #endregion
}


插件地址:http://download.csdn.net/download/agroupofruffian/10192849

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Unity UnityWebSocket插件是一款用于在Unity项目中实现WebSocket通信的插件WebSocket是一种新的网络通信协议,它建立在HTTP协议之上,可以提供全双工通信,使得客户端和服务器可以通过一次HTTP握手建立持久的连接,实现实时的双向通信。 Unity UnityWebSocket插件可以方便地在Unity使用WebSocket协议进行网络通信。它提供了简洁易用的API接口,开发者可以轻松地实现连接、发送和接收消息等操作。通过该插件,我们可以构建实时的游戏功能,例如聊天系统、多人游戏和实时更新等。 使用Unity UnityWebSocket插件,开发者可以通过几行代码实现WebSocket的连接和消息处理。首先需要创建WebSocket连接,通过指定服务器地址和端口号等参数进行连接。连接建立后,可以通过发送消息来与服务器进行通信,并通过接收消息事件来处理服务器返回的数据。 Unity UnityWebSocket插件还提供了一些高级功能,例如心跳机制和断线重连。心跳机制可以保持连接的稳定性,防止连接断开。断线重连功能可以在网络连接断开后自动重新连接服务器,确保通信的连续性。 总之,Unity UnityWebSocket插件是一款强大的工具,可以帮助开发者在Unity中实现WebSocket通信。它提供了简单易用的接口,并支持一些高级功能,使得开发者可以轻松地构建实时的游戏功能。该插件使用可以提高开发效率,为游戏开发带来更多可能性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值