6. Channel錛?/strong>Netty鏈夎嚜宸辯殑Channel鎶借薄錛屽畠鏄竴涓祫婧愮殑瀹瑰櫒錛屽寘鍚簡鎵鏈変竴涓繛鎺ユ秹鍙?qiáng)鍒扮殑鎵鏈夎祫婧愮殑楗敤錛屽灝佽NIO Channel銆丆hannelPipeline銆丅oss銆丯ioWorkerPool絳夈傚彟澶栧畠榪樻彁渚涗簡鍚戝唴閮∟IO Channel鍐欏搷搴旀暟鎹殑鎺ュ彛write銆佽繛鎺?緇戝畾鍒版煇涓湴鍧鐨刢onnect/bind鎺ュ彛絳夛紝涓漢鎰熻铏界劧瀵笴hannel鏈韓鏉ヨ錛屽洜涓哄畠?yōu)畞瑁呬簡NIO Channel錛屽洜鑰岃繖浜涙帴鍙e畾涔夊湪榪欓噷鏄悎鐞嗙殑錛屼絾鏄鏋滆冭檻鍒癗etty鐨勬灦鏋勶紝瀹冪殑Channel鍙槸涓涓祫婧愬鍣紝鏈夎繖涓狢hannel瀹炰緥灝卞彲浠ュ緱鍒板拰瀹冪浉鍏崇殑鍩烘湰鎵鏈夎祫婧愶紝鍥犺岃繖縐峸rite銆乧onnect銆乥ind鍔ㄤ綔涓嶅簲璇ュ啀鐢卞畠璐熻矗錛岃屾槸搴旇鐢卞叾浠栫被鏉ヨ礋璐o紝姣斿鍦∟etty4涓氨鍦–hannelHandlerContext娣誨姞浜唚rite鏂規(guī)硶錛岃櫧鐒秐etty4騫舵病鏈夊垹闄hannel涓殑write鎺ュ彛銆?br />Netty3涓殑Intercepting Filter妯″紡
濡傛灉璇碦eactor妯″紡鏄疦etty3鐨勯鏋訛紝閭d箞Intercepting Filter妯″紡鍒欐槸Netty鐨勪腑鏋€俁eactor妯″紡涓昏搴旂敤鍦∟etty3鐨勫唴閮ㄥ疄鐜幫紝瀹冩槸Netty3鍏鋒湁鑹ソ鎬ц兘鐨勫熀紜錛岃孖ntercepting Filter妯″紡鍒欐槸ChannelHandler緇勫悎瀹炵幇涓涓簲鐢ㄧ▼搴忛昏緫鐨勫熀紜錛屽彧鏈夊緢濂界殑鐞嗚В浜嗚繖涓ā寮忔墠鑳戒嬌鐢ㄥソNetty錛岀敋鑷寵兘寰楀績搴旀墜銆?br />
鍏充簬Intercepting Filter妯″紡鐨勮緇嗕粙緇嶅彲浠ュ弬鑰?a href="http://m.tkk7.com/DLevin/archive/2015/09/03/427086.html">榪欓噷錛屾湰鑺備富瑕佷粙緇峃etty3涓Intercepting Filter妯″紡鐨勫疄鐜幫紝鍏跺疄灝辨槸DefaultChannelPipeline瀵笽ntercepting Filter妯″紡鐨勫疄鐜般傚湪涓婃枃鏈夋彁鍒癗etty3鐨凜hannelPipeline鏄疌hannelHandler鐨勫鍣紝鐢ㄤ簬瀛樺偍涓庣鐞咰hannelHandler錛屽悓鏃跺畠鍦∟etty3涓篃璧峰埌妗ユ鐨勪綔鐢紝鍗沖畠鏄繛鎺etty3鍐呴儴鍒版墍鏈塁hannelHandler鐨勬ˉ姊併備綔涓篊hannelPipeline鐨勫疄鐜拌匘efaultChannelPipeline錛屽畠浣跨敤涓涓狢hannelHandler鐨勫弻鍚戦摼琛ㄦ潵瀛樺偍錛屼互DefaultChannelPipelineContext浣滀負(fù)鑺傜偣錛?br />public interface ChannelHandlerContext {
Channel getChannel();
ChannelPipeline getPipeline();
String getName();
ChannelHandler getHandler();
boolean canHandleUpstream();
boolean canHandleDownstream();
void sendUpstream(ChannelEvent e);
void sendDownstream(ChannelEvent e);
Object getAttachment();
void setAttachment(Object attachment);
}
private final class DefaultChannelHandlerContext implements ChannelHandlerContext {
volatile DefaultChannelHandlerContext next;
volatile DefaultChannelHandlerContext prev;
private final String name;
private final ChannelHandler handler;
private final boolean canHandleUpstream;
private final boolean canHandleDownstream;
private volatile Object attachment;
.....
}
鍦―efaultChannelPipeline涓紝瀹冨瓨鍌ㄤ簡鍜屽綋鍓岰hannelPipeline鐩稿叧鑱旂殑Channel銆丆hannelSink浠ュ強(qiáng)ChannelHandler閾捐〃鐨刪ead銆乼ail錛屾墍鏈塁hannelEvent閫氳繃sendUpstream銆乻endDownstream涓哄叆鍙f祦緇忔暣涓摼琛細(xì)
public class DefaultChannelPipeline implements ChannelPipeline {
private volatile Channel channel;
private volatile ChannelSink sink;
private volatile DefaultChannelHandlerContext head;
private volatile DefaultChannelHandlerContext tail;
......
public void sendUpstream(ChannelEvent e) {
DefaultChannelHandlerContext head = getActualUpstreamContext(this.head);
if (head == null) {
return;
}
sendUpstream(head, e);
}
void sendUpstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
try {
((ChannelUpstreamHandler) ctx.getHandler()).handleUpstream(ctx, e);
} catch (Throwable t) {
notifyHandlerException(e, t);
}
}
public void sendDownstream(ChannelEvent e) {
DefaultChannelHandlerContext tail = getActualDownstreamContext(this.tail);
if (tail == null) {
try {
getSink().eventSunk(this, e);
return;
} catch (Throwable t) {
notifyHandlerException(e, t);
return;
}
}
sendDownstream(tail, e);
}
void sendDownstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
if (e instanceof UpstreamMessageEvent) {
throw new IllegalArgumentException("cannot send an upstream event to downstream");
}
try {
((ChannelDownstreamHandler) ctx.getHandler()).handleDownstream(ctx, e);
} catch (Throwable t) {
e.getFuture().setFailure(t);
notifyHandlerException(e, t);
}
}
瀵筓pstream浜嬩歡錛屽悜鍚庢壘鍒版墍鏈夊疄鐜頒簡ChannelUpstreamHandler鎺ュ彛鐨凜hannelHandler緇勬垚閾撅紙getActualUpstreamContext()錛?/span>錛岃屽Downstream浜嬩歡錛屽悜鍓嶆壘鍒版墍鏈夊疄鐜頒簡ChannelDownstreamHandler鎺ュ彛鐨凜hannelHandler緇勬垚閾撅紙getActualDownstreamContext()錛夛細(xì)
private DefaultChannelHandlerContext getActualUpstreamContext(DefaultChannelHandlerContext ctx) {
if (ctx == null) {
return null;
}
DefaultChannelHandlerContext realCtx = ctx;
while (!realCtx.canHandleUpstream()) {
realCtx = realCtx.next;
if (realCtx == null) {
return null;
}
}
return realCtx;
}
private DefaultChannelHandlerContext getActualDownstreamContext(DefaultChannelHandlerContext ctx) {
if (ctx == null) {
return null;
}
DefaultChannelHandlerContext realCtx = ctx;
while (!realCtx.canHandleDownstream()) {
realCtx = realCtx.prev;
if (realCtx == null) {
return null;
}
}
return realCtx;
}
鍦ㄥ疄闄呭疄鐜癈hannelUpstreamHandler鎴朇hannelDownstreamHandler鏃訛紝璋冪敤
ChannelHandlerContext涓殑sendUpstream鎴杝endDownstream鏂規(guī)硶灝嗘帶鍒舵祦紼嬩氦緇欎笅涓涓?
ChannelUpstreamHandler鎴栦笅涓涓狢hannelDownstreamHandler錛屾垨璋冪敤Channel涓殑write鏂規(guī)硶鍙戦?
鍝嶅簲娑堟伅銆?br />public class MyChannelUpstreamHandler implements ChannelUpstreamHandler {
public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// handle current logic, use Channel to write response if needed.
// ctx.getChannel().write(message);
ctx.sendUpstream(e);
}
}
public class MyChannelDownstreamHandler implements ChannelDownstreamHandler {
public void handleDownstream(
ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
// handle current logic
ctx.sendDownstream(e);
}
}
褰揅hannelHandler鍚慍hannelPipelineContext鍙戦佷簨浠舵椂錛屽叾鍐呴儴浠庡綋鍓岰hannelPipelineContext鑺傜偣鍑哄彂鎵懼埌涓嬩竴涓狢hannelUpstreamHandler鎴朇hannelDownstreamHandler瀹炰緥錛屽茍鍚戝叾鍙戦丆hannelEvent錛屽浜嶥ownstream閾撅紝濡傛灉鍒拌揪閾懼熬錛屽垯灝咰hannelEvent鍙戦佺粰C(jī)hannelSink錛?br />public void sendDownstream(ChannelEvent e) {
DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
if (prev == null) {
try {
getSink().eventSunk(DefaultChannelPipeline.this, e);
} catch (Throwable t) {
notifyHandlerException(e, t);
}
} else {
DefaultChannelPipeline.this.sendDownstream(prev, e);
}
}
public void sendUpstream(ChannelEvent e) {
DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
if (next != null) {
DefaultChannelPipeline.this.sendUpstream(next, e);
}
}
姝f槸鍥犱負(fù)榪欎釜瀹炵幇錛屽鏋滃湪涓涓湯灝劇殑ChannelUpstreamHandler涓厛縐婚櫎鑷繁錛屽湪鍚戞湯灝炬坊鍔犱竴涓柊鐨凜hannelUpstreamHandler錛屽畠鏄棤鏁堢殑錛屽洜涓哄畠鐨刵ext宸茬粡鍦ㄨ皟鐢ㄥ墠灝卞浐瀹氳緗負(fù)null浜嗐?br />
ChannelPipeline浣滀負(fù)ChannelHandler鐨勫鍣紝瀹冭繕鎻愪緵浜嗗悇縐嶅銆佸垹銆佹敼ChannelHandler閾捐〃涓殑鏂規(guī)硶錛岃屼笖濡傛灉鏌愪釜ChannelHandler榪樺疄鐜頒簡LifeCycleAwareChannelHandler錛屽垯璇hannelHandler鍦ㄨ娣誨姞榪汣hannelPipeline鎴栦粠涓垹闄ゆ椂閮戒細(xì)寰楀埌鍚屽織錛?br />public interface LifeCycleAwareChannelHandler extends ChannelHandler {
void beforeAdd(ChannelHandlerContext ctx) throws Exception;
void afterAdd(ChannelHandlerContext ctx) throws Exception;
void beforeRemove(ChannelHandlerContext ctx) throws Exception;
void afterRemove(ChannelHandlerContext ctx) throws Exception;
}
public interface ChannelPipeline {
void addFirst(String name, ChannelHandler handler);
void addLast(String name, ChannelHandler handler);
void addBefore(String baseName, String name, ChannelHandler handler);
void addAfter(String baseName, String name, ChannelHandler handler);
void remove(ChannelHandler handler);
ChannelHandler remove(String name);
<T extends ChannelHandler> T remove(Class<T> handlerType);
ChannelHandler removeFirst();
ChannelHandler removeLast();
void replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler);
ChannelHandler getFirst();
ChannelHandler getLast();
ChannelHandler get(String name);
<T extends ChannelHandler> T get(Class<T> handlerType);
ChannelHandlerContext getContext(ChannelHandler handler);
ChannelHandlerContext getContext(String name);
ChannelHandlerContext getContext(Class<? extends ChannelHandler> handlerType);
void sendUpstream(ChannelEvent e);
void sendDownstream(ChannelEvent e);
ChannelFuture execute(Runnable task);
Channel getChannel();
ChannelSink getSink();
void attach(Channel channel, ChannelSink sink);
boolean isAttached();
List<String> getNames();
Map<String, ChannelHandler> toMap();
}
鍦―efaultChannelPipeline鐨凜hannelHandler閾炬潯鐨勫鐞嗘祦紼嬩負(fù)錛?br />
鍙傝冿細(xì)
銆奛etty涓婚〉銆?/a>
銆奛etty婧愮爜瑙h錛堝洓錛塏etty涓嶳eactor妯″紡銆?/a>
銆奛etty浠g爜鍒嗘瀽銆?/a>
Scalable IO In Java
Intercepting Filter Pattern

]]>