2

我正在创建一个通用的 Erlang 服务器,它应该能够同时处理数百个客户端连接。为简单起见,假设服务器为每个客户端执行一些基本计算,例如客户端提供的每两个值的加法或减法。

作为起点,我将本教程用于基本的 TCP 客户端-服务器交互。代表监督树的摘录:

                +----------------+
                | tcp_server_app |
                +--------+-------+
                         | (one_for_one)
        +----------------+---------+
        |                          |
+-------+------+           +-------+--------+
| tcp_listener |           + tcp_client_sup |
+--------------+           +-------+--------+
                                   | (simple_one_for_one)
                             +-----|---------+
                           +-------|--------+|
                          +--------+-------+|+
                          |  tcp_echo_fsm  |+
                          +----------------+

我想扩展此代码并允许tcp_echo_fsm将对套接字的控制传递给两个模块之一:(tcp_echo_addition计算每两个客户端值的加法),或tcp_echo_subtraction(计算每两个客户端值之间的减法)。

tcp_echo_fsm根据来自客户端的第一条消息选择哪个模块来处理套接字,例如,如果客户端发送<<start_addition>>,则它将控制权传递给tcp_echo_addition

上图变成:

                +----------------+
                | tcp_server_app |
                +--------+-------+
                         | (one_for_one)
        +----------------+---------+
        |                          |
+-------+------+           +-------+--------+
| tcp_listener |           + tcp_client_sup |
+--------------+           +-------+--------+
                                   | (simple_one_for_one)
                             +-----|---------+
                           +-------|--------+|
                          +--------+-------+|+
                          |  tcp_echo_fsm  |+
                          +----------------+
                                  |
                                  |
                 +----------------+---------+
         +-------+-----------+      +-------+--------------+
         | tcp_echo_addition |      + tcp_echo_subtraction |
         +-------------------+      +-------+--------------+

我的问题是:

  1. 我在正确的道路上吗?我正在使用的教程是可扩展 TCP 服务器设计的良好起点吗?

  2. 如何将控制权从一个 gen_fsm(即tcp_echo_fsm)传递给另一个 gen_fsm(tcp_echo_additiontcp_echo_subtraction)?或者更好:这是设计服务器的正确/干净的方式吗?这个相关问题表明,在 gen_fsm 和另一个模块之间传递控制权并非易事,这种方法可能有问题。

4

1 回答 1

3

对于 2,您可以使用gen_tcp:controlling_process/2来传递对 tcp 连接的控制: http: //erlang.org/doc/man/gen_tcp.html#controlling_process-2

对于 1,我不确定生成新模块的价值,而不是作为有限状态机中定义状态的一部分处理减法和加法逻辑。这样做会创建现在在您的监督树之外运行的代码,因此更难处理错误和重新启动。为什么不将加法和减法定义为状态机中的不同状态处理这两种状态中的逻辑呢?

您可以创建tcp_echo_fsm:subtraction_state/2,3tcp_echo_fsm:addition_state/2,3处理此逻辑,并使用您的第一条消息转换到适当的状态,而不是增加应用程序的复杂性。

于 2015-07-13T20:04:27.733 回答