本文共 684 字,大约阅读时间需要 2 分钟。
整个底层通信模块修改过很多次,因为首次使用epoll,在其中遇见了很多问题,最终设计成下面的方式:
1: 对于epoll中EPOLLOUT事件的使用,因为频繁的调用send()函数,系统会在内核模式和用户模式之间切换太多消耗太大,所以最终启用了定时器模式,比如以50ms为间隔,定时的遍历所有的ClientPlayer 去发送 OutStream 里面的数据。
2: 最开始使用玩家的id 对应每个玩家的ClientPlayer的,在玩家没有进入的时候 使用玩家的账号名; 后来增加了一个map,用玩家id去映射对应的socket,在用socket 去映射对应的Clientplayer。
3: 对于epoll中的EPOLLOUT事件,因为启用的是边缘模式,所以在连接刚建立的时候会触发这个事件,但是如果在之后再想通过这个时间的触发去发送数据就不可能了。所以尽量还是不要使用EPOLLOUT事件去做发送处理。
4: 每个连接都有自己的缓存,当缓存慢的时候就做异常处理,将这个客户端断开。
5: 最先设计的时候,是做成了多进程,后来修改成了单进程多线程模式。可能疑问单进程会不会影响在线,本来场景内的玩家确实要处理走动逻辑,后来考虑到这是一个模拟经营类游戏,玩家可能不关系走动逻辑的一致性,所以就去掉了服务器走动逻辑的处理,交给了客户端处理。没有这个压力,服务器压力小很多。
6: 消息的接受和发送做在了一个线程里,不同类型的消息的处理坐在了不同的线程里。两者通过上篇讲到的消息队列进行通信。
7: 所有的底层API函数包括epoll相关,socket相关都做了一封装。
转载地址:http://sepox.baihongyu.com/