关于联网交互

news/2024/10/23 11:23:59

进程间的通讯经常需要走网络。网络的交互方式有很多,最基础的就是Socket,.NET平台还封装了TcpListener和TcpClient,跟Socket相差不大,属于简单封装。
另外我们公司常用的交互方式还有ZeroMQ和RabbitMQ。
其实C++那边用ZeroMQ比较多。C++开发经常也开前后台,有人负责前台的界面部分,可能会使用MFC或QT,然后另外有人负责后台的业务代码。C++的前后端交互有时候经常也直接使用ZeroMQ,一些状态和配置的东西,有时候也会借助Redis数据库。
ZeroMQ他们使用最多的还是发布/订阅模式。
C#这边,ZeroMQ的实现对应是NetMQ,一些常用的模式都有。
但在之前的项目使用中,发些一些问题:
1、请求/响应模式,其实相当的脆弱,请求端和响应端的收发必须保持严格的一致,中间如果出现任意一个请求端的操作不正确,会导致响应端的线程也崩掉,导致服务也会不正常。
这点上个人感觉还是不太能接触。其实类似的TCP的监听和HTTP的监听,某一个终端交互的异常,可能会导致和这一路的终端交互会异常或中断,但一般都不会影响其它终端的交互和监听响应端的后绫正常工作。
所以强烈建议不要使用这个请求/响应模式,这个问题,我不是知道是NetMQ的问题,还是所有的ZeroMQ都会有这个问题。
2、NetMQ的发布/订阅,底层的实现一般都还是一个个TCP Socket,当然还可以设置其它的连接方式。
这种方式会有什么问题呢?相当于一个终端的订阅就是一个Socket连接,这种方式其实并不适合大批量大流量的订阅发布。
之前我们有个项目,拿发布/订阅模式去分发文件。服务端用的是千兆网卡。连了30台机器,其实每个终端分到的有效带宽是3MB/S。
发布端往消息队列里面放文件数据的时候,只要超过3MB/S,相当于整个的带宽已经不足够把数据发出去了。
这样的NetMQ底层的队列就会积压缓存,过一段时间,队列就会满出来。队列满出来以后,NetMQ就会去丢掉一些数据包。类似一些大文件,丢掉一些包,就会导致这个文件传送就失败了。
所以当时在遇到很多终端连着,并且传送大文件的时候,是有问题的。
连接的终端比较少,或者传送小文件的时候是没有问题的。连接的终端少时,每个终端分到的带宽就比较多,传输数据就比较快,就不容易出现堆积的情况。传送小文件的时候,因为本身持续的时间比较短,消息队列的缓存还没满,整个发送过程就结束了。
因为当时已经是在项目后期,我们没办法重新更换网络传输架构,所以我们当时的解决方式是,发布端控制一下往队列里面放数据的速度,比如我们就按3MB/S的速度往队列里面放,达到这个速率了以后,我们就暂停。
因为我们主要用来传输一些文档类的小文件,所以这样限制其实问题不大。
但这样的限制,在连接的终端比较少的情况下,其实是比较浪费的。相当于千兆的网络,如果就连了两台的机子,也限制了3MB/S的速度,其实就是在浪费带宽。所以其实还需要根据连接的终端情况来调整带宽,所以相对就比较复杂。
所以后面的时间,我其实也有一直在研究这个文件大批量分开发的问题。个人感觉比较好的理念,其实是P2P的方式,当然也可以使用组播这些方式。但是我做的那个项目里面,有种情况,有些终端可能会后续连进来的,所以想完全靠组播来一劳永逸的解决也比较难。
所以当时的想法就是想着,不要把流量全部集中在服务端。大文件的话可以采用分块的方式,一般终端已经下载了,没下的终端可以从已经下载的终端来获取。
一种解决方案是借助IPFS。这种方式需要在服务器和每个终端上先安装一个IPFS的服务。然后借助IpfsShipyard.Ipfs.Http.Client,调用IPFS的服务来实现。

Install-Package IpfsShipyard.Ipfs.Http.Client
  • https://github.com/ipfs-shipyard/net-ipfs-http-client

示例代码:

using Ipfs.Http;var ipfs = new IpfsClient();const string filename = "QmXarR6rgkQ2fDSHjSY5nM2kuCXKYGViky5nohtwgF65Ec/about";
string text = await ipfs.FileSystem.ReadAllTextAsync(filename);

还有一种方式,就是完全自己实现,自己切块,每个终端都去监听连接。自己去控制去哪里获取分块。
分块采HASH值标识和保存。

SOCKET的使用

很多同事都不喜欢直接使用SOCKET,主要是觉得状态的维护比较麻烦。包括C++那边,平常喜欢用ZeroMQ,主要也还是觉得它不用维护终端和连接状态。
但是个人的话,不排诉Socket,有时候甚至喜欢用Socket,主要也是因为状态的连接和可控。
用了第三方封装的通讯库,有个很大的问题,一些基础的信息和连接状态,有时候反而变得比较难感知。
关于Socket的使用,最近也有一些想法。
个人感觉其实不同的操作,可以用不同的通道来处理。
类似有些操作,其实比较像请求响应,其实可以使用单次连接的方式,连上去,发消息,然后收消息,收完以后就把连接给关闭了。
还有一些有点像发布订阅的方式,连上去,告诉服务端,我要什么东西,然后服务端按要求持续的发送数据。
另外还有一些情况,采集的间隔可变的,客户端发一个采集的请求,服务端就回一帧的。什么时候停止也是客户端自己决定的。其实也可以起一个专门的线程和连接去完成这部分的操作。
我个人的理解,其实分线程分连接去完成上面三部分的工作。可以不要用同一个Socket连接,这样的话,逻辑相对会比较简单。

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

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

相关文章

nacos 下载与启动

1.情景展示 Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、…

浅析RocketMQ

SpringBoot引入RocketMQ 快速构建单机RocketMQ https://www.haveyb.com/article/3079 参考这篇文章,快速构建单机RocketMQ 项目引入jar包和配置<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</art…

STAR: A Simple Training-free Approach for Recommendations using Large Language Models

目录概符号说明STARRetrievalRanking最后的结果Lee D., Kraft A., Jin L., Mehta N., Xu T., Hong L., Chi E. H. and Yi X. STAR: A simple training-free approach for recommendations using large language models. 2024.概 本文提出了一种融合语义/协同/时序信息的方法, 使…

最近做题小结

https://www.luogu.com.cn/problem/AT_abc373_e这道题是个二分 然后标答是两个二分 我用的树组+二分 需要对代数式进行拆分才能得到 我一开始看错题目了 看成大于等于他的票的人不多于M就行 然后就很简单 我觉得可以改编下这个题 很明显 最终前m个人一定当选 那么对于每一个人 …

前端ai工具v0使用配置

资料 ai工具Vo Installation - Tailwind CSS 以vue3 + sass为例,配置如下 安装tailwindcss npm install -D tailwindcss npx tailwindcss init安装依赖(可选) npm install lucide-vue-next更新 tailwind.config.js /** @type {import(tailwindcss).Config} */ module.export…

ERP开源项目Odoo

Odoo Odoo 的全称是 On Demand Open Object。名称反映了 Odoo 的起源和核心理念: •On Demand:代表 Odoo 作为一个按需使用的系统,可以根据企业的需要定制和部署各种模块。 •Open Object:强调 Odoo 是一个开源项目,允许用户访问和修改其源代码,以便根据具体业务需求进行…