[英]Concurrent Threads Reading a Socket
I have a simple Server-Client socket connection. 我有一个简单的服务器-客户端套接字连接。 I encapsulate all my data in objects which are sent backward and forward between the sockets, sent through ObjectStreams.
我将所有数据封装在通过ObjectStreams在套接字之间来回发送的对象中。
I have created a "HeartBeat" monitor, which runs in a separate thread, where both the server and the client, every 500ms, send a HeartBeat (empty object) backward and forward to check for connectivity, which works great. 我创建了一个“ HeartBeat”监视器,该监视器在单独的线程中运行,服务器和客户端每500ms前后发送一个HeartBeat(空对象)以检查连接性,效果很好。 However, because of this, when I want to send other data between the server and client, it is mixed up with these HeartBeat objects.
但是,因此,当我要在服务器和客户端之间发送其他数据时,它与这些HeartBeat对象混合在一起。
For example my Server is expecting a Login object, but instead gets an object of instance HeartBeat. 例如,我的服务器期望使用Login对象,但获取实例HeartBeat的对象。
My code is a simple client/server setup, so I don't think it'd be necessary to post their code, however, the HeartBeat code is as follows: 我的代码是一个简单的客户端/服务器设置,因此我认为不必发布他们的代码,但是,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);
}
My options seem to be to as follows: 我的选择似乎如下:
Thanks in advance for any help! 在此先感谢您的帮助!
EDIT: Code which reads the Login object (server side): 编辑:读取登录对象(服务器端)的代码:
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 as follows: 异常如下:
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)
Consider doing something like this. 考虑做这样的事情。 I just threw this together, so it's obviously untested, but I'm sure you'll get the idea:
我只是将它们放在一起,因此显然未经测试,但是我敢肯定您会明白的:
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?
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.