title | date | categories | tags | description | ||||
---|---|---|---|---|---|---|---|---|
26.同时作为客户端和服务端 |
2020-04-20 |
|
|
|
同时作为客户端和服务端的情况。
比如 , 客户端C1与服务器端S1建立连接, 然后客户端C1把数据发送给S1。 S1拿到数据后,要把数据转发到另外 一个服务器端S2。 对于C1而言, S1是服务端; 对于S2而言, S1是客户端。
当S1作为服务端, 它启动的话 需要使用 ServerBootstrap。
当S1作为客户端, 它启动的话 需要使用 Bootstrap。
C1 ---> S1 ---- > S2
对于这种情况,要让它的客户端功能和服务端功能共用 EventLoop。
怎么共用?
我们知道, 当S1作为服务器的时候,有个workGroup, 里面有多个EventLoop, 每个EventLoop又和一个Thread关联。当与客户端Channel 进行IO通信的时候,其实是在 EventLoop关联的那个单线程Thread 上执行的。那么当S1作为客户端,再从其他服务器通信的时候,就可以共用这个 EventLoop。因为客户端其实就只要一个EventLoop就好了。
代码举例:
比如下面这个代码是在S1 作为服务端的时候,在 客户端 处于活动状态的时候调用的。这个方法其实是在workGroup里的一个EventLoop 的一个Thread 里执行的。 比如,此时我们要把数据发送到其他服务器,就直接共用这个EventLoop:: 创建 Bootstrap,然后group方法就指定 ctx.channel().eventLoop().
ctx.channel().eventLoop() 返回的是一个 NioEventLoop。
group方法需要的参数是EventLoopGroup类型。 NioEventLoop EventLoopGroup的子类, 所以可以这么传
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端" + ctx.channel().remoteAddress() + "处于活动状态了");
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(ctx.channel().eventLoop());
bootstrap.connect();
}