谈谈游戏服务器的发送数据处理

简介:

发送数据处理模式的概念:

 相信每一个第一次写游戏服务器的人都会在发送数据处理这里卡主,因为相对于简单易处理的接收消息处理,发送消息的时机和驱动更加难以把握。为什么呢?我们看下套接字可读的条件:

 1: 该套接字接收缓冲区中的数据字节数大于接收低水位标记

 2: 该连接的读关闭

 3: 该套接字是一个监听套接字,并且有新的连接

 4: 该套接字上有错误处理

以上所有的条件,都可以通过注册事件来完成,并且因为都是被动触发,所以处理起来比较轻松。

那我们看看套接字可写的条件:

 1: 该套接字发送缓冲区中可用空间大于发送高水位标记

 2: 该套接字的写关闭

 3: 该套接字上有错误处理

看到套接字可写的条件我们为难了,因为我们需要发送的时候,套接字并不一定可写;而套接字可写的时候,我们未必有数据要发送,这就造成了事件的浪费,也就造成了发送数据比接收数据更难。

 

前言: 我们在这里是将网络数据的发送和接收放在单独的线程里面处理,称之为网络IO线程;而在其他的线程总处理玩家逻辑,称之为玩家逻辑线程。

 

解决方案1: 定时发送。

定时发送算是一个比较通用的处理,也是用起来比较方便的方式。对于每一个来自客户端的连接,我们只是注册可读事件,而不会注册可写事件,对于发送处理,我们采用定时器触发的模式,比如每一个连接上绑定一个30ms的定时器,每次定时器触发的时候,也就是写饥饿的时候,对每个连接都去做一次试图发送的处理。

当大家看到思路的时候,我想麻烦也就跟着来了。因为是30ms的定时器,所以每条消息的延迟都是N*30ms;可能很多的套接字并没有数据要发送,但是定时器到了,造成了很多浪费;因为定时器的触发也是轮训的模式,大家不是都说“轮训就是强奸吗”。

 

解决方案2: 按需注册write事件

 如果我们真正了解write事件,就应该按需注册write事件。每次发送玩家数据的时候,如果只发送了部分数据,则把剩余的数据存放到自定义缓冲区,并且注册write写事件;这个事件会在下一次select的时候触发,触发的时候发送剩余的数据,如果发送完毕,就关闭write事件。

 这里我们分开网络io线程和游戏逻辑线程,如果是网络io线程内部发送数据,那么很简单,只需要调用提供send函数就可以了。如果是游戏逻辑线程里发送数据,就会稍微麻烦一点。为了保证线程的安全性以及数据的完整性,在游戏逻辑线程里面调用发送数据的接口,实际的工作是在网络线程里面完成。简单来说就是将这个函数或者task,投递到网络io线程里面去执行。

我们可以参考下muduo的做法,如果是在非网络io线程里面发送数据,就将要发送的套接字和数据封装成Functor,投递到网络io线程中去,并且唤醒网络IO线程,去处理这些需要执行的Functors(std::vector<Functor>)。

我在修改自己的网络发送模式的时候,也是这个思路,不过是用的是java为多线程提供的FutureTask,如果是在非网络io线程中发送数据,就将需要发送的连接和数据封装成FutureTask,投递到网络Io线程中去,唤醒io线程,处理需要执行的FutureTasks(Vector<FutureTask>)。

好吧,最后还是承认,其实在设计的时候,参考了一下mina的设计,不过看到muduo网络库居然和mina 的设计如此类似,相比muduo的设计也是参考了mina的设计。

 

可能很多人认为方案2的方案,会增加系统调用。因为我们不是总说要减少系统调用吗。这也是定时器发送数据模式的依据,可是我们的tcp已经提供了negle算法,大部分send的函数,只是将数据写入到缓冲区,并没有那么大的消耗。大家可以测试看下!

相关文章
|
10月前
|
存储 Nacos 微服务
【项目实战典型案例】23.部分服务总是频繁出现掉线情况
【项目实战典型案例】23.部分服务总是频繁出现掉线情况
|
8天前
|
存储 缓存 数据安全/隐私保护
说一说你对移动应用中的离线模式的实现。
【4月更文挑战第2天】移动应用的离线模式允许用户在无网情况下仍能部分使用应用,依赖于数据缓存和本地存储。应用在联网时缓存关键数据,离线时从本地读取。数据同步通过延迟策略在重连时完成,敏感信息加密存储并定期备份。开发者还需关注用户体验、性能优化及错误处理,确保离线模式的无缝衔接和稳定性。
24 1
|
8天前
|
缓存 监控 负载均衡
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据缓存不一致分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(数据缓存不一致分析)
42 2
|
8天前
|
数据采集 Web App开发 文字识别
高并发数据采集:Ebay商家信息多进程爬虫的进阶实践
高并发数据采集:Ebay商家信息多进程爬虫的进阶实践
|
存储 缓存 算法
【优化技术专题】「线程间的高性能消息框架」再次细节领略Disruptor的底层原理和优势分析
【优化技术专题】「线程间的高性能消息框架」再次细节领略Disruptor的底层原理和优势分析
180 0
【优化技术专题】「线程间的高性能消息框架」再次细节领略Disruptor的底层原理和优势分析
|
存储 消息中间件 编解码
[自己做个游戏服务器二] 游戏服务器的基石-Netty全解析,有例子,多图解释
Netty的大名我想做java 的基本都知道,因为他实在太出名了,现在很多著名的软件都是使用netty作为通讯基础,今天就聊聊Netty,希望能讲清楚,如果懒得看理论,可以直接拉到后面看Hello world。把代码抄下来,运行一下看看。
268 0
[自己做个游戏服务器二] 游戏服务器的基石-Netty全解析,有例子,多图解释
|
存储 弹性计算 缓存
直播代码是如何工作的,不同服务器之间的区别
简单来说直播的原理就是把主播录好的内容实时推送到服务器,再由服务器分发给各个用户进行观看。直播发展到如今,由PC端的网页版直播到如今的移动端直播,越来越多直播功能的APP上线,直播的服务器分为很多种类,那么不同的服务器之间有哪些差异呢?本文来为大家简单介绍一下。 服务器在网络中为其它客户机提供计算或者应用服务。服务器具有高速的CPU运算能力、长时间的可靠运行、强大的I/O外部数据吞吐能力以及更好的扩展性。
直播代码是如何工作的,不同服务器之间的区别
|
自动驾驶 物联网 5G
5G 时代的应用场景 | 带你读《5G时代的承载网》之八
下面我们来展望,在“互联网 +”以及 5G 时代,移动通信将在哪些行业出 现新的应用,以及具体的应用方式。

热门文章

最新文章