本章实现功能为:客户端连接成功之后,向服务端发送数据,服务端接收到数据之后,向客户端返回一段数据。
客户端发送数据到服务端
之前提到过,处理业务逻辑是在handler中进行的,现在我们就添加一个 handler
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new FirstClientHandler());
}
});
向服务端发送数据的业务逻辑
public class FirstClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("客户端开始写出数据");
// 1.创建将要写出的数据
ByteBuf buffer = getByteBuf(ctx);
// 2.发送数据
ctx.channel().writeAndFlush(buffer);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
// byte类型的数据
byte[] bytes = "这里是将要写往服务端的数据".getBytes(Charset.forName("utf-8"));
// 申请一个数据结构存储信息
ByteBuf buffer = ctx.alloc().buffer();
// 将信息放入数据结构中
buffer.writeBytes(bytes);
return buffer;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println("客户端读到数据:" + byteBuf.toString(Charset.forName("utf-8")));
}
}
说明:
- 1.
ChannelInboundHandlerAdapter是实现了io.netty.channel.ChannelHandler这个接口的, 所有实现了该接口的handler都具有以下生命周期:
| 状态 | 描述 |
|---|---|
| ChannelUnregistered | channel已经创建,但还未注册到EventLoop |
| ChannelRegistered | channel已经被注册到了EventLoop |
| ChannelActive | channel处于连接到远程节点的状态,它现在可以接受和发送数据了 |
| ChannelInactive | channel没有连接到远程节点 |
- 2.这个
handler继承ChannelInboundHandlerAdapter,这个handler也有它附加的方法,其中channelRead指从channel读到数据时调用的方法。
服务端读取客户端数据
和客户端一样,添加一个处理业务逻辑的handler
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) {
ch.pipeline().addLast(new FirstServerHandler());
}
});
服务端接受客户端数据以及向客户端返回数据的业务逻辑
public class FirstServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println("服务端读到数据:" + byteBuf.toString(Charset.forName("utf-8")));
// 回复数据到客户端
System.out.println("服务端开始写出数据");
// 创建需要回复的数据
ByteBuf out = getByteBuf(ctx);
// 发送数据
ctx.channel().writeAndFlush(out);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
byte[] bytes = "这里是服务端将要写出发往客户端的数据".getBytes(Charset.forName("utf-8"));
// 申请一个数据结构存储信息
ByteBuf buffer = ctx.alloc().buffer();
// 将信息放入数据结构中
buffer.writeBytes(bytes);
return buffer;
}
}
参考资料
-
掘金小册《Netty 入门与实战:仿写微信 IM 即时通讯系统》
Github地址:link.juejin.im/?target=htt…
-
《Netty in action》
本文由 发给官兵 创作,采用 CC BY 3.0 CN协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出 处。如转载至微信公众号,请在文末添加作者公众号二维码。