插件:Best HTTP

一、简介

WebSocket

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

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

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

二、使用

Best HTTP插件:这款插件不但支持WebSockets,还支持HTTP,Sockets等通信方式是一款不错的插件。也支持打包Webgl。下边记录两种Unity客户端使用WebSocket的方法。

插件

绑定

将插件包拖入unity然后在代码里引入插件类,最后写代码

代码

using UnityEngine;
using System;
using BestHTTP.WebSocket;
using System.Collections;
 
public class WebSocketClient : MonoBehaviour
{
    public string address = "ws://127.0.0.1:8002";

    WebSocket webSocket;
    private bool lockReconnect = false;
    private Coroutine _pingCor, _clientPing, _serverPing;

    private void Start()
    {
        CreateWebSocket();
    }

    private void Update()
    {
        Debug.Log(lockReconnect);
    }

    /*
     * 创建并初始化连接 start -------------------------------------------------------------------------------------------------------------------
     */
    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();
        }

    }
    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();
    }
    //end -------------------------------------------------------------------------------------------------------------------

    /*
     * 发送信息
     */
    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!");
    }

    /*
     * 重新连接
     */
    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;
    }

    /*
     * 心跳检测 start -------------------------------------------------------------------------------------------------------------------
     */

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


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/618827.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【保姆级教程】VMware Workstation Pro的虚拟机导入vritualbox详细教程

解决方案 1、OVF格式2、VMX格式 1、OVF格式 选定需要导出的虚拟机(关闭或者挂起状态下)依次选择文件-导出为ovf 在Vritualbox导入刚刚导出的.ovf文件 更改路径,按实际需要修改 成功导入 2、VMX格式 如果在VMware Workstation Pro导出的…

算法练习之双指针算法

目录 前言 一、移动零【做题链接】 二、复写零【做题链接】 三、快乐数【做题链接】 四、盛水最多的容器【做题链接】 五、查找总价值为目标值的两件商品【做题链接】 六、三数之和【做题链接】 七、四数之和 【做题链接】 八、有效三角形的个数【做题链接】 总结 前言…

MapReduce | 二次排序

1.需求 主播数据--按照观众人数降序排序,如果观众人数相同,按照直播时长降序 # 案例数据 用户id 观众人数 直播时长 团团 300 1000 小黑 200 2000 哦吼 400 7000 卢本伟 100 6000 八戒 250 5000 悟空 100 4000 唐僧 100 3000 # 期望结果 哦吼 4…

STC8增强型单片机开发【电位器案例(ADC)⭐⭐】

目录 一、引言 二、硬件准备 三、电路连接 四、软件编程 五、案例实现 六、总结 一、引言 STC8系列增强型单片机以其高性能、低功耗和丰富的外设接口,在嵌入式系统开发中得到了广泛应用。其中,模数转换器(ADC)是单片机的一…

鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式

运行机制 共享好端端的一词,近些年被玩坏了,共享单车,共享充电宝,共享办公室,共享雨伞… 甚至还有共享女朋友,真是人有多大胆,共享有多大产。但凡事太尽就容易恶心到人,自己也一度被 共享内存 恶心到了&am…

代码生成工具1 ——项目简介和基础开发

1 项目简介 需要提前在数据库建好表,然后执行代码生成工具,会生成简单的Java文件,避免重复编写增删改查代码。类似的工具网上有很多,本人开发这个工具属于自娱自乐。这个专栏会记录开发的过程。 2 项目搭建 数据库使用MySQL &…

MySQL中的子查询

子查询,在一个查询语句中又出现了查询语句 子查询可以出现在from和where后面 from 表子查询(结果一般为多行多列)把查询结果继续当一张表对待 where 标量子查询(结果集只有一行一列)查询身高最高的学生,查询到一个最高身高 列子查询(结果集只有一行多列) 对上表进行如下操作 …

韩顺平0基础学Java——第10天

p202-233 类与对象(第七章) 成员方法 person类中的speak方法: 1.public表示方法是公开的 2.void表示方法没有返回值 3.speak()中,speak表示方法名,括号是形参列表。 4.大括号为方法体&am…

SpringCloud2024最新版链路追踪教程micrometer+zipkin

本文基于B站尚硅谷2024版springcloud教学视频,主要用于自己学习记录以及分享技术,侵权私删 自己本机环境信息: jdk:17.0.10springboot:3.2.0springcloud:2023.0.0 micrometer 之前行业内使用的分布式链路…

机器学习案例:加州房产价格(一)

参考链接:https://hands1ml.apachecn.org/2/ 假设你是被一家地产公司雇佣的数据科学家,现在需要做一些工作。 公司所给的数据集是StatLib 的加州房产价格数据集。这个数据集是基于 1990 年加州普查的数据。数据已经有点老,但它有许多优点&…

HCIP的学习(15)

第六章,BGP—边界网关协议 自治系统—AS ​ 定义:由一个单一的机构或组织所管理的一系列IP网络及其设备所构成的集合。 ​ AS的来源: 整个网络规模过大,会导致路由信息收敛速度过慢,设备对相同目标认知不同。AS之间…

HCIP 6(BGP综合实验)

一、实验拓扑 二、实验要求 1.AS1中存在两个环回,一个地址为192.168.1.0/24,该地址不能在任何协议中宣告;AS3中存在两个环回,一个地址为192.168.2.0/24,该地址不能在任何协议中宣告,最终要求这两个环回可以…

批量文本高效编辑神器:轻松拆分每行内容,一键保存更高效!轻松实现批量拆分与保存

文本处理成为我们日常工作中的一项重要任务。然而,面对大量的文本内容,传统的逐行编辑方式往往显得繁琐且效率低下。那么,有没有一种更高效、更便捷的解决方案呢?答案是肯定的——批量文本高效编辑神器,让您的文本处理…

用命令运行Java程序

1、创建一个类 2、在类文件路径下执行命令(编译),生成.class javac 类名.java 3、运行.class文件 java 类名

机器学习案例:加州房产价格(二)

参考链接:https://hands1ml.apachecn.org/2/ 设计好系统后,要开始在工作区编写代码来解决问题了。 下载数据 首先我们需要先得到数据集。 一般情况下,数据是存储于关系型数据库(或其它常见数据库)中的多个表、文档、…

WSL——Centos7.9安装

1. 下载cenos镜像包 centos7.9下载地址 下载CentOS7.zip 2. 安装 将下载的zip文件解压至安装目录(这个目录就是安装centos的目录,可以是c盘之外的盘) 双击CentOS.exe 安装完成后,在安装目录下会多出一个ext4.vhdx 3. 启动 使用 wsl --list 可以查…

linux学习:linux视频输出+FRAME BUFFER+jpeg库+lcd上显示

目录 概念 使用 struct fb_fix_screeninfo{ } struct fb_bitfield { } struct fb_var_screeninfo{ } 例子1 例子2 例子3 jpeg库 步骤 概念 framebuffer 是一种很底层的机制,在 Linux 系统中,为了能够屏蔽 各种不同的显示设备的具体细节&#…

使用 scrapyd 部署 scrapy

1.scrapyd 是什么? Scrapyd 是一个用于部署和运行 Scrapy 爬虫项目的服务器应用程序。它使得你可以通过 HTTP 命令来部署、管理和执行多个 Scrapy 爬虫,非常适合持续集成和生产环境中的爬虫部署。 2.安装scrapyd 并使用 2.1 安装 scrapyd F:\scrapydTes…

CSS之高级技巧

目录 CSS高级技巧精灵图(精灵技术)字体图标iconfontCSS三角CSS用户界面样式vertical-align属性应用溢出的文字省略号显示常见布局技巧 CSS高级技巧 精灵图(精灵技术) 为什么? 目的:有效减少服务器接受和…

vs code中如何使用git

由于本地代码有了一些储备,所以想通过网址托管形式,之前一直使用了github,但是鉴于一直被墙,无法登录账号,所以选择了国内的gitee来作为托管网站。 gitee的网址:Gitee - 基于 Git 的代码托管和研发协作平台…