游戏开发论坛

 找回密码
 立即注册
搜索
楼主: sjinny

我写的网络模块,大家来看看,不用也来讨论讨论……

[复制链接]

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2009-5-29 16:06:00 | 显示全部楼层

Re:我写的网络模块,大家来看看,不用也来讨论讨论……

思路想法不同而已。我做的只是在“一个系统由多台机器上的多个进程组成一个进程网络对外提供服务。这个进程网络是一个以netgate进程为顶点、功能进程或管线为边的有向图。”基础上更进一步,再把netgate以一个svrcenter为顶点组成一张网,当然,为了效率考虑,netgate间以类似P2P方式各自连接。

可能开发习惯的不同吧,RPC我习惯于 service obj 级 event 调用(有点像web service),就写成那样了,一般用于通用服务模块(帐号、地图管理等),而对于长连接及时通信(如地图服务),采用非RPC模型,而是group管理的网络镜像对象通信模型。 RPC类调用应用是存在于适合它的场合,滥用就是自己找抽,就像设计模式是好东西,但是为了模式而模式就是大大的不该。

我只是觉得,有那么多现成的库,而且功能强大。对于网络模块实在是已经很成熟了,对于有一定技术实力的公司来说,怕是早就有内部使用的固定模块了,不会重新找个新的。而对于不具备完整技术实力的公司,往往选用有口碑且经过商业运用检验过的模块或自己重头写...

其实讨论了那么多,你不是也逐步对自己netgate有了后续想法么,加油做,等到你想做的东西逐步完善,会发现最后已经不是当初设想那么简单了,我也走过一样的路,开始想的很好,但经过将近3年的开发,几千行代码变成了十几万行,也成了我前面所说的框架(苦笑下...)....也希望能看到你做出更好更新的东西,加油吧,不要停止,开头不难,难在持续下去

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2009-5-29 19:11:00 | 显示全部楼层

Re:我写的网络模块,大家来看看,不用也来讨论讨论……

“以一个svrcenter为顶点组成一张网”
这个不太明白,是组织进程网络的一种策略?这个倾向于完全外置,也就是说不在底层提供针对性的支持。通信机制和进程网络的组织策略尽量分开。

我对你RPC使用方式的理解,就是披着RPC外衣的消息发送;)
“group管理的网络镜像对象通信模型”这个就看不明白了。

就现成的库来说,我还没有看到现在netgate这种使用方式的。对我来说,如果已经有现成的可用,我绝对不会再去自己做的。你觉得有哪些库是和netgate的使用方式差不多的呢?

“开始想的很好,但经过将近3年的开发,几千行代码变成了十几万行,也成了我前面所说的框架”
这个就是我从一开始就想极力避免的。我做网络模块,一开始是框架,后来慢慢地才越来越小,最后变成现在这样一个相对独立的小工具。我现在对于那种把需求往框架里塞的做法很不喜欢,对小程序+胶水的方法比较有爱,呵呵。

其实netgate的核心功能特性已经差不多了,开发现在也已经基本停止了,目前在玩blender内置的游戏引擎,也算调剂一下吧。

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2009-5-29 23:05:00 | 显示全部楼层

Re:我写的网络模块,大家来看看,不用也来讨论讨论……

打个比方,netgate兼dns镜像服务和路由,svrcenter是根节点,负责netgate信息汇总以及dns的注册。

RPC的核心在于Remote Procedure,首先它是远程的,这个不必多说。其次,它是一个Procedure,且过程可简可繁,甚至服务层可能由多个服务模块配合完成后才给调用方返回,如前面提到的帐号验证,很可能其过程为“调用方->帐号中心->第三方帐号接口->帐号中心->调用方”,对于调用方,不必知道其中所经历的第三方帐号接口细节(甚至可能其间还需要访问多个远程接口),这是一种网络化的模块封装,可以类比一下数据库的存储过程。

group那个,就看做实现到类似聊天室一层好了,提供进入group内客户端的组播、单播、区域同步,某客户端进入、离开时的处理以及相应向其他客户端的消息推送。

好像我知道的,很多公司都把把gate说成最基本一个网络模块而已,大多都实现了自己的gate,只是都没有对外公布而已(好像服务端系统架构没有哪家公司对外开放的),自己实现一个gate应该只是第一步,还应该研究配合自己gate的特性,实现自己的服务器架构。

其实说到最后,还是前面所提到的,这些是一套系统和一个组件模块的关系,不好放在一起比较,也没有可比性。实际开发中往往无法做到完全按照自己设想去做,需要考虑各种各样的“历史遗留问题”以及合作方接口问题,经过实际项目的洗礼后才会变得更加成熟。(比如我自己实现过一个string,实现初期目的很可笑,公司原代码库是多字符集、单线程,而一个合作方提供的库是unicode并使用了多线程,为了粘合2个模块,才写了那个string...)

个人以为,术业有专攻,真对服务器端有兴趣,就因该深化研究到服务器架构,而不单单是技术细节

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2009-5-30 02:04:00 | 显示全部楼层

Re:我写的网络模块,大家来看看,不用也来讨论讨论……

我做netgate的意图很单纯,就是做一个“进程粘合剂”,作为实践多进程编程的基础。

“服务层可能由多个服务模块配合完成后才给调用方返回”
这个其实和是否使用RPC的关系应该不大了,RPC更多的是连接两段的接口形式,即使是使用消息发送的形式,一样可能是一个消息发过去,对面再由此向其他机器发送更多消息,经过一连串的处理后才产生给源机器的响应,这个过程也是透明的,和端点是否采用RPC的形式无关。

其实我现在感兴趣的是,无论是公开的库也好,不公开的内部库也好,有多少是做成独立进程形式、功能进程使用标准输入输出通信并使用shell进行胶合的,以及大家对这种方式的接受度有多少。


就netgate上面的结构,这个可能和具体应用的关系更加紧密了。即使没有历史遗留问题,要做一套通用的机制估计也还是很困难。不过我觉得在合适工具的帮助下,只要能确保每个程序都小巧简单,那就容易适应各种需求,netgate就是为把程序写小所提供的工具。


其实我在自己开始写网络模块之前就开始“研究”“架构”,而后来则更多的在尝试真正把细节实现出来。现在看来,“架构”很容易做得过度设计,因为涉及架构时往往会为了尚不存在或尚不明确的需求而做设计。所以我就不怎么热衷于“架构”了。

15

主题

368

帖子

406

积分

中级会员

Rank: 3Rank: 3

积分
406
发表于 2009-6-2 00:21:00 | 显示全部楼层

Re: Re:我写的网络模块,大家来看看,不用也来讨论讨论

sjinny: Re:我写的网络模块,大家来看看,不用也来讨论讨论……

ls的逻辑很强大……你是在暗示“即使现在想不到有什么问题,实际使用中也一定会有严重的问题”吗?

既然...


呵呵,不要激动。
首先,我所说的是基于“实用价值”考虑而非去否定这样一种方案的纯技术上的可行性。

其次是 “即使现在想不到有什么问题,实际使用中也一定会有严重的问题” 这个说法不正确。并不是我想不出有什么问题,而是我本来打算只举出一例获取socket的连接状态的问题来说明。最本质的是应用层和网络层基本上是完全隔离的,而实际上应用层和网络层是不太可能完全隔离。这么做明显也属于设计过度了。

那我再举出其他几个例子吧:逻辑层处理不过来,网络数据收得太多了,正常情况下逻辑层应该控制要求停止网络接收,等处理完后再继续接收的,这个时候怎么办?(但有些情况又需要网络层继续接收并抛弃这些数据包)对于连接的IP有安全策略限制或是某种状态下不希望某个IP连接上来,传统的方式是逻辑层要处理就是网络模块提供OnAccept回调里进行判断是否允许连接,但使用插件后这种情况就会变得复杂。特别是如果你的网络模块与应用层通讯是异步而非阻塞的话,这会导致逻辑处理起来相当麻烦。

你的这套方案从理论上是可行的,但是从实用性上来看,不如传统的提供库编译到同一进程中控制来得方便直接。所以我说如果真用它来做项目,可能会花比较大的力气,属于“事倍功半”性质。


其实我很好奇你为什么要这么做,传统的做法有什么问题呢?你这么做带来的全新方式所带来的正面影响是否大于负面影响?(当然,我指的是将它使用在一个网络游戏项目的开发中,我承认你的这个东西写个demo,像echoserver这种确实蛮简单的)

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
 楼主| 发表于 2009-6-2 15:26:00 | 显示全部楼层

Re:我写的网络模块,大家来看看,不用也来讨论讨论……

恩,如果是逻辑层需要获取socket的连接状态,那我是这么理解的:当建立链接或某链接断开时需要通知逻辑层,这个目前是完全可以做到的,因为这些事件是会通知给插件的,插件可以选择合适的协议通知逻辑层。除了这两个事件,逻辑层还需要知道什么呢?

“逻辑层处理不过来,网络数据收得太多了,正常情况下逻辑层应该控制要求停止网络接收,等处理完后再继续接收的,这个时候怎么办?”
这时是这样的,如果逻辑进程处理速度跟不上,那么pipe就会填满,这时netgate就会发现通往逻辑进程的pipe不可写,这时会把数据缓存在netgate里。
“但有些情况又需要网络层继续接收并抛弃这些数据包”
这个我怀疑几乎不可能,因为网络层不可能知道别人发过来的数据哪些是重要的不可丢弃的、哪些是不重要的可以丢弃,如果网络层知道,那么很可能网络层与逻辑层耦合过紧了。不过如果实在需要这个,也不是不可以,无非是插件需要知道通往逻辑进程的pipe是否被发生拥塞以及什么样的数据是可以丢弃的,这个丢弃的工作可以在插件里做。当然,如果你说要由逻辑层通知网络层那也可以,因为插件是可以获取所有网络数据的,无非就是逻辑进程向netgate里的插件发消息。

“对于连接的IP有安全策略限制或是某种状态下不希望某个IP连接上来,传统的方式是逻辑层要处理就是网络模块提供OnAccept回调里进行判断是否允许连接,但使用插件后这种情况就会变得复杂。”
如果希望实现拒绝某些连接,那么可以在插件里做,最直接的做法就是让插件读取一个配置文件,然后在发生accept后进行处理。这和传统方法的区别仅仅是:IP过滤和具体的逻辑功能是否在一个进程里做。除此之外,插件也是“网络模块提供OnAccept回调里进行判断是否允许连接”,没什么区别。

你所说的“问题”都不存在,因为发生任何网络事件时插件都会得到通知(accept一个连接、某个连接有数据到达、某个连接被迫断开),对插件来说,网络的各种状态信息是完整的,插件对网络连接所能做的操作也是完整的(建立连接、断开连接、收发数据、建立监听用的socket)。
也许我之前没有把netgate的细节讲清楚,但是你在不很了解netgate的情况下是怎样得出种种结论的呢?你可以提问说这种情况netgate是否可以处理,但有根据直接下结论说不可以吗?有必要直接下结论吗?

传统做法的问题就是,使用者必须包含额外的头文件、连接额外的库、调用额外的API甚至针对网络模块设计自己的主循环。netgate的目的就是进一步减少网络层与上层的耦合,提高网络通信对上层的透明度。我从来不曾承诺过netgate包治百病,其实我也强调过netgate的目的是单纯的,设计原则之一就是能不在netgate里做的就不在netgate里做。


如果ls怀疑某种情况netgate不能处理好,那么完全可以提出来,但是请在了解netgate之前不要下结论。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 04:36

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表