我想用Swing作为接口在Java中编写一个聊天应用程序。
我提出了一个想法(在MadProgrammer的帮助下),但我不确定这是否是解决此问题的最佳方法。
Blockinqueue
线程中有两个main
个队列,一个用于传入消息,另一个用于传出消息。
有四个线程,两个用于传出,两个用于传入消息,一个用于处理GUI和套接字。
外发邮件的主题
ActionListener (Swing)
:当用户点击GUI中的“发送”时触发。该线程将新消息添加到传出队列并在其上触发notifyAll()
。socketOutgoing
:可以访问套接字。在传出队列中以wait()
休眠,直到通知为止。通过套接字在Outgoing Queue中发送新消息,然后再次进入休眠状态。收到消息的主题
socketIncoming:
可以访问套接字。不断检查新的
套接字中的消息(如何?)。当有新消息时,将其添加到
传出队列并触发notifyAll()
。Swingworker displayIncoming
:在传入队列中使用wait()
睡眠,直到通知为止。在GUI中显示新消息,然后再次进入休眠状态。虽然这在理论上会起作用,但为此有四个线程似乎有点混乱(并且不可靠)。
有更实用的解决方案吗?
请注意未来的读者:我对socketIncoming
的描述是误导的:无法“在套接字中持续检查新邮件”。
当您致电ObjectInputStream#readObject()
并且没有新消息时,它只是等待或“阻止”,直到新消息到达。无法事先检查新消息是否已到达。 See this question。
答案 0 :(得分:3)
如果我正在考虑做某事,我可能会设置两个队列,一个传出和传入队列。这些将用于“暂存”消息。
这个想法是将传出的消息放入传出队列中,当Thread
能够执行时,它会弹出下一条消息并发送它。当队列为空时,它只会“等待”,直到有新消息可用。
该概念对于传入队列反向工作。 Thread
将读取一条消息并将其推送到传入队列。
其他一些进程(可能是SwingWorker
)将监视队列并弹出下一条消息并将其与GUI重新同步。
您可能会发现Concurrency in Swing有些用途。
基础协议的实际工作原理如何通过
来规定更多细节答案 1 :(得分:1)
对于简单的聊天应用程序,您应该有两个部分
现在,您必须决定要用于通信[Tcp]或[Udp]的协议。虽然您的消息传输应该是可靠的,但您必须使用java Tcp ServerSocket。您的服务器将是多线程意味着每个客户端与服务器连接将具有单独的线程来处理来自该客户端的所有消息通信。
对于客户端,它将具有GUI组件和一个专用线程来接收来自服务器的消息。当您想要向任何用户发送消息时,只需传递消息并通过客户端套接字发送。