【问题标题】:ZeroMQ pattern for a (legacy) TCP to ZeroMQ proxy(旧版)TCP 到 ZeroMQ 代理的 ZeroMQ 模式
【发布时间】:2013-01-16 16:15:35
【问题描述】:

我们正在为现有的在线游戏构建一个新客户端以及一个缓存代理组件。当前设置如下:

  Server
  |     \
 TCP    TCP
  |       \
Client1  Client2

新设置将是:

 Server
 |   |
TCP TCP
  \   \
   Proxy          <-- (New!)
   |    \
  0MQ   0MQ
   |      \
Client1  Client2  <-- (New!)

代理组件将靠近现有游戏服务器,并与旧的基于线路的 TCP 协议对话,同时通过 0MQ 与新的客户端对话基于 Google Protocol Buffers 的新协议。除了在服务器与其客户端之间转发和翻译消息外,代理还将缓存(protobuf)发往客户端的消息。

服务器响应客户端请求,但也可能向特定客户端或所有客户端发送未经请求的消息。由于代理将维护发往某个客户端的消息缓存,因此它需要保持与每个客户端相关联的某些状态。

我已经阅读了很多关于 ZeroMQ 指南的内容,但我仍然不确定它的哪个“模式”或套接字组合最适合这种设置。我希望那里有一些 ZeroMQ 向导,可以就这里的最佳方式提供一些建议。

问题与语言无关,但代理组件将用 Java 编写,客户端用 C# 编写。

提前非常感谢!

【问题讨论】:

    标签: java zeromq


    【解决方案1】:

    我认为Asynchronous Client Server 模式会让你更接近。您的每个客户端都会创建一个 DEALER 套接字,该套接字连接到您代理中的 ROUTER 套接字。查看example Java source。您可以将代理基于 ServerTask 类,使用前端/ROUTER 套接字并省略后端/经销商套接字。

    您的服务器将能够响应客户端请求并将未经请求的消息发送回任何客户端。在客户端至少发送一条消息后,您需要缓存每个客户端的套接字 id。

    您到游戏服务器的 TCP 连接在概念上类似于服务器和工作人员之间的后端 DEALER 套接字 - 但是,由于您的连接是经典 TCP 而不是 ZeroMQ,因此您不能使用 ZeroMQ 套接字并且需要做一些自定义的事情。当您与经典 TCP 套接字集成时,您的自定义解决方案要求您不违反 ZeroMQ 的并发规则。

    这是一种方法 - 使用一组 PAIR 套接字(我们称它们为 A 和 B)和 BlockingQueue 充当 ZeroMQ 和 TCP 套接字之间的桥梁。并创建 3 个线程 - TCPRead、TCPWrite 和 ZeroMQ。

    TCPRead 从 TCP 连接读取游戏服务器。它将它们转换为 protobuf 消息并通过 A 套接字转发。

    TCPWrite 轮询 BlockingQueue 中的消息。当它收到一条消息时,它会将其转换并通过 TCP 连接发送到游戏服务器。

    最后,大部分工作都在 ZeroMQ 线程中。它使用 ZeroMQ 轮询并不断轮询它的路由器套接字(用于来自所有客户端的所有消息)和 B 套接字(用于来自游戏服务器的消息)。向客户端发送消息很简单,通过将消息发送到路由器套接字来处理,并在消息前面加上客户端的套接字 id。通过将消息添加到 BlockingQueue 来完成向服务器发送消息。它将被 TCPWrite 提取并转发到游戏服务器。

    一旦你完成了这个基本设计,你就可以按照各种模式中的描述疯狂并添加工人等。

    希望这会有所帮助。

    【讨论】:

    • 很棒的答案。非常感谢。我现在接受这个答案,即使我需要消化一下。我确实忘记提到,由于旧服务器的设计,代理需要为每个连接的客户端维护一个与现有服务器的经典 TCP 连接。我更新了问题中的 ASCII 图形以反映这一点。我认为应该可以重新处理您的 PAIR+3 线程建议以适应这一点。只需想办法将每个 TCP 连接与对应的 ZeroMQ 连接关联起来即可。
    【解决方案2】:

    您还可以在原始模式下使用 0MQ ROUTER 套接字,这意味着您可以使用两个 ROUTER 套接字编写代理。除了父子线程管道之外,我会远离 PAIR 套接字。

    【讨论】:

      【解决方案3】:

      阅读 ZeroMQ 文档需要一些时间,尽管它非常出色。我做了并得出结论,异步客户端-服务器与我最初想要的很接近。

      但并不完全如此。所以我然后开始构建。

      我真正想要的是基于我从各种示例中学到的知识。我最终得到的完整描述在here 中,代码可能有一些用处,供参考或作为实际库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-19
        • 2012-01-02
        • 2017-05-06
        • 1970-01-01
        • 1970-01-01
        • 2011-05-02
        相关资源
        最近更新 更多