Unity中使用WebSocket (ws://)的方法 您所在的位置:网站首页 unity服务器用什么语言 Unity中使用WebSocket (ws://)的方法

Unity中使用WebSocket (ws://)的方法

2024-07-18 08:23| 来源: 网络整理| 查看: 265

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket与http

其实从历史上来讲,websocket是为了克服http无法双向通信而引入的,在通常的使用中,可以复用http的端口与功能,除此外,他们没有其他的联系,而是完全是独立的协议,通常情况下,http是单向的web 服务,而websocket是全双工的,服务器和客户端可以实时的传输信息,在引用时他们可以在http服务器上同时部署,特别是在NodeJs中。

WebSocket与Socket 

那么websocket和socket是什么关系呢? 其实可以理解为websocket是在socket的基础上实现的,其基于消息帧和TCP协议,而socket更通用,在编程中,可以选在tcp,udp,也需要自己控制数据流格式,每次的数据的长度都需要自己控制与读取。

下边记录两种Unity客户端使用WebSocket的方法。

1.不使用插件的客户端

引入System.Net.WebSockets;命名空间。

在使用过程中发现这种方法打包WebGl的的时候是存在问题的。

具体使用方法如下:

WebSocket 类 (System.Net.WebSockets) | Microsoft Learn

 Unity客户端代码:

using System; using System.Net.WebSockets; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.UI; public class test4 : MonoBehaviour { private void Start() { WebSocket(); } public async void WebSocket() { try { ClientWebSocket ws = new ClientWebSocket(); CancellationToken ct = new CancellationToken(); //添加header //ws.Options.SetRequestHeader("X-Token", "eyJhbGciOiJIUzI1N"); Uri url = new Uri("ws://xxx.xxx.xxx.xx:18x/xxx/xxx"); await ws.ConnectAsync(url, ct); await ws.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes("hello")), WebSocketMessageType.Binary, true, ct); //发送数据 while (true) { var result = new byte[1024]; await ws.ReceiveAsync(new ArraySegment(result), new CancellationToken());//接受数据 var str = Encoding.UTF8.GetString(result, 0, result.Length); Debug.Log(str); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } } 2.使用Best HTTP插件

这款插件不但支持WebSockets,还支持HTTP,Sockets等通信方式是一款不错的插件。也支持打包Webgl

插件地址:

https://download.csdn.net/download/f402455894/87597949?spm=1001.2014.3001.5501

客户端代码: using UnityEngine; using System; using BestHTTP.WebSocket; using Newtonsoft.Json; public class GaoYaGuHuaLu : MonoBehaviour { string address = "ws://10.xxx.xx.193:1880/xxx"; WebSocket webSocket; public GaoYaGuHuaLuEntity gaoYaGuHuaLu = new GaoYaGuHuaLuEntity(); private void Awake() { } private void Start() { Init(); } public void Init() { if (webSocket == null) { webSocket = new WebSocket(new Uri(address)); #if !UNITY_WEBGL webSocket.StartPingThread = true; #endif // Subscribe to the WS events webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageRecv; webSocket.OnBinary += OnBinaryRecv; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; // Start connecting to the server webSocket.Open(); } } public void Destroy() { if (webSocket != null) { webSocket.Close(); webSocket = null; } } void OnOpen(WebSocket ws) { Debug.Log("OnOpen: "); // webSocket.Send("我来啦"); } void OnMessageRecv(WebSocket ws, string message) { Debug.LogFormat("OnMessageRecv: msg={0}", message); } void OnBinaryRecv(WebSocket ws, byte[] data) { Debug.LogFormat("OnBinaryRecv: len={0}", data.Length); } void OnClosed(WebSocket ws, UInt16 code, string message) { Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message); webSocket = null; } void OnError(WebSocket ws, string ex) { string errorMsg = string.Empty; #if !UNITY_WEBGL || UNITY_EDITOR if (ws.InternalRequest.Response != null) { errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message); } #endif Debug.LogFormat("OnError: error occured: {0}\n", (ex != null ? ex : "Unknown Error " + errorMsg)); webSocket = null; } public void OnClose() { // 关闭连接 webSocket.Close(1000, "Bye!"); } } 加上心跳检测和断线重连 using UnityEngine; using System; using System.Collections; using System.Collections.Generic; using BestHTTP; using BestHTTP.WebSocket; using BestHTTP.Examples; public class ZGAndroidcCient : MonoBehaviour { // w ws://XXXX:7799 public string address = "ws://XXXX:7799"; WebSocket webSocket; private bool lockReconnect = false; private Coroutine _pingCor, _clientPing, _serverPing; private void Start() { CreateWebSocket(); } void CreateWebSocket() { try { webSocket = new WebSocket(new Uri(address)); #if !UNITY_WEBGL webSocket.StartPingThread = true; #endif InitHandle(); webSocket.Open(); } catch (Exception e) { Debug.Log("websocket连接异常:" + e.Message); ReConnect(); } } private void Update() { Debug.Log(lockReconnect); } void InitHandle() { RemoveHandle(); webSocket.OnOpen += OnOpen; webSocket.OnMessage += OnMessageReceived; webSocket.OnClosed += OnClosed; webSocket.OnError += OnError; } void RemoveHandle() { webSocket.OnOpen -= OnOpen; webSocket.OnMessage -= OnMessageReceived; webSocket.OnClosed -= OnClosed; webSocket.OnError -= OnError; } void OnOpen(WebSocket ws) { Debug.Log("websocket连接成功"); webSocket.Send("一个客户端连过来了"); if (_pingCor != null) { StopCoroutine(_pingCor); _pingCor = null; } _pingCor = StartCoroutine(HeartPing()); // 心跳检测重置 HeartCheck(); } void OnMessageReceived(WebSocket ws, string message) { // 如果获取到消息,心跳检测重置 // 拿到任何消息都说明当前连接是正常的 HeartCheck(); Debug.Log(message); } void OnClosed(WebSocket ws, UInt16 code, string message) { Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message); webSocket = null; ReConnect(); } void OnError(WebSocket ws, string ex) { string errorMsg = string.Empty; #if !UNITY_WEBGL || UNITY_EDITOR if (ws.InternalRequest.Response != null) { errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message); } #endif Debug.LogFormat("OnError: error occured: {0}\n", (ex != null ? ex : "Unknown Error " + errorMsg)); webSocket = null; ReConnect(); } void ReConnect() { if (this.lockReconnect) return; this.lockReconnect = true; StartCoroutine(SetReConnect()); } private IEnumerator SetReConnect() { Debug.Log("正在重连websocket"); yield return new WaitForSeconds(5); CreateWebSocket(); lockReconnect = false; } //心跳检测 private void HeartCheck() { if (_clientPing != null) { StopCoroutine(_clientPing); _clientPing = null; } if (_serverPing != null) { StopCoroutine(_serverPing); _serverPing = null; } _clientPing = StartCoroutine(ClientPing()); } // 这里发送一个心跳,后端收到后,返回一个心跳消息 // onmessage拿到返回的心跳就说明连接正常 private IEnumerator ClientPing() { yield return new WaitForSeconds(5); WebSend("heartbeat"); _serverPing = StartCoroutine(ServerPing()); } // 如果超过一定时间还没重置,说明后端主动断开了 // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 private IEnumerator ServerPing() { yield return new WaitForSeconds(5); if (webSocket != null) { webSocket.Close(); } } //发送心跳 private IEnumerator HeartPing() { while (true) { yield return new WaitForSeconds(5); this.WebSend("Heartbeat"); } } //向服务端发送信息 public void WebSend(string msg) { if (webSocket == null || string.IsNullOrEmpty(msg)) return; if (webSocket.IsOpen) { webSocket.Send(msg); } } public void OnClose() { // 关闭连接 webSocket.Close(1000, "Bye!"); } }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有