草庐IT

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

十幺卜入 2023-04-07 原文

前言

该功能主要是项目上的需求,按后端的需求就是我们通过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

有关Unity3d C#实现基于SocketIOUnity的与后端(node.js为例)Socket通信功能(含工程)的更多相关文章

  1. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  2. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  3. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  4. unity---接入Admob - 2

    目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

  5. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  6. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  7. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  8. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  9. u盘安装系统(win10为例) - 2

    下载微PE工具箱进入官网下载微PE工具箱-下载 安装好后,打开微PE工具箱客户端,选择安装PE到U盘 PE壁纸可选择自己喜欢的壁纸,勾选上包含DOS工具箱,个性化盘符图标 下载原版系统进入网站下载镜像NEXT,ITELLYOU如果没有账号,注册一下就好进入选择开始使用选择win10 这里我们选择消费者版,用迅雷把BT种子下载下来 下面的两个盘符,是PE工具箱安装进U盘后,分成的盘符,注意EFI的盘符,这里面不能删东西,也不能添东西,另一个盘符可以当做正常的U盘空间使用,我们现在需要把下载下来的景象文件复制到正常的U盘空间中去 这个时候我们的系统U盘就只做好了 安装系统我们将U盘插入电脑,开机,

  10. Unity Shader 学习笔记(5)Shader变体、Shader属性定义技巧、自定义材质面板 - 2

    写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c

随机推荐