【发布时间】:2012-10-09 07:52:29
【问题描述】:
我正在使用像 MSN 这样的 IM 程序用 Java 制作一个聊天程序。现在,我的程序不会像 MSN 那样功能齐全,我也不会深入研究广泛的 GUI 设计。
我的问题是,我可能会选择错误的设计来做到这一点。
我目前正在设计一个会话对象。基本上,用户与服务器联系并处于“边缘”状态,直到他们决定邀请某人聊天。然后是服务器的工作(还没有到那部分)在所涉及的用户之间建立一个会话。
我的问题是,我必须监听多个 InputStream 的变化并相应地更新每个人的显示。当其中一个“向会话发送消息”时,我将如何设法监听所有 InputStream 并进行更新?
到目前为止,这是我的代码。时间不长。
包服务器;
import java.io.*;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*
* @author Vipar
*/
public class Session implements Runnable {
private static User[] users;
private static PrintWriter[] outputs;
private int sessionId;
public Session(User[] users) {
this.users = users;
outputs = new PrintWriter[users.length];
sessionId = this.hashCode();
try {
for(int i = 0; i < users.length; i++) {
outputs[i] = new PrintWriter(users[i].getSocket().getOutputStream(), true);
}
} catch (IOException ioe) {
ChatServer.print("An error occured in session " + sessionId);
ChatServer.print(ioe.getMessage());
}
}
@Override
public void run() {
ChatServer.print("SessionId: " + sessionId + " have initiated.");
ExecutorService service = Executors.newFixedThreadPool(users.length);
for(int i = 0; i < users.length; i++) {
service.submit(new InputStreamListener(users[i]));
}
do {
if(users.length < 2) {
ChatServer.print("SessionId: " + sessionId + " have ended.");
break;
}
} while(true);
}
public static void update(User u, String message) {
for(int i = 0; i < users.length; i++) {
outputs[i].println("new");
outputs[i].println(u.getUserName());
outputs[i].println(message);
}
}
}
我刚刚做的InputStreamListener:
package server;
import java.util.Scanner;
import java.io.*;
import java.util.NoSuchElementException;
/**
*
* @author Vipar
*/
public class InputStreamListener implements Runnable {
private Scanner scanner;
private User user;
public InputStreamListener(User user) {
this.user = user;
try {
scanner = new Scanner(user.getSocket().getInputStream());
} catch (IOException ioe) {
ChatServer.print("An Error occured for the InputStream: "
+ user.getUserName());
ChatServer.print(ioe.getMessage());
}
}
@Override
public void run() {
String s = "";
do {
try {
s = scanner.nextLine();
Session.update(user, s);
} catch(NoSuchElementException e) {
continue;
}
} while(!s.equals("/DISCONNECT"));
try {
user.getSocket().close();
} catch(IOException ioe) {
ChatServer.print("Problem closing users InputStream: "
+ user.getUserName());
ChatServer.print(ioe.getMessage());
}
}
}
【问题讨论】:
-
我会为每个连接使用一个线程,并使用 ExecutorService 来保存所有线程,以便它们被回收。
-
服务器应该管理线程部分。这样每个会话都有自己的线程来运行。
-
我相信是最简单的,。您可以避免使用非阻塞 NIO 执行此操作,但这会增加很多复杂性,除非您知道自己需要它,否则我会避免这样做。
-
在考虑 NIO 或 NIO2 之前,我会先让 IO 实现工作;)
标签: java io inputstream