|
|||||||||
| 上一个类 下一个类 | 框架 无框架 | ||||||||
| 摘要: 嵌套 | 字段 | 构造方法 | 方法 | 详细信息: 字段 | 构造方法 | 方法 | ||||||||
public interface ChannelHandler

处理或拦截一个ChannelEvent并发送一个 ChannelEvent到ChannelPipeline
里的下一个处理器 .
ChannelHandler自己并不提供任何方法.要处理一个ChannelEvent
,你需要实现它的子接口.它有两个处理收到事件的子接口,一个用于上游事件,另一个用于下游事件:
ChannelUpstreamHandler处理和拦截一个上游ChannelEvent.ChannelDownstreamHandler处理和拦截一个下游ChannelEvent.
一个ChannelHandler是通过ChannelHandlerContext对象提供的.一个
ChannelHandler应该通过一个上下文和他属于的ChannelPipeline交互.使用上下文对象,
ChannelHandler可以传递上游事件或下游事件、动态修改管道,或保存信息(附件)到指定的处理器中.
ChannelHandler经常需要保存一下有状态的信息.最简单和推荐的方法是使用成员变量:
public class DataServerHandler extends由于处理器实例有一个专用于一个连接的状态变量,所以你需要为每个新的通道创建一个新的处理器实例以避免一个非法客户端获取机密信息的条件竞争:SimpleChannelHandler{ private boolean loggedIn;@Overridepublic void messageReceived(ChannelHandlerContextctx,MessageEvente) {Channelch = e.getChannel(); Object o = e.getMessage(); if (o instanceof LoginMessage) { authenticate((LoginMessage) o); loggedIn = true; } else (o instanceof GetDataMessage) { if (loggedIn) { ch.write(fetchSecret((GetDataMessage) o)); } else { fail(); } } } ... }
// 为每个通道创建一个处理器实例. // 查看Bootstrap.setPipelineFactory(ChannelPipelineFactory). public class DataServerPipelineFactory implementsChannelPipelineFactory{ publicChannelPipelinegetPipeline() { returnChannels.pipeline(new DataServerHandler()); } }
ChannelHandlerContext提供的附件:
既然使用附件保存处理器的状态,你可以为不同的管道添加相同的处理器实例:@Sharablepublic class DataServerHandler extendsSimpleChannelHandler{@Overridepublic void messageReceived(ChannelHandlerContextctx,MessageEvente) {Channelch = e.getChannel(); Object o = e.getMessage(); if (o instanceof LoginMessage) { authenticate((LoginMessage) o); ctx.setAttachment(true); } else (o instanceof GetDataMessage) { if (Boolean.TRUE.equals(ctx.getAttachment())) { ch.write(fetchSecret((GetDataMessage) o)); } else { fail(); } } } ... }
public class DataServerPipelineFactory implementsChannelPipelineFactory{ private static final DataServerHandler SHARED = new DataServerHandler(); publicChannelPipelinegetPipeline() { returnChannels.pipeline(SHARED); } }
ChannelLocalChannelLocal:
public final class DataServerState {
public static final ChannelLocal<Boolean> loggedIn = new ChannelLocal<Boolean>() {
protected Boolean initialValue(Channel channel) {
return false;
}
}
...
}
@Sharable
public class DataServerHandler extends SimpleChannelHandler {
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
Channel ch = e.getChannel();
Object o = e.getMessage();
if (o instanceof LoginMessage) {
authenticate((LoginMessage) o);
DataServerState.loggedIn.set(ch, true);
} else (o instanceof GetDataMessage) {
if (DataServerState.loggedIn.get(ch)) {
ctx.getChannel().write(fetchSecret((GetDataMessage) o));
} else {
fail();
}
}
}
...
}
// 打印合法客户端的远程地址:
ChannelGroup allClientChannels = ...;
for (Channel ch: allClientChannels) {
if (DataServerState.loggedIn.get(ch)) {
System.out.println(ch.getRemoteAddress());
}
}
@Sharable注解
不管上面例子是使用附件还是ChannelLocal,你可以注意到@Sharable注解.
如果一个ChannelHandler使用@Sharable
注解,这意味着你可以只创建一次处理器实例,并可以多次添加到一个或多个ChannelPipeline上而不会发生条件竞争.
如果没有指定该注解,你必须每次创建一个新的处理器实例并添加到一个管道上,因为它有不共享的状态,如成员变量.
该注解被作为文档目的提供,就像 JCIP注解.
查阅ChannelEvent和ChannelPipeline了解什么是上游事件和下游事件,它们的区别以及如果在管道中流动.

| 嵌套类摘要 | |
|---|---|
static interface |
ChannelHandler.Sharable
表示被注解的相同 ChannelHandler实例可以被多次添加到一个或多个ChannelPipeline
上而不会发生条件竞争. |
|
|||||||||
| 上一个类 下一个类 | 框架 无框架 | ||||||||
| 摘要: 嵌套 | 字段 | 构造方法 | 方法 | 详细信息: 字段 | 构造方法 | 方法 | ||||||||