我有一个简单的服务器-客户端套接字连接。我将所有数据封装在对象之间,这些对象在通过ObjectStreams发送的套接字之间来回发送。
我创建了一个“HeartBeat”监视器,该监视器在单独的线程中运行,服务器和客户端每500ms向前和向后发送一个HeartBeat(空对象)以检查连接性,效果很好。但是,因此,当我要在服务器和客户端之间发送其他数据时,它与这些HeartBeat对象混合在一起。
例如,我的服务器需要一个Login对象,但是却获得了HeartBeat实例的对象。
我的代码是一个简单的客户端/服务器设置,因此我认为不必发布他们的代码,但是,HeartBeat代码如下:
private static final int HEARTBEAT_INTERVAL = 500;
private void addHeartBeatMonitor(final Socket socket) {
this.heartBeatTimer = new Timer();
this.heartBeatTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(new HeartBeat());
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
if (!(is.readObject() instanceof HeartBeat)) { throw new IOException(); }
} catch (IOException e) {
LOG.info("Received disconnect from " + getClientSocket().getInetAddress());
heartBeatTimer.cancel();
if (clientSocket != null) {
try {
clientSocket.close();
} catch (IOException e1) {}
}
} catch (ClassNotFoundException e) {}
}
}, 0, HEARTBEAT_INTERVAL);
}
我的选择似乎如下:
在此先感谢您的帮助!
编辑:
读取Login对象(服务器端)的代码:
User result = null;
try {
ObjectInputStream is = new ObjectInputStream(this.getInputStream());
Login request = (Login) is.readObject(); ### ERROR ###
result = this.mongoService.login(request);
ObjectOutputStream os = new ObjectOutputStream(this.getOutputStream());
os.writeObject(result);
} catch (IOException e) {
} catch (ClassNotFoundException e) {}
return result;
异常如下:
Exception in thread "Thread-0" java.lang.ClassCastException: model.HeartBeat cannot be cast to model.Login
at socket.SocketServerWorker.login(SocketServerWorker.java:78)
at socket.SocketServerWorker.<init>(SocketServerWorker.java:47)
at socket.SocketServer$2.run(SocketServer.java:50)
at java.lang.Thread.run(Thread.java:744)
最佳答案
考虑做这样的事情。我只是把它们放在一起,所以显然没有经过测试,但是我相信您会明白的:
public class HeartBeatMonitor
{
final Map<Class,Consumer> handlers = new HashMap<> ();
final Socket sock;
final ObjectInputStream is;
final ObjectOutputStream os;
public HeartBeatMonitor (final Socket sock)
{
try
{
this.sock = sock;
this.is = new ObjectInputStream (sock.getInputStream ());
this.os = new ObjectOutputStream (sock.getOutputStream ());
}
catch (final IOException e)
{
throw new RuntimeException (e);
}
}
public <T> void setHandler (final Class<T> type, final Consumer<? super T> handler)
{
this.handlers.put (type, handler);
}
// This would be called in a loop
void accept () throws ClassNotFoundException, IOException
{
final Object o = this.is.readObject ();
final Consumer handler = this.handlers.get (o.getClass ());
if (handler != null)
handler.accept (o);
// Else default handler?
}
}