【问题标题】:Java chat application using Swing (Conceptual)使用 Swing 的 Java 聊天应用程序(概念)
【发布时间】:2014-01-21 02:03:03
【问题描述】:

我想用 Java 编写一个使用 Swing 作为接口的聊天应用程序。

我想出了一个想法(在MadProgrammer 的帮助下),但我不确定这是否是最好的方法。

main 线程中有两个Blockinqueue 队列,一个用于传入消息,一个用于传出消息。

有四个线程,两个用于传出消息,两个用于传入消息,一个用于处理 GUI 和套接字。

传出消息的线程:

  1. ActionListener (Swing):当用户在 GUI 中单击“发送”时触发。该线程将新消息添加到 Outgoing Queue 并在其上触发 notifyAll()
  2. socketOutgoing:可以访问套接字。休眠,wait() 在 Outgoing Queue 上,直到收到通知。通过套接字在 Outgoing Queue 中发送新消息,然后再次进入睡眠状态。

传入消息的线程:

  1. socketIncoming: 可以访问套接字。不断检查新的 套接字中的消息(如何?)。当有新消息时,将其添加到 传出队列并在其上触发notifyAll()
  2. Swingworker displayIncoming:休眠,wait() 在传入队列中,直到收到通知。在 GUI 中显示新消息,然后再次进入睡眠状态。

虽然这在理论上可行,但为此设置四个线程似乎有点混乱(而且不可靠)。

有没有更实用的解决方案?

未来读者请注意:我对@9​​87654335@ 的描述有误:不可能“连续检查套接字中的新消息”。

当您调用ObjectInputStream#readObject() 并且没有新消息时,它只是等待或“阻塞”,直到有新消息到达。没有办法事先检查是否有新消息到达。 See this question

【问题讨论】:

  • “不断检查套接字中的新消息(如何?)” 基本上是while(true) { checkForMessage(); },但您不希望它完全失控地运行。您可能会查看ScheduledThreadPoolExecutor 和它的旧版本Timer 来以特定速率调度单个任务。 “为此使用四个线程似乎有点混乱(而且不可靠)” 多个线程使复杂任务远离 EDT 和 GUI 响应。
  • 谢谢,我会调查的。

标签: java multithreading swing sockets


【解决方案1】:

如果我正在考虑做类似的事情,我可能会设置两个队列,一个传出队列和传入队列。这些将用于“暂存”消息。

这个想法是将传出的消息放入传出队列中,当Thread 能够这样做时,它将弹出下一条消息并发送它。当队列为空时,它会简单地“等待”直到有新消息可用。

对于传入队列,该概念将相反。 Thread 会读取一条消息并将其推送到传入队列中。

其他一些进程(可能是SwingWorker)将监视队列并弹出它的下一条消息并与 GUI 重新同步。

您可能会发现 Concurrency in Swing 有一些用处。

不过,底层协议的实际工作方式将决定更多细节

【讨论】:

  • 感谢您的回答。我会调查的。
  • 我添加了很多细节。你能看一下,告诉我你的想法吗?
  • 您可能想要搜索阻塞队列,因为这些实际上可能能够减少一些工作量。另外,这一切都取决于您的协议是如何编写的。发送消息应该有某种回执,例如,如果消息接收正常、已送达或因某种原因被拒绝,则让发件人现在。这使问题复杂化,因为您不能简单地从另一个线程中的传入流中“读取”下一条消息,因为它可能会获取“协议”消息......
  • 差不多。这样做的目的是,如果你能找到一个实现,它们应该在你调用get 时阻塞,直到有东西可用
  • 是的,它应该是......但您需要仔细阅读文档,因为 poll 方法的大多数状态类似于 " 或返回 null 如果此队列是空"
【解决方案2】:

对于一个简单的聊天应用程序,您应该有两个部分

  1. 客户端部分
  2. 服务器部分。

现在,您必须决定要使用哪种协议进行通信 [Tcp] 或 [Udp]。虽然您的消息传输应该是可靠的,但您必须使用 java Tcp ServerSocket。您的服务器将是多线程的,这意味着每个与服务器连接的客户端都有单独的线程来处理来自该客户端的所有消息通信。

对于客户端,它将具有 GUI 组件和一个专用线程来接收来自服务器的消息。当您想向任何用户发送消息时,只需传递消息并通过客户端套接字发送。

【讨论】:

  • 谢谢,我已经决定使用 TCP,目前正在编写客户端代码。
  • 我已经编辑了我的答案,你能看一下吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
相关资源
最近更新 更多