Java MINA:执行同步写入请求/读取响应
我正试图用MINA 2.0 RC1在一个基于demux的客户端应用程序中执行同步写/读操作,但它似乎被卡住了。这是我的密码:Java MINA:执行同步写入请求/读取响应,java,sockets,synchronous,apache-mina,Java,Sockets,Synchronous,Apache Mina,我正试图用MINA 2.0 RC1在一个基于demux的客户端应用程序中执行同步写/读操作,但它似乎被卡住了。这是我的密码: public boolean login(final String username, final String password) { // block inbound messages session.getConfig().setUseReadOperation(true); // send the login request fi
public boolean login(final String username, final String password) {
// block inbound messages
session.getConfig().setUseReadOperation(true);
// send the login request
final LoginRequest loginRequest = new LoginRequest(username, password);
final WriteFuture writeFuture = session.write(loginRequest);
writeFuture.awaitUninterruptibly();
if (writeFuture.getException() != null) {
session.getConfig().setUseReadOperation(false);
return false;
}
// retrieve the login response
final ReadFuture readFuture = session.read();
readFuture.awaitUninterruptibly();
if (readFuture.getException() != null) {
session.getConfig().setUseReadOperation(false);
return false;
}
// stop blocking inbound messages
session.getConfig().setUseReadOperation(false);
// determine if the login info provided was valid
final LoginResponse loginResponse = (LoginResponse)readFuture.getMessage();
return loginResponse.getSuccess();
}
我可以在服务器端看到,已检索LoginRequest对象,并发送LoginResponse消息。在客户端,protocolcodecfactory
接收到响应,但在插入一些日志后,我可以看到客户端在调用readFuture.waitingly()时遇到了问题
我一辈子都搞不明白为什么基于我自己的代码它会被困在这里。我在会话配置中将读取操作正确设置为true,这意味着应该阻止消息。然而,当我尝试同步读取响应消息时,消息似乎已经不存在了
关于为什么这对我不起作用,有什么线索吗?这对我不起作用的原因是我的代码中有一个问题,我愚蠢地忽略了实现消息响应编码器/解码器。啊。不管怎样,我的问题中的代码在我修复它之后就开始工作了。我遇到了这个问题。事实证明,这是因为我在IoHandler.sessionCreated()实现中进行了读/写操作。我将处理移到建立连接的线程上,而不是等待不久的将来。您不能在IoHandler
线程中使用login()
函数:
如果在IoHandler
的覆盖事件函数中调用IoFuture.waitunterruptibly()
IoHandler不工作就会卡住
您可以在其他线程中调用login()
,它将正常工作。我更喜欢这个(Christian Mueller:)
公共类UCPClient{
私有映射concurrentMap=新的ConcurrentHashMap();
//其他代码
公共UCPMessageResponse发送(UCPMessageRequest请求)抛出可丢弃的{
BlockingQueue=新的LinkedBlockingQueue(1);
UCPMessageRes=null;
试试{
如果(发送同步){
concurrentMap.put(Integer.valueOf(request.getTransactionReference()),queue);
}
WriteFuture WriteFuture=会话。写入(请求);
如果(发送同步){
布尔值isSent=writeFuture.await(transactionTimeout,TimeUnit.毫秒);
如果(!isSent){
抛出新的TimeoutException(“无法在“+transactionTimeout+”毫秒内发送请求”);
}
如果(writeFuture.getException()!=null){
抛出writeFuture.getException();
}
res=queue.poll(transactionTimeout,TimeUnit.ms);
如果(res==null){
抛出新的TimeoutException(“无法在“+transactionTimeout+”毫秒内接收响应”);
}
}
}最后{
如果(发送同步){
remove(Integer.valueOf(request.getTransactionReference());
}
}
返回res;
}
}
而IoHandler:
public class InnerHandler implements IoHandler {
// some other code
public void messageReceived(IoSession session, Object message) throws Exception {
if (sendSync) {
UCPMessageResponse res = (UCPMessageResponse) message;
BlockingQueue<UCPMessageResponse> queue = concurrentMap.get(res.getTransactionReference());
queue.offer(res);
}
}
公共类InnerHandler实现IoHandler{
//其他代码
public void messageReceived(IoSession会话,对象消息)引发异常{
如果(发送同步){
UCPMessageRes=(UCPMessageResponse)消息;
BlockingQueue=concurrentMap.get(res.getTransactionReference());
排队。报价(res);
}
}
}我不熟悉MINA,只是出于好奇-如果你同步做所有事情,你必须使用futures吗?我相信如果你的应用程序通常异步通信,但在应用程序中的任何给定点都需要特殊情况,你只需要使用futures同步读/写。这就是我在这里尝试登录的目的,而我的其余通信将异步处理。谢谢回复!不确定是谁否决了你,但如果是真的,可能会帮助其他人。不幸的是,我已经有一段时间没有接触此代码了,因此我无法测试您答案的有效性。:)
public class InnerHandler implements IoHandler {
// some other code
public void messageReceived(IoSession session, Object message) throws Exception {
if (sendSync) {
UCPMessageResponse res = (UCPMessageResponse) message;
BlockingQueue<UCPMessageResponse> queue = concurrentMap.get(res.getTransactionReference());
queue.offer(res);
}
}