Unity3d C#实现基于SocketIOUnity的与后端(node.js为例)Socket通信功能(含工程)

news2024/9/22 5:46:34

#前言
该功能主要是项目上的需求,按后端的需求就是我们通过SocketIO进行通信,之前游戏通信功能大多是基于原始的Socket进行封装,需要对包体进行设计,还需要粘包拆包等系列操作,属实有点麻烦。这次尝试了SocketIOUnity的使用,感觉还是挺快速的就是实现了,而且也比较方便,所以将基本过程进行了总结分享。

效果

在这里插入图片描述
在这里插入图片描述

#开源库

这个功能的实现主要基于GitHub上itisnajim封装的SocketIOUnity插件 ,而该插件是一个将socket.io-client-csharp与Unity一起工作的包装器, 支持 socket.io 服务器 v2/v3/v4,并实现了 http 轮询和 websocket等功能。这也使得我们能顺畅的在Unity3d上使用socket.io.

准备Unity工程

直接将这个库克隆下来,或者下载(Download ZIP)可以看到如下目录:
在这里插入图片描述

新建一个Unity工程,并将我们这里的文件夹复制到工程中的Assets\SocketIO文件夹下。

也可以通过Unity工程中的 Package Manager进行安装:复制此网址:然后在 Unity 中打开Window -> Package Manager -> 并单击(+) add package from git URL…
并将

https://github.com/itisnajim/SocketIOUnity.git

贴到地址框内。

这是在工程中,可以看到报错:
在这里插入图片描述

Assets\SocketIO\Samples\Sample\SocketManager.cs(4,22): error CS0234:
The type or namespace name ‘Newtonsoft’ does not exist in the
namespace ‘SocketIOClient’ (are you missing an assembly reference?)

大致意思是缺失’Newtonsoft’ ,经过研究发现socket.io-client-csharp中包含SocketIOClient.Newtonsoft.Json,
在这里插入图片描述

将其下载放入工程Assets\SocketIO文件夹下后错误消除。

服务端

服务端有个案例脚本(SocketIO\Samples\Server\index.js)代码如下:

'use strict';

const http = require('http');
const socket = require('socket.io');
const server = http.createServer();
const port = 11100;

var io = socket(server, {
    pingInterval: 10000,
    pingTimeout: 5000
});

io.use((socket, next) => {
    if (socket.handshake.query.token === "UNITY") {
        next();
    } else {
        next(new Error("Authentication error"));
    }
});

io.on('connection', socket => {
  console.log('connection');

  setTimeout(() => {
    socket.emit('connection', {date: new Date().getTime(), data: "Hello Unity"})
  }, 1000);

  socket.on('hello', (data) => {
    console.log('hello', data);
    socket.emit('hello', {date: new Date().getTime(), data: data});
  });

  socket.on('spin', (data) => {
    console.log('spin');
    socket.emit('spin', {date: new Date().getTime(), data: data});
  });

  socket.on('class', (data) => {
    console.log('class', data);
    socket.emit('class', {date: new Date().getTime(), data: data});
  });
});


server.listen(port, () => {
  console.log('listening on *:' + port);
});

这里将其通过node.js启动起来。
Node.js的下载、安装以及环境配置在此就不赘述了,网上一搜一大堆。
在cmd命令行中跳转至Assets\SocketIO\Samples\Server目录,并执行npm install命令安装关联的包体:
在这里插入图片描述

安装完成后,输入node index执行脚本:
在这里插入图片描述

这就完成了服务端的运行。

运行案例

要Unity3d端能连上我们启动好的服务后台还需要修改一下Unity工程的SocketManager.cs脚本中的Uri地址,将其修改为:

var uri = new Uri("http://127.0.0.1:11100");

因为我们服务器后端监听的是 *:11100。

这样我们启动运行Unity工程,就能连接node.js 并可以进行通信:
在这里插入图片描述

这里先收到了后端返回的连接信息,点击按钮发送了类、旋转指令和其它json数据并获得了服务端的响应。只要自己定义数据和事件名称(EventName)就可以实现自己的功能了。

其它

发送信息

socket.Emit("eventName");socket.Emit("eventName", "Hello World");
socket.Emit("eventName", someObject);
socket.EmitStringAsJSON("eventName", "{\"foo\": \"bar\"}");
await client.EmitAsync("hi", "socket.io"); // Here you should make the method async

##接收信息

socket.On("eventName", (response) =>
{
    /* Do Something with data! */
    var obj = response.GetValue<SomeClass>();
});

##连接/断开

socket.Connect();
await socket.ConnectAsync();
socket.Disconnect();
await socket.DisconnectAsync();

主线程问题

如果要使用 Unity 游戏对象(例如:旋转对象)或使用 PlayerPrefs 系统保存数据,请使用以下命令:

// Set (unityThreadScope) the thread scope function where the code should run.
// Options are: .Update, .LateUpdate or .FixedUpdate, default: UnityThreadScope.Update
socket.unityThreadScope = UnityThreadScope.Update; 
// "spin" is an example of an event name.
socket.OnUnityThread("spin", (response) =>
{
    objectToSpin.transform.Rotate(0, 45, 0);
});

或者

 socket.OnAnyInUnityThread((name, response) =>
 {
     Debug.Print("Received On " + name + " : " + response.GetValue().GetRawText() + "\n");
  });

再或者

socket.On("spin", (response) =>
{
    UnityThread.executeInUpdate(() => {
        objectToSpin.transform.Rotate(0, 45, 0);
    });
    /*     or      UnityThread.executeInLateUpdate(() => { ... });    or     UnityThread.executeInFixedUpdate(() => { ... });    */
});

版本问题

虽然该库?支持 socket.io 服务器 v2/v3/v4等版本,但是使用不同版本需要不同的设置,这里也是我走了很长弯路的地方。这就需要设置这个EIO:
在这里插入图片描述

如果您的服务器使用的是 socket.io 服务器 v2.x,请明确设置为 3。

这里我的服务器端他们刚好使用的就是2.x版本所以造成怎么都连接不上。 我的设置如下:

        var uri = new Uri("https://127.0.0.1:11100");
        socket = new SocketIOUnity(uri, new SocketIOOptions
        {
            Query = new Dictionary<string, string>
                {
                    {"code", SystemInfo.deviceUniqueIdentifier}
                }
            ,
            EIO = 3,
            //ExtraHeaders = header,
            Transport = SocketIOClient.Transport.TransportProtocol.WebSocket
        }); 

工程

https://download.csdn.net/download/qq_33789001/87366117

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Exynos_4412——RTC实验

目录 一、ADC小作业 二、RTC简介 三、Exynos_4412下的RTC控制器 四、RTC中的寄存器 五、RTC编程 六、RTC小作业 一、ADC小作业 电压在1501mv~1800mv时&#xff0c;LED2、LED3、LED4、LED5点亮 电压在1001mv~1500mv时&#xff0c;LED2、LED3、LED4点亮 电压在501mv~1000m…

什么是芯片老化测试?芯片老化测试系统NSAT-2000解决方案

随着半导体电子技术的进步&#xff0c;老化测试已成为保证产品质量的关键流程。除了半导体元件外&#xff0c;PCB、IC 和处理器部件也都需要在老化条件下进行测试。本篇文章纳米软件Namisoft小编将带大家分享一下关于芯片老化测试系统的相关知识。 一、什么是芯片老化测试&…

开发工具篇第十二讲:常用开发库 - Lombok工具库详解

开发工具篇第十二讲&#xff1a;常用开发库 - Lombok工具库详解 Lombok是一款非常实用Java工具&#xff0c;可用来帮助开发人员消除Java的冗长代码&#xff0c;尤其是对于简单的Java对象&#xff08;POJO&#xff09;。实际上我并不推荐使用Lombok&#xff08;不主动使用它&…

CANoe测试TC8

OPEN联盟发布的TC8是目前行业内关于车载以太网的标准测试规范之一。 CANoe环境需要硬件和软件: 硬件是CANoe设备&#xff0c;用来连接电脑和DUT&#xff0c;TC8测试的是以太&#xff0c;那么CANoe设备必须支持以太才行&#xff0c;目前VN5640以上都是支持的。 软件需要安装CANo…

对git rebase 和git merge的理解

一、是什么 在使用 git 进行版本管理的项目中&#xff0c;当完成一个特性的开发并将其合并到 master 分支时&#xff0c;会有两种方式&#xff1a; git mergegit rebase git rebase 与 git merge都有相同的作用&#xff0c;都是将一个分支的提交合并到另一分支上&#xff0c;…

物联网技术在地下综合管廊智能化建设中的应用实例分析

摘 要:物联网是21世纪传感技术、通信技术、信息技术的应用大集成利用物联网技术实现地下综合管廊的智能化管理符合经济和城市规划发展的需要分析了物联网技术的特点及地下综合管廊建设中物联网技术的应用并结合物联网技术在地下综合管廊建设的应用实例对物联网技术在地下综合…

Qt扫盲-Windows任务栏使用总结

Qt扫盲-Windows任务栏使用总结一、概述二、覆盖图标和进度指示器三、跳转列表四、缩略图工具栏一、概述 任务栏为用户提供了访问桌面上打开的应用程序的权限。Windows自动在任务栏上创建用于访问应用程序窗口的按钮。 从 Windows 7到Windows10 都有效果。就是在任务栏上的一个…

基于springboot框架个人博客管理系统

一、项目简介 本项目是一套基于springboot框架实现的个人博客管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&a…

头歌:UDP Ping程序实现 客户端创建UDP套接字

头歌平台&#xff1a;头歌实践教学平台 (educoder.net)创建数据包套接字套接字 Socket 实质上提供了主机间进程通信的连接点。进程通信之前&#xff0c;双方首先必须各自创建一个连接点,否则是没有办法建立联系并相互通信的。一个完整的 Socket {协议,本地地址,本地端口,远程地…

在 React 中使用 i18next

1. 安装依赖 npm i i18next react-i18next i18next-browser-languagedetectori18next 提供了翻译的基本能力。react-i18next 是 i18next 的一个插件&#xff0c;用来降低 react 的使用成本。i18next-browser-languagedetector 是用来检测浏览器语言的插件。 2. 在src下创建i18…

.net core 中使用confluent kafka构建生产者

创建.net 6 API安装依赖包 创建kafka生产者 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Confluent.Kafka; using Confluent.Kafka.Admin; using KafkaHelper.Config; using Microsoft.Exte…

Cuk拓扑产生负压

1、基础拓扑的输入输出电流连续情况 1>Buck电路 图中绿色波形为输入端的电流&#xff08;测的图中MOS上的电流&#xff09;&#xff0c;蓝色的输出端的电流&#xff08;图中电感L4的电流&#xff09;&#xff0c;可以看出输入端电流不连续&#xff0c;输出端电流连续。 2&…

Revit中项目特别大如何将项目完整的体现在图纸中?

一、Revit中项目特别大如何将项目完整的体现在图纸中? 遇到项目特别大&#xff0c;在一张图纸是放置不下时&#xff0c;如图1所示&#xff0c;怎样才能将项目完整的体现在图纸当中? 在遇到特别大的项目可能会在图纸中放不下&#xff0c;在这种情况下我们要用拼接线来处理。在…

【JavaEE】SSM框架

文章目录一、Spring1、Spring相关概念1.1 Spring Framework系统架构1.2 核心概念(lOC、lOC容器、Bean、DI)2、入门案例2.1 IOC入门案例2.2 DI入门案例3、lOC相关内容3.1 bean配置3.2 bean实例化3.3 bean的生命周期3.3.1 控制bean生命周期执行的方法3.3.2 bean销毁时机4、DI相关…

AI智能分析在智慧电厂的典型应用

电力供应是整个社会生产、人民生活的基本保证之一。智慧电力作为城市智能化发展的客观需求&#xff0c;是智慧城市的重要基础&#xff0c;也是智慧城市建设的一项重要内容。 智慧能源用最前沿技术淋漓尽致地表达着对未来能源发展趋势的理解与实践。智慧电力将多项创新成果应用于…

【前端】Vue项目:旅游App-(6)city:隐藏TabBar的2种方法

文章目录目标过程与代码方法1&#xff1a;通过路由隐藏方法2&#xff1a;用样式隐藏对方法2封装总代码修改的文件common.cssindex.jscity.vue目标 city页是点击上篇“广州”位置所跳转的页面。此页面要隐藏TabBar。 过程与代码 city页要隐藏TabBar。我们这里有两种隐藏的方法…

【Effective Objective - C】—— 读书笔记(五)

【Effective Objective - C】—— 读书笔记&#xff08;五&#xff09; 内存管理 文章目录【Effective Objective - C】—— 读书笔记&#xff08;五&#xff09;内存管理29.理解引用计数引用计数工作原理属性存取方法中的内存管理自动释放池保留环要点30.以ARC简化引用计数使…

Qt扫盲-QSystemTrayIcon理论总结

QSystemTrayIcon理论总结一、概述二、使用对象三、使用四、常用函数介绍1. 静态函数2. 公共槽函数3. 信号一、概述 现代操作系统通常在桌面上提供一个特殊的区域&#xff0c;称为系统托盘或通知区域&#xff0c;长期运行的应用程序可以在这里显示图标和短消息。什么意思呢&…

【Spring】1. Java对象序列化和反序列化

1. 概念 1.1 序列化 将数据结构或对象转换成二进制字节流的过程 1.2 反序列化 序列化的反过程把二进制字节流恢复为数据结构或对象的过程1.3 序列化的目的&#xff1a; 通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。 2. 为什么要进行序列化&#xff1f;&…

【Linux】Linux开发工具(一)——vim工具

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Linux》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 1.什么是vim 1.1什么是vim 1.2vim和vi的区别&#xff1a; 2.vim基础 2.…