Project darkstar
Project darkstar 或者又称 sun game server (简称sgs) 是sun为大型多用户在线游戏(mmo) 和虚拟社区应用而开发的一套软件基础架构.目的是为了简化此类应用程序的开发,具体的介绍可见:Project darkstar faq. 这里有一篇中文的详细介绍
Darkmud
Darkmud 是sun在javaone大会上为了演示sgs 而开发的一个 文字型mud 游戏.在darkmud 的主页上没有release 的下载链接,需要直接从svn checkout 它的代码.checkout 出来的代码包含了服务器端的mud 游戏实现和一个简单的swing 客户端.这是swing client 运行时的截图:
Sgs server 通信模型
Sgs 和客户端之间的通信是在tcp协议之上通过直接传输字节流来完成,例如从client 向server 传输数据就是: SimpleClient.send(ByteBuffer buf); 客户端和服务器端的通信协议是公开的,所以各种语言,只要支持socket 的tcp通信,都可以连接到 sgs 上,官方目前支持java和c的客户端api,但已经有一些第三方开发的客户端api出现,例如在flash/as3 平台就可以使用这个. 客户端和服务器端接收对方的数据都是事件驱动的,发送数据时,发送完方法就返回了,并不等待对方回应,而是在接收到对方的数据时产生一个事件,让应用程序有机会处理.
Sgs proxy 解决什么问题?
sgs允许任何支持tcp通信的客户端都能连接上,但有一个问题: 浏览器访问不了,现在的浏览器支持XmlHttpRequest,在浏览器上不刷新页面的前提下可以使用http协议和服务器交换数据,但不支持tcp,而现在web game 发展很快,有没有可能让浏览器上基于javascript 的程序能够和sgs 通信,享受sgs 的强大功能呢?这就是这个项目开发的初衷.
Sgs proxy 的基本思路是在web server创建一个代理,每个浏览器客户端和代理交互,代理再和sgs server 交互.sgs proxy 负责所有的连接创建,销毁,管理,调用等工作,应用程序只需要设计通过tcp连接sgs server的协议,浏览器和web server之间的协议,然后实现并注册一个转换接口,在浏览器中就能够象拥有tcp连接一样,连接到sgs server上.下面是这个系统的结构图:
如图,sgs proxy 作为一个web app 运行在java web server 上(例如tomcat),每个浏览器可以通过sgs proxy 连接到 sgs server 服务器组中的任何一个节点,在连接之后,sgs proxy 负责管理连接,后续的通信都通过同一个tcp连接进行,直到连接断开(客户端主动logout,或者服务器将客户端踢出).在sgs proxy 这一层,只负责创建和管理到sgs server 的连接,其它所有的应用程序状态都存储在sgs server上.所以sgs proxy 这一层可以根据需要,动态添加新的web server.其它支持tcp通信的平台则直接通过tcp连接到sgs server 服务器组的节点.
Sgs proxy 通信模型:
由于与 sgs server 的通信本质上是异步的事件驱动的通信,所以在sgs proxy 上,为每个浏览器客户端创建了事件队列,当有事件到达,并且目前浏览器客户端没有连接到web server时,就将事件缓存到队列中,浏览器客户端定时执行轮询,在每一次轮询中,sgs proxy 负责将所有的事件对象转换为浏览器能够理解的格式,并返回.另外考虑到浏览器和web server通信模型是请求/响应方式,所以sgs proxy 实现了对这种通信方式的支持,在每次浏览器请求sgs proxy时,都附带一个标志,表示当前的请求是否为同步请求,如果是同步请求,则当前的请求消息发送到sgs server 后,并不立即返回,而是等待sgs server返回一个事件(实际应用中,sgs proxy 和sgs server 应该是部署在同一个局域网中,所以sgs proxy 和sgs server之间通信应该不会有较大的延迟),直到sgs proxy 返回一个事件后,sgs proxy 将此事件立即传递给当前正在等待的浏览器客户端,不再放到事件队列中.对于应用协议被设计成为请求/响应方式的应用程序来说,使用这一特性在浏览器端可以获得更好的效果.相反,如果是异步请求,消息发送到sgs server 后,浏览器就立即返回了,所有的事件处理放到了下一次轮询中进行.缺省的轮询间隔为5秒,此参数可调,也可以程序主动执行轮询操作.轮询间隔长一些,有助于减轻web server的负担,但浏览器端的实时通信效果就下降,反之可以让浏览器更像实时的连接和通信,但增加了web server 的负担.
目前在jetty和tomcat中虽然有对 comet 的一定程度的支持,但使用的都是私有的技术,考虑到兼容性的问题,所以未使用comet实现,而使用了轮询作为模拟持久连接的手段,由于每次轮询操作都是处理内存中的事件队列,并且传输的都是少量的json数据,所以每次轮询的开销并不是很大.
在servlet3.0的规范中提到了对comet的支持,所以在servlet3.0实现之后,会考虑增加comet的通信方式.
目前实现功能
目前sgs proxy 基本上实现了sgs server 的所有操作和事件类型包括:
支持的操作包括:
l 登录
l 登出
l 向server 发送消息
l 向channel 发送消息
l 轮询操作(这是sgs proxy为了模拟实时的消息获取而设计的,非sgs server 的操作)
支持的事件类型包括:
l 登录成功
l 登录失败
l 连接断开
l 加入channel
l 退出channel
l 接收到服务器消息
l 接收到Channel 消息
数据格式:
浏览器和web server 之间通过json格式传递数据,应用程序的数据通过一个javascript 对象数组的形式构造,传递到web server 后,此对象数组被映射成为一个List<Map>类型的对象. 具体的数据项由应用程序负责,应用程序需要实现一个对象到字节流(ByteBuffer) 转换的接口,sgs proxy 和sgs server之间的通信使用了sgs server 定义的标准方式—ByteBuffer,对于从 sgs server 接收到的消息,应用程序需要实现一个ByteBuffer 到应用程序对象的转换接口,最后对象被转换为javascript 的对象数组返回给浏览器.
如何开始:
Sgs proxy包含了一个浏览器版本的 darkmud 客户端,用以验证各项功能,以下地址下载darkmud服务器,darkmud swing client,以及sgs proxy, 运行darkmud 服务器后,同时用swing client 和sgs proxy 中包括的浏览器客户端连接到darkmud,观看效果.具体的使用说明可以查阅下载包中的readme 文档.
下载地址:
darkmud
darkmud swing client
darkmud web client
这是浏览器连接上darkmud之后的截图:
之后可以从 svn 中checkout 代码,实际使用
本项目以lgpl的协议发布.
如果有什么问题和建议,可以联系:
袁云昌
qq: 517655261