【问题标题】:Java multithreaded stateful server - networking designJava多线程有状态服务器——网络设计
【发布时间】:2011-06-19 06:46:03
【问题描述】:

我正在尝试实现一个有状态的多客户端服务器应用程序,并且对网络/线程设计有一些疑问。我目前面临的问题是如何在通信层和逻辑层之间交换消息。

服务器处理多个客户端,其中每个客户端都可以在多个“通道”中处于活动状态,其中每个通道具有多个阶段并且可能有多个客户端在其中起作用。可以将其想象为类似于具有多个房间的聊天程序。

我已经在服务器端实现了消息的接收。每个客户端都有自己的线程,用于阻塞读取数据并解码为消息。现在如何进行?在我看来,每个通道也应该有自己的线程来轻松维护其状态。我可以使用 BlockingQueue 与通道线程交换接收到的消息,通道线程阻塞地等待该队列上的新消息。

那么如何向客户端发送消息呢?通道中的逻辑将处理消息,并产生一些消息发送给一个/一些/所有客户端。使用通道线程直接写入套接字是否安全?还是应该使用另一个 BlockingQueue 将消息传输到客户端处理程序线程?但是如何唤醒它,因为它正在等待套接字读取?或者我应该为每个客户端使用单独的发送线程,甚至是单独的发送套接字?

顺便说一句:我知道我可以将现有的库用于网络层,但我想在普通套接字上从头开始。

【问题讨论】:

  • 我不确定我是否会使用多线程,如果处理成本低且按消息处理的话。我会考虑改用反应堆。每个客户端和/或通道都有状态这一事实并不意味着您必须使用线程。
  • @sinelaw 我假设您指的是 NIO。我读了这篇文章paultyma.blogspot.com/2008/03/…比较 NIO/IO,所以我选择使用一个线程每个连接(并且已经实现)。但是对于渠道,可以选择另一种方法......但是实际问题将是相同的

标签: java multithreading sockets


【解决方案1】:

在封装套接字的通信对象上放置一个发送消息方法。同步此方法,以便一次只能有一个线程调用它。然后,有多少线程调用此方法没有任何区别。每条消息一次只能发送一条。您也不必打扰阻止读取的线程。此发送方法将是一个足够快的操作,您不必担心线程发送时其他线程阻塞。

只要通道对每个连接的客户端都有对通信对象的引用,它就可以发送消息而不必担心。

如果它曾经导致问题,您可以随时修改该发送消息以将要发送的对象排入队列。然后你可以有一个特定的发送线程来阻塞队列并将内容写入套接字。但根据我的经验,这不是必需的。

【讨论】:

  • 这就是我所说的“直接写入套接字”的意思,这是一个糟糕的论坛。但对我来说,有一个线程用于“读取传入消息”和另一个线程用于“处理消息和向多个客户端写入响应”似乎很奇怪。但也许这只是我对线程任务解耦的品味……
  • 您的频道线程不会处理消息并写入对多个通信对象的响应吗?我不明白为什么您需要该线程和您的通信对象之间的任何东西。实际上,该线程将通过通信对象直接写入所有套接字。
【解决方案2】:

事件机制呢?当您准备好处理请求并且有可用的客户端数据时,只需将其与客户端套接字处理程序线程的事件一起发送即可。因为来自客户端的传输已经结束,你可以正常发送回复 - 如果我认为正确的话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2013-06-11
    • 2012-06-16
    • 2017-03-29
    相关资源
    最近更新 更多