我们正在为一个现有的在线游戏构建一个新的客户端和一个缓存代理组件。当前设置如下所示:
Server
| \
TCP TCP
| \
Client1 Client2新的设置将是:
Server
| |
TCP TCP
\ \
Proxy <-- (New!)
| \
0MQ 0MQ
| \
Client1 Client2 <-- (New!)代理组件将靠近现有的游戏服务器,并对其使用基于旧线路的TCP协议,同时对新客户端使用基于Google protocol Buffers的新协议。除了在服务器及其客户端之间转发和转换消息之外,代理还将缓存(protobuf)发往客户端的消息。
服务器响应客户端请求,但也可以向特定客户端或所有客户端发送未经请求的消息。由于代理将维护发往某个客户端的消息缓存,因此它需要保持与每个客户端相关联的一些状态。
我已经在ZeroMQ指南中读了很多,但我仍然不确定它的哪种“模式”或套接字组合最适合这种设置。我希望有一些ZeroMQ精灵能给出一些建议,告诉我最好的方法是什么。
这个问题不是特定于语言的,但代理组件将使用Java语言编写,客户端将使用C#编写。
首先要感谢大家!
发布于 2013-01-17 01:59:58
我认为Asynchronous Client Server模式会让您更接近。您的每个客户端创建一个经销商套接字,该套接字连接到您代理中的路由器套接字。查看example Java source。您可以将代理建立在ServerTask类的基础上,使用前端/路由器套接字,省略后端/经销商套接字。
您的服务器将能够响应客户端请求,并将未经请求的消息发送回任何客户端。在客户端发送了至少一条消息之后,您将需要缓存每个客户端的套接字id。
你到游戏服务器的TCP连接在概念上类似于服务器和玩家之间的后端发牌套接字-但是,因为你的连接是传统的TCP而不是ZeroMQ,所以你不能使用ZeroMQ套接字,需要做一些自定义的事情。当您与传统的TCP套接字集成时,您的自定义解决方案要求您不违反ZeroMQ的并发规则。
这里有一种方法--使用一组成对套接字(让我们称它们为A和B)和一个BlockingQueue来充当ZeroMQ和您的TCP套接字之间的桥梁。并创建3个线程- TCPRead,TCPWrite和ZeroMQ。
TCPRead从游戏服务器的TCP连接中读取。它将它们转换为protobuf消息,并通过A套接字转发它们。
TCPWrite轮询BlockingQueue以查找消息。当它接收到消息时,它会对其进行转换,并通过TCP连接将其发送到游戏服务器。
最后,大部分工作都在ZeroMQ线程中完成。它使用ZeroMQ轮询,并不断轮询其路由器套接字(针对来自所有客户端的所有消息)和B套接字(针对来自游戏服务器的消息)。向客户端发送消息很简单,可以通过将消息发送到路由器套接字来处理,并在消息前加上客户端的套接字id。向服务器发送消息是通过向BlockingQueue添加消息来完成的。它将被TCPWrite接收并转发到游戏服务器。
一旦你得到了这个基本的设计,你就可以疯狂地添加工人等等,就像各种模式中描述的那样。
希望这能有所帮助。
发布于 2013-01-17 05:54:06
您还可以在raw模式下使用0MQ路由器套接字,这意味着您可以编写具有两个路由器套接字的代理。我会避免使用配对套接字,除非是父子线程管道。
发布于 2014-07-05 22:35:56
浏览ZeroMQ文档需要一段时间,尽管它非常出色。我这样做了,并得出结论,异步客户端-服务器接近于我最初想要的。
但这并不完全是。因此,我开始着手构建。
我真正想要的是基于我从各种例子中学到的东西。我最终得到的完整描述是用here编写的,代码可能会有一些用处,供参考或作为实际的库使用。
https://stackoverflow.com/questions/14362812
复制相似问题