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

这篇具有很好参考价值的文章主要介绍了Unity中使用WebSocket (ws://)的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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中使用WebSocket (ws://)的方法

 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<byte>(Encoding.UTF8.GetBytes("hello")), WebSocketMessageType.Binary, true, ct); //发送数据

            while (true)
            {
                var result = new byte[1024];
                await ws.ReceiveAsync(new ArraySegment<byte>(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文章来源地址https://www.toymoban.com/news/detail-489433.html

客户端代码:

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!");
    }


}

到了这里,关于Unity中使用WebSocket (ws://)的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java后端使用websocket实现与客户端之间接收及发送消息

    客户端请求websocket接口,连接通道=》我这边业务成功客户端发消息=》客户端自动刷新。 接口:ws://localhost:8080/websocket/xx 经测试,成功 如果是线上服务器连接,则需要在nginx里配置websocket相关内容,再重启nginx,代码如下 本地连接的时候用的是ws://,因为是http链接,但是如果是

    2024年02月16日
    浏览(42)
  • 【ChatGPT】如何使用Qt设计SocketIO类型的WebSocket协议客户端

    本文第一次发布 2023年03月24日09点28分 Authors ChatGPT / THDMI 最近写 Flask-SocketIO 服务端的时候,苦于不熟悉前端代码,想试着用 QT 来写客户端,但不清楚该怎么描述,以致于好像一直查的都是 RAW 类型的 WebSocket 协议处理,于是一直没找到 event 和 room 或者 namespace 处理方式。 简单

    2023年04月21日
    浏览(59)
  • Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息

    Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息 回调函数处理

    2024年02月13日
    浏览(56)
  • 服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写的参考笔记

    2023/8/29 19:21:11 服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写 2023/8/29 19:22:25 在服务器端使用Django WebSocket和客户端使用Uniapp的情况下,以下是代码示例来实现服务器端和客户端之间的群组互发消息。 服务器端代码 (使用Django Chann

    2024年02月11日
    浏览(43)
  • AI对话交互场景使用WebSocket建立H5客户端和服务端的信息实时双向通信

    WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许 服务端主动向客户端推送数据 。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HT

    2024年02月03日
    浏览(47)
  • Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中

    SpringBoot+Vue整合WebSocket实现前后端消息推送: SpringBoot+Vue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客 上面实现ws推送数据流程后,需要在windows上使用ws客户端定时记录收到的数据到文件中,这里 文件使用SQLite数据库进行存储。 Winform中操作Sql

    2024年02月22日
    浏览(44)
  • 客户端 WebSocket详细用法

    WebSocket是一种网络通信协议,很多高级功能都需要用到它。 有些人会想,既然我们已经有了HTTP协议了,为什么还要花时间学另一种协议呢?这个协议到底有什么魔力,值得我们花时间学它。 因为 HTTP 协议有一个缺陷:通信只能由客户端发起。只能是客户端向服务器发出请求

    2024年02月04日
    浏览(41)
  • Java WebSocket客户端

    1.依赖 2.代码 1.依赖 2.代码 2.1 自定义 websocket handler 2.2 将websocket handler加入容器 2.3 定时器监控

    2024年02月16日
    浏览(40)
  • Java实现websocket客户端

    常规情况下,大多数时候Java后台作为websocket服务端,实现方式也比较简单,网上很多案例代码。但是很多时候项目中服务与服务之间也需要使用websocket通信,此时项目就需要实现客户端功能。 步骤一:导入依赖: 步骤二:实现WebSocketClient抽象类: 该类中和websocket服务端接口

    2024年02月16日
    浏览(55)
  • SpringBoot WebSocket做客户端

    常见的都是springboot应用做服务,前端页面做客户端,进行websocket通信进行数据传输交互。但其实springboot服务也能做客户端去连接别的webSocket服务提供者。 刚好最近在项目中就使用到了,需求背景大概就是我们作为一个java段应用需要和一个C语言应用进行通信。在项目需求及

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包