专用协议的长寿命多线程客户端(Python、select、epoll)

专用协议的长寿命多线程客户端(Python、select、epoll),python,asynchronous,client,asyncsocket,Python,Asynchronous,Client,Asyncsocket,第一件事是,我是一个长期的潜伏者,但第一次用户,我想感谢你们所有人创建的网站 我的情况是,我需要实现专有协议的客户端部分。协议下面使用TCP/IP,消息流可总结如下: 客户端连接到服务器 客户表示对某种类型的数据感兴趣 如果服务器有任何这样的数据,它会发送到客户端 客户端向服务器确认接收 客户机现在需要告诉服务器它仍然对相同类型的数据感兴趣 服务器在数据进入时将数据发送到客户端 客户端需要不时地(比如每分钟左右)向服务器发送应用程序级别的保持活动请求 来自服务器的某些消息要求客户端将回复发送回服

第一件事是,我是一个长期的潜伏者,但第一次用户,我想感谢你们所有人创建的网站

我的情况是,我需要实现专有协议的客户端部分。协议下面使用TCP/IP,消息流可总结如下:

  • 客户端连接到服务器
  • 客户表示对某种类型的数据感兴趣
  • 如果服务器有任何这样的数据,它会发送到客户端
  • 客户端向服务器确认接收
  • 客户机现在需要告诉服务器它仍然对相同类型的数据感兴趣
  • 服务器在数据进入时将数据发送到客户端
  • 客户端需要不时地(比如每分钟左右)向服务器发送应用程序级别的保持活动请求
  • 来自服务器的某些消息要求客户端将回复发送回服务器
  • 客户端断开连接
  • 所有这些都将发生在一个TCP会话中,这将是一个长寿的会话,有点像我想象中的WebSocket

    另一件事是,客户端将部署在多线程服务器上,并且应该允许多个线程同时访问,这意味着单个线程应该能够“订阅”来自服务器的特定类型的消息,并且还应该能够向其发送消息

    我很了解GIL,所以我想对此没有什么评论,我只是在写一个客户,我不能改变架构的任何其他部分

    所以问题是,我从来没有深入研究过HTTP级别以下的内容,我很幸运总是使用一些已经存在的库,另一方面,我还没有做过那么多的网络编程,这将是我自己第一次这样做

    我希望这是我进一步了解所有异步库/工具/工具包(如select、epoll、libev或gevent)的机会

    问题是,web上的大多数资源都与编写服务器有关,我甚至不确定是否要将客户端部署在多线程上,这并不意味着所有这些资源都做不了什么。显然,所有的服务器都是单线程的,但不清楚这是因为不需要多个线程,还是因为epoll之类的东西不喜欢多线程使用它们

    服务器显然会将所有客户端视为单线程单元,因此我认为需要序列化对客户端的访问。我不太明白的是如何确保服务器响应与线程匹配,反之亦然。如果一个线程接收到一条消息,但另一个线程需要在前一个线程获得确认消息的机会之前确认它接收到的消息,那么我如何确保消息不会混淆

    你觉得这一切怎么样?在这种情况下,异步库是一个不错的选择吗?你能想出一些我可以看一下的代码示例吗?我使用Python,但是我认为这个问题是通用的,我可以用C,C++或java来启发。
    非常非常感谢

    每个线程(每个客户端)都可以打开自己的套接字吗?在这种情况下,这都不是问题:只有一个线程中的客户端在该套接字上有句柄,因此它会自动从服务器获取正确的数据。对于服务器,来自客户端的所有这些连接看起来都像是完全独立的客户端连接(这正是它们的本质)

    如果其中一个要求是限制网络连接的总数,那么您可以构造一个特殊的线程来维护与服务器的连接,并在本地接收来自不同线程的通信请求/但是使用独立套接字(每个线程一个)可能要简单得多

    您是否一定要使用应用程序级keepalive?因为TCP可以自动为您执行此操作。如果未及时收到keepalive,则套接字将关闭,从而通知另一端连接已超时。如果你的情况下有可能,请考虑这是一个选项。


    最后,如果您不必执行应用程序级别的keepalive,那么您可以利用多线程编程的一个优点:将每个线程开发为只有一个线程,这样您就不必担心任何异步问题。例如,您可以编写客户端发送请求,然后阻塞等待响应,进行计算,然后发送结果或检查是否有来自服务器的更多数据到达。来自服务器的数据将累积在您一侧的TCP接收窗口中。这也可以作为流量控制的一种手段:如果您的客户端变得太慢,并且接收窗口已满,那么服务器将无法再发送。这可能会阻塞服务器,因此您需要查看服务器是否可以处理这种情况。

    每个线程(每个客户端)是否可以打开自己的套接字?在这种情况下,这都不是问题:只有一个线程中的客户端在该套接字上有句柄,因此它会自动从服务器获取正确的数据。对于服务器,来自客户端的所有这些连接看起来都像是完全独立的客户端连接(这正是它们的本质)

    如果其中一个要求是限制网络连接的总数,那么您可以构造一个特殊的线程来维护与服务器的连接,并在本地接收来自不同线程的通信请求/但是使用独立套接字(每个线程一个)可能要简单得多

    您是否一定要使用应用程序级keepalive?因为TCP可以自动为您执行此操作。如果未及时收到keepalive,则套接字将关闭,从而通知另一端连接已超时。如果它是POS,请考虑这是一种选择。