Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MINA:执行同步写入请求/读取响应_Java_Sockets_Synchronous_Apache Mina - Fatal编程技术网

Java MINA:执行同步写入请求/读取响应

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

我正试图用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
    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); 
    } 
}