Unity使用webSocket与服务器通信(二)——C#服务器端使用Fleck时的简单服用方法
C#服务端用到Fleck包,它包含哪些可用的回调函数,有哪些常用的api方法?
演示:服务端收到Unity用户发来的信息
1、Fleck服务器提供哪些回调函数
Fleck提供的回调函数有下面几种:
//用户连入服务器时...
Action OnOpen { get; set; }//用户与服务器断开连接时...
Action OnClose { get; set; }//收到字符串消息时...
Action<string> OnMessage { get; set; }//收到二进制数据时...
Action<byte[]> OnBinary { get; set; }//收到别人发来的ping信息时...
Action<byte[]> OnPing { get; set; }//收到别人发来的pong信息时...
Action<byte[]> OnPong { get; set; }//出错的时候调用...[?谁出错,服务器出错还是连接出错,出的是什么错?]
Action<Exception> OnError { get; set; }
2 、服务器提供的其它API
其它常用的api主要有:
//发送字符串
Task Send(string message);//发送字节码(二进制数据)
// 1Byte = 8 bits
// 1KB = 1024 Bytes
// 1MB = 1024KB
Task Send(byte[] message);//发送一个ping信息
Task SendPing(byte[] message);//发送一个pong信息
Task SendPong(byte[] message);//关闭连接
void Close();//关闭连接?关闭连接池中指定序号的连接?
void Close(int code);
- ping pong的作用是啥?
WebSocket为了保持客户端、服务端的实时双向通信,需要确保客户端、服务端之间的TCP通道保持连接没有断开。然而,对于长时间没有数据往来的连接,如果依旧长时间保持着,可能会浪费包括的连接资源。但不排除有些场景,客户端、服务端虽然长时间没有数据往来,但仍需要保持连接。这个时候,可以采用心跳来实现。
发送方->接收方:ping;
接收方->发送方:pong;
C# 在WinForm里使用Fleck作为服务器的简单示例代码:
private void button1_Click(object sender, EventArgs e)
{if (hasStartedServer)//不重复启动服务器实例return;var server = new WebSocketServer("ws://192.168.0.137:8081"); //ws://localhost:8081 ws://127.0.0.0:8181server.Start(socket =>{//连上时...socket.OnOpen = () =>{Debug.WriteLine($"有新用户连入:{socket.ConnectionInfo.ClientIpAddress}");};//断开时...socket.OnClose = () =>{Debug.WriteLine($"用户断开连接:{socket.ConnectionInfo.ClientIpAddress}");UserSockets.First(x => x.socket.ConnectionInfo.Id == socket.ConnectionInfo.Id).connected = false;};//收到string信息时...socket.OnMessage = message =>{socket.Send($"服务器收到消息 : {DateTime.Now.ToString()}");Debug.WriteLine($"收到一条消息,来自:{socket.ConnectionInfo.ClientIpAddress}");Debug.WriteLine(message);var cmd = message.Split("#")[0];if (cmd == "name"){var userID = message.Split("#")[1];Debug.WriteLine($"收到一条消息,来自用户:{userID} 连接id:{socket.ConnectionInfo.Id}");UserSocket user = new UserSocket(){userID = userID,socket = socket,connected = true};UserSockets.Add(user);}};//收到二进制信息时...socket.OnBinary = bytes =>{var userName = UserSockets.First(x => x.socket.ConnectionInfo.Id == socket.ConnectionInfo.Id).userID;Debug.WriteLine($"收到二进制数据,长度为{bytes.Length}Bytes,来自ip:{socket.ConnectionInfo.ClientIpAddress},userID ={userName}");};});Debug.WriteLine("服务器已经启动!");hasStartedServer = true;
}
3、服务器与客户端建立的连接包含哪些信息
public interface IWebSocketConnectionInfo{string SubProtocol { get; }string Origin { get; }string Host { get; }string Path { get; }string ClientIpAddress { get; }int ClientPort { get; }IDictionary<string, string> Cookies { get; }IDictionary<string, string> Headers { get; }Guid Id { get; }string NegotiatedSubProtocol { get; }}
每次建立的连接,Id号是唯一的。
4、服务器接收数据时是否会粘包?
经测试,同一连接连续向服务器发送数据时,每次OnBinary收到的消息是完整的。
还没瞻仰源码,后面有空看看,server端TCP接收数据时,应该是做了包的合并处理,接到一个整坨数据,才调用的OnBinary。
- Unity用户端代码
连发50笔数据,每次发送1M bytes
int i = 0;while (i < 50) //连发50笔数据,每次发送1M bytes{var bytesArray = new byte[1048576]; // 1024 * 1024 = 1048576await websocket.Send(bytesArray); //或者直接await,测试结果一样Debug.Log($"发送数据-{i}");i++;}
- C#服务端代码
每当收到数据时,把收到的数据长度打印出来
socket.OnBinary = bytes =>{Debug.WriteLine($"收到二进制数据,长度为{bytes.Length}Bytes,来自{socket.ConnectionInfo.ClientIpAddress}");};
5、同一个ip上有两个应用同时发来信息,如何区分这些连接属于哪个用户?
简要思路:每个用户端启动的时候,需要用户名登录,建立连接时,告诉服务器这个socket是哪个userID的,凡是该用户建立连接,后台都把该连接绑定到user ID。
-
1、每次建立连接,connection的id是唯一的
-
2、服务器端维护一个【连接列表】:(string userID - > webSocket sockt),如下所示:
public class UserSocket
{/// <summary>/// 用户ID/// </summary>public string userID;/// <summary>/// socket对象/// </summary>public IWebSocketConnection socket;/// <summary>/// 状态:true-可用状态 false-断开状态/// </summary>public bool connected;
}
userID | socket | connected |
---|---|---|
guest | socket1 | true |
user1 | socket2 | true |
user2 | socket3 | false |
… | … | … |
userN | socketM | true |
客户端建立连接的时候,发送信息给服务器,告诉服务器该连接对应那个用户名。
服务器收到信息后,及时更新【连接列表】。
- 用户端在建立连接的时候,发送一个string命令,告诉服务器这个连接后面是哪个用户(user ID)
websocket.OnOpen += () =>
{Debug.Log("连接成功!!"); websocket.SendText($"name#user001"); //发送用户id
};
- 服务器收到信息的处理
//收到二进制信息
socket.OnBinary = bytes =>
{var userName = UserSockets.First(x => x.socket.ConnectionInfo.Id == socket.ConnectionInfo.Id).userID;Debug.WriteLine($"收到二进制数据,长度为{bytes.Length}Bytes,来自ip:{socket.ConnectionInfo.ClientIpAddress},userID ={userName}");
};
收到信息,且识别了是哪个userID发来的
6、本文测试环境
Win10 + Unity2021.3.18 + VS2019(.NET 5.0)
相关文章:

Unity使用webSocket与服务器通信(二)——C#服务器端使用Fleck时的简单服用方法
C#服务端用到Fleck包,它包含哪些可用的回调函数,有哪些常用的api方法? 演示:服务端收到Unity用户发来的信息 1、Fleck服务器提供哪些回调函数 Fleck提供的回调函数有下面几种: //用户连入服务器时... Action OnOp…...

【Linux】线程概念 | 线程控制
🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉知识补充&…...

pocsuite3安装及使用
pocsuite3安装及使用简介项目地址环境配置及安装环境要求安装(详情可以参考[https://pocsuite.org/](https://pocsuite.org/))使用方法运行模块加载目标参数:Console模式查看有哪些模块使用Telnet 弱密码模块这里以flask模板注入漏洞为例pocs…...

docker从安装到部署一个项目
一.centos安装docker 参考博客:https://blog.csdn.net/m0_47010003/article/details/127775185 1.设置一下下载Docker的镜像源 设置下载的镜像源为国内的阿里云,如果不设置,会默认去Docker的官方下载 yum-config-manager --add-repo http…...
QT编程从入门到精通之十二:“第四章:Qt程序创建基础”之“4.1 创建基础程序”
目录 第四章:Qt程序创建基础 4.1 创建基础程序 4.1.1 新建一个项目...

黑客入门教程【非常详细】从零基础入门到精通,看这一篇就够了!
首先要明白啊,我们现在说的黑客不是那种窃取别人信息、攻击别人系统的黑客,说的是调试和分析计算机安全系统的网络安全工程师。 黑客技术的核心就是渗透攻防技术,是为了证明网络防御按照预期计划正常运行而提供的一种机制。就是通过模拟恶意…...
手机怎么远程控制腾讯云云服务器?
手机怎么远程控制腾讯云云服务器?腾讯云提供的连接:Windows系统。可以用远程桌面连接,你本地电脑点击,开始-运行-输入mstsc,弹出的框里,填IP和账号密码信息。 管理服务器上还会运行一个数据采集程序&#…...

dorcker与vlu靶场搭建
dorcker与vlu靶场搭建 dorcker安装 以kali linux 为例 安装必要的一些系统工具 apt update apt -y install apt-transport-https ca-certificates curl software-properties-common 添加Docker PGP key curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg …...
Unity性能优化 - Overdraw篇
一、什么是Overdraw Unity Overdraw(超绘)是指在渲染过程中绘制了超过一次相同像素的现象。当多个UI元素重叠时,每个像素都需要被多次绘制。这种绘制超出了渲染所需的最小像素数,因此被称为Overdraw。 二、都有哪些元素会导致Ov…...
Tp5操作mysql json函数
Tp5操作mysql json函数 官方文档介绍正常单个json数据更新没什么问题,但是某些情况可能一次修改多个,但是也不想全部替换 怎么处理?注意 :在源码中 项目\thinkphp\library\think\db\builder.php@parseData方法中 修改控制器调用:官方文档介绍 JSON字段 从V5.1.4+版本开始…...

【蓝桥杯嵌入式】PWM的设置,原理图解析与代码实现(第十一届省赛为例)——STM32
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...

Learning C++ No.13【STL No.3】
引言: 北京时间:2023/3/7/15:33,还有27分钟就要去上课啦!刚刚把最近因为考试原因欠的课给还干净了,已经准备好今天晚上接受航哥的毒打了,毒打就毒打,咱不怕,只要不欠钱,…...
推荐收藏!10大程序员必备生产力工具
作为程序员,提高生产力是我们一直追求的目标。随着技术的发展,越来越多的工具和应用程序被开发出来,帮助程序员们更好地完成工作。在本文中,我将介绍一些程序员必备的生产力工具。 一、IDE(集成开发环境) …...

【项目总结】基于SSM+SpringBoot+Redis的个人博客系统项目总结
文章目录项目介绍(开发背景)数据库设计主要使用到的技术点前端后端自定义统一返回对象自定义拦截器加盐加密操作分页功能session持久化自定义头像的存储和获取项目编写过程中遇到的困难点困难点一(小)困难点二(小&…...
从入门到精通MongoDB数据库系列之一:MongoDB简介
从入门到精通MongoDB数据库系列之一:MongoDB简介 一、易于使用二、易于扩展三、功能丰富四、性能卓越五、设计理念MongoDB是功能强大、灵活且易于扩展的通用型数据库。融合了二级索引、范围查询、排序、聚合以及地理空间索引等诸多特性。 一、易于使用 MongoDB是面向文档的数…...

大数据系列——什么是hdfs?hdfs用来干什么的?
一、什么是HDFSHDFS全称是Hadoop Distributed File System是一种分布式文件系统(HDFS使用多台计算机存储文件,对外提供统一操作文件的接口)Hodoop使用HDFS(Hadoop Distributed File System)作为存储系统。二、hdfs用来干什么的用于大规模数据的分布式读写࿰…...

云端地球2月更新了这些功能,你都用过了吗?
时光飞逝、转眼已到2023年的第三个月,武汉的天气也逐渐转好,温度步步高升。云端地球产研团队的脚步也越走越快,虽然春节仿佛还是昨天的事,但云端地球已经完成了四次迭代,为广大建模爱好者带来了更多实用功能࿰…...

基于gin-vue-admin[gin+gorm]手动实现crud(全)
使用Gin-Vue- Admin框架手动实现crud 在gva框架下自己手动实现一个CRUD的操作,该操作将会结合gen进行探讨学习,具体实现可以看下面代码的实现,项目目录层级分为api层,service层,model层,common层ÿ…...

彻底关闭Windows10更新!!
以下四个步骤都需要执行。 一、禁用Windows Update服务 1、同时按下键盘 Win R,然后输入 services.msc ,点击确定。 2、找到 Windows Update 这一项,并双击打开。 3、双击打开它,点击 停止,把启动类型选为 禁用&…...

跨时钟域CDC
https://www.cnblogs.com/icparadigm/p/12794483.html https://www.cnblogs.com/icparadigm/p/12794422.html 亚稳态 是什么 时序逻辑在跳变时,由于异步信号、跨时钟域等原因,不满足setup或hold条件,输出在0和1之间产生振荡。 原因 D触发…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...