我目前正致力于实施隐私保护数据挖掘算法。对于我正在使用Netty 4.0的不同方之间的通信部分。双方之间的沟通流程如下:
-- multiplicationMsg --> ... -- multiplicationMsg -->
P_{1} P_{N}
<-- multiplicationMsg -- ... <-- multiplicationMsg --
其中P_{1}
是发起和控制整个计算的主方。安全多方乘法的逻辑位于Netty ChannelHandler
中。还有另一种安全添加协议。
目前我使用类似this的解决方案,由Netty核心团队的Norman Maurer展示,以便在子协议计算完成时获得通知。但这感觉有点像与框架作斗争。
有没有办法从channel.write(msg)
获得自定义承诺,这将在ChannelPipeline
中创建并实现?在上面的示例中,当multiplicationMsg
返回P_{1}
时,应该会完成此操作。
修改1
这是我通常从ChannelPipeline
:
ChannelFuture f = channel.write(msg);
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
//do something with the future
}
});
如果数据可以写入套接字或发生故障,则上述示例中的ChannelFuture
f
将得到满足。但除了Future
之外,我还需要一种方法来取回自定义ChannelFuture
,不知怎的样:
ChannelFuture f = channel.write(msg);
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
// I need something like the following
if(future.isSuccess()) {
Future myFuture = future.getMyFuture();
}
}
});
答案 0 :(得分:4)
有很多方法可以做到这一点,这里有一个建立在netty之上的例子:
从管道外部,使用包含IoClient
(来自连接初始化)的类(例如,ChannelFuture
)中的公共方法发送消息。该方法看起来像这样:
public MyCustomFuture send(String msg) {
MyCustomFuture responseFuture = new MyCustomFuture();
channelFuture.channel().pipeline().get(MyAppClientHandler.class).setResponseFuture(responseFuture);
channelFuture.channel().writeAndFlush(msg);
return responseFuture;
}
MyCustomFuture
是我们创建实现netty的Future
接口的自定义类,因此它的实例将代理我们的消息。 MyAppClientHandler
是要履行承诺的网络管道(在responseFuture
中),.setResponseFuture(...)
将代理添加到管道。
根据频道的初始化,channelFuture.channel()
可能仍为null
,为我们提供NullPointerException
。所以我们需要更改上面的代码以从回调中插入代理:
public MyCustomFuture send(final String msg) {
final MyCustomFuture responseFuture = new MyCustomFuture();
channelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
channelFuture.channel().pipeline()
.get(MyAppClientHandler.class).setResponseFuture(responseFuture);
channelFuture.channel().writeAndFlush(msg);
}
});
return responseFuture;
}
关于MyCustomFuture
的另一件事是它需要一个setter方法:
public void set(String msg) throws InterruptedException {
if (state == State.DONE) {
return;
}
blockingReplyHolder.put(msg);
state = State.DONE;
}
顾名思义, blockingReplyHolder
是实现的字段,它包含履行承诺的消息,并且如果它仍然不存在则阻止(检查Future)< / p>
右。现在,当预期的消息到达管道MyAppClientHandler
时,我们可以履行承诺,如:
protected void channelRead(ChannelHandlerContext ctx, String msg) throws Exception {
responseFuture.set(msg);
}
生成的自定义API的用法是:
MyCustomFuture future = ioClient.send(message);
// do other stuff if needed
String response = future.get(); // waits if necessary
// make use of the response
这个答案来自于我正在玩弄的example。