java - 接收输入后如何通知所有线程
问题描述
我目前正在开发一些东西,我有一个服务器等待连接,一旦建立连接,就会创建一个线程来处理服务器和客户端之间的通信。所有这些通信都是基于字符串的,使用 InputStreamReaders 和 OutputStreamReaders,我现在需要做的是能够通过他们自己的 ServerThread 向每个连接的客户端发送消息。事物如何编写的一个简单视图是:
public final static int SERVER_PORT = 12345;
private static int numThreads=0;
public void Server() {
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(Server.SERVER_PORT);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
while (true) {
try {
Socket socket = serverSocket.accept();
numThreads++;
new ServerThread(socket, numThreads).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
该变量numThreads
主要用于向客户端打印特定信息。在ServerThread
我会:
@Override
public void run() {
while (true) {
String command=null;
try{
command = readString(); //method that reads input from Client
//Do actions based on command
}catch(Exception ex){
ex.getMessage();
}
}
//Close streams and socket
}
显示的方法的内容可能有一些错别字,因为目前它们还有很多,但应该有助于可视化问题。
为了简化客户端,让我们假设有一个客户端,它连接到服务器并将命令/消息发送到我们的ServerThread
.
每次客户端连接到服务器时,ServerThread
都会创建一个新的,它将不断等待客户端发送一个command
. 如果这command
对应于例如“发送”,我需要向连接到服务器的每个客户端发送一条消息。
我怎么能做到这一点?
解决方案
这里我提供一个思路,可以通过事件监控(Observer Pattern)来解决。
可以将发布者分成单独的类。
public class ServerThread implements Runnable {
// Used for event subscription (CopyOnWriteArrayList is not the best implementation, please adjust
// according to project needs)
private static final List<ServerThread> LISTENERS = new CopyOnWriteArrayList<>();
public ServerThread(Socket socket, int num) {
// do something ...
LISTENERS.add(this);
}
@Override
public void run() {
while (true) {
String command = null;
try {
command = readString(); // method that reads input from Client
// Do actions based on command
if ("send".equals(command)) {
ServerThread.publish(new SendEvent(command));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// Close streams and socket
}
private String readString() {
return null;
}
/**
* event publishing method
*
* @param event
*/
public static void publish(SendEvent event) {
LISTENERS.forEach(listener -> listener.listen(event));
}
/**
* Event processing method
*
* @param event
*/
public void listen(SendEvent event) {
// to something ...
}
}
推荐阅读
- java - JavaFX ListChangeListener 删除触发添加更改
- javascript - 使用 JavaScript 在 URL 中添加 GET 参数
- c++ - 将对象插入 std::map 时构造函数中的变量地址
- realm - Realm db 的撤消管理
- .net - 如何为 ARM 平台构建 Tizen C# .NET Wearable TPK 并发布到三星卖家门户?
- javascript - 在 dataLoader amchart v3 中循环
- java - 有没有办法根据给定的字符串设置实例的成员变量?
- firebase - Flutter Cloud Firestore 仅在调试时获取最新数据
- c - 如何订购相互依赖的功能?
- javascript - 将“keydown”事件侦听器添加到文档中,输入字段除外