2

我正在尝试使用 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 消息。在客户端,DemuxingProtocolCodecFactory接收响应,但在进行一些日志记录后,我可以看到客户端卡在对readFuture.awaitUninterruptibly().

我一生都无法根据我自己的代码弄清楚为什么它会卡在这里。我在会话配置上正确地将读取操作设置为 true,这意味着应该阻止消息。但是,当我尝试同步读取响应消息时,消息似乎不再存在。

关于为什么这对我不起作用的任何线索?

4

4 回答 4

1

这对我不起作用的原因是因为我的代码中的其他地方存在一个问题,我愚蠢地忽略了实现消息响应编码器/解码器。啊。无论如何,我问题中的代码在我修复它后立即起作用。

于 2010-08-01T20:03:25.420 回答
1

我更喜欢这个(Christian Mueller:http ://apache-mina.10907.n7.nabble.com/Mina-Client-which-sends-receives-messages-synchronous-td35672.html )

public class UCPClient { 

private Map<Integer, BlockingQueue<UCPMessageResponse>> concurrentMap = new ConcurrentHashMap<Integer, BlockingQueue<UCPMessageResponse>>(); 

// some other code 

public UCPMessageResponse send(UCPMessageRequest request) throws Throwable { 
    BlockingQueue<UCPMessageResponse> queue = new LinkedBlockingQueue<UCPMessageResponse>(1); 
    UCPMessageResponse res = null; 

    try { 
        if (sendSync) { 
            concurrentMap.put(Integer.valueOf(request.getTransactionReference()), queue); 
        } 

        WriteFuture writeFuture = session.write(request); 

        if (sendSync) { 
            boolean isSent = writeFuture.await(transactionTimeout, TimeUnit.MILLISECONDS); 

            if (!isSent) { 
                throw new TimeoutException("Could not sent the request in " + transactionTimeout + " milliseconds."); 

            } 

            if (writeFuture.getException() != null) { 
                throw writeFuture.getException(); 
            } 

            res = queue.poll(transactionTimeout, TimeUnit.MILLISECONDS); 

            if (res == null) { 
                throw new TimeoutException("Could not receive the response in " + transactionTimeout + " milliseconds."); 
            } 
        } 
    } finally { 
        if (sendSync) { 
            concurrentMap.remove(Integer.valueOf(request.getTransactionReference())); 
        } 
    } 

    return 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); 
    } 
} 

}

于 2018-09-05T09:42:50.347 回答
0

我有这个确切的问题。事实证明,这是因为我在 IoHandler.sessionCreated() 实现中进行读/写。我将处理转移到建立连接的线程上,而不是仅仅等待不久的将来。

于 2010-08-17T18:32:28.807 回答
-1

您不得在Thread中使用您的login()函数:IoHandler

如果调用IoFuture.awaitUninterruptibly()的覆盖事件函数IoHandler

IoHandler 不起作用并被卡住。

您可以调用login()其他线程,它将正常工作。

于 2014-02-06T13:58:11.953 回答