Netty框架中文編碼(二)
2023-04-12
netty實(shí)戰(zhàn)
- 1. 背景
- 2. 思路
- 3. 實(shí)現(xiàn)
- 4. 日志分析
- 5. 總結(jié)
1. 背景
我在上一篇文章中提到,假如針對老系統(tǒng)升級,面向的客戶端是不同的主體,并且因?yàn)楦鞣N原因出現(xiàn)了編碼不一致的問題(實(shí)際情況下很難出現(xiàn)的場景),那么我們該如何處理?之前我想到一種辦法是使用Nginx代理stream,但是經(jīng)過驗(yàn)證不可行。后邊我還有一種想法是通過程序來實(shí)現(xiàn),根據(jù)對端的IP來指定不同的編碼方式,采用配置化的方式實(shí)現(xiàn)。此種方式有待于進(jìn)一步學(xué)習(xí)動態(tài)handler來進(jìn)行驗(yàn)證。今天我就簡單記錄下實(shí)戰(zhàn)情況。
2. 思路
- 初始化initChannel時,先獲取客戶端IP
- 根據(jù)客戶端IP,動態(tài)實(shí)現(xiàn)不同編碼
3. 實(shí)現(xiàn)
- handler
public class CodeHandler extends ChannelInboundHandlerAdapter {
public static final Logger log = LoggerFactory.getLogger(CodeHandler.class);
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info("服務(wù)端接收消息是:{}", msg);
ctx.write(msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.info("exceptionCaught: " + cause.getLocalizedMessage());
}
}
- server
public class CodeServer {
public static final Logger log = LoggerFactory.getLogger(CodeServer.class);
private final String ip = "192.168.0.118";
private final String port = "8001";
public void init(){
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap bs = new ServerBootstrap();
bs.group(bossGroup, workerGroup);
bs.channel(NioServerSocketChannel.class);
bs.childHandler(new ChannelInitializer(){
@Override
protected void initChannel(Channel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new LoggingHandler(LogLevel.INFO));
String remoteAddress = ch.remoteAddress().toString();
log.info("遠(yuǎn)程地址:" + ch.remoteAddress().toString());
if (remoteAddress.contains("192.168.0.118")) {
log.info("UTF-8編碼");
pipeline.addLast(new StringDecoder(Charset.forName("UTF-8")));
pipeline.addLast(new StringEncoder(Charset.forName("UTF-8")));
} else {
log.info("GBK編碼");
pipeline.addLast(new StringDecoder(Charset.forName("GBK")));
pipeline.addLast(new StringEncoder(Charset.forName("GBK")));
}
log.info("添加業(yè)務(wù)handler");
pipeline.addLast(new CodeHandler());
}
});
try {
ChannelFuture channelFuture = bs.bind(ip, Integer.parseInt(port)).sync();
log.info("Netty Server 啟動成功! Ip: " + channelFuture.channel().localAddress().toString() + " ! ");
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
- 客戶端模擬單元測試
public class CodeClient {
public static final Logger log = LoggerFactory.getLogger(CodeClient.class);
public void connect(int port, String host) throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
final ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new LoggingHandler(LogLevel.INFO));
// 不同內(nèi)網(wǎng)機(jī)器,實(shí)驗(yàn)時靈活切換
// 比如192.168.0.118為UTF-8,192.168.0.105為GBK
//pipeline.addLast(new StringEncoder(Charset.forName("UTF-8")));
pipeline.addLast(new StringEncoder(Charset.forName("GBK")));
}
});
ChannelFuture future = bootstrap.connect("192.168.0.118", 8001).sync();
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
future.channel().writeAndFlush("你好");
}
});
future.syncUninterruptibly();
future.channel().closeFuture().sync();
}
public static void main(String[] args) throws InterruptedException {
new CodeClient().connect(8001, "192.168.0.118");
}
}
4. 日志分析
- 192.168.0.118日志記錄
可以看到后臺接收6B,為UTF-8編碼。
10:43:08.021 [nioEventLoopGroup-3-4] INFO com.ll.demo2.CodeServer - 遠(yuǎn)程地址:/192.168.0.118:5756
10:43:08.021 [nioEventLoopGroup-3-4] INFO com.ll.demo2.CodeServer - UTF-8編碼
10:43:08.021 [nioEventLoopGroup-3-4] INFO com.ll.demo2.CodeServer - 添加業(yè)務(wù)handler
10:43:08.022 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] REGISTERED
10:43:08.022 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] ACTIVE
10:43:08.053 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] READ: 6B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| e4 bd a0 e5 a5 bd |...... |
+--------+-------------------------------------------------+----------------+
10:43:08.053 [nioEventLoopGroup-3-4] INFO com.ll.demo2.CodeHandler - 服務(wù)端接收消息是:你好
10:43:08.054 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] WRITE: 6B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| e4 bd a0 e5 a5 bd |...... |
+--------+-------------------------------------------------+----------------+
10:43:08.054 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] READ COMPLETE
10:43:08.054 [nioEventLoopGroup-3-4] INFO io.netty.handler.logging.LoggingHandler - [id: 0xbe4fd2ce, L:/192.168.0.118:8001 - R:/192.168.0.118:5756] FLUSH
- 192.168.0.105日志記錄
可以看到后臺接收4B,為GBK編碼。
10:41:54.537 [nioEventLoopGroup-3-3] INFO com.ll.demo2.CodeServer - 遠(yuǎn)程地址:/192.168.0.105:49630
10:41:54.537 [nioEventLoopGroup-3-3] INFO com.ll.demo2.CodeServer - GBK編碼
10:41:54.537 [nioEventLoopGroup-3-3] INFO com.ll.demo2.CodeServer - 添加業(yè)務(wù)handler
10:41:54.538 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] REGISTERED
10:41:54.538 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] ACTIVE
10:41:54.560 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] READ: 4B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| c4 e3 ba c3 |.... |
+--------+-------------------------------------------------+----------------+
10:41:54.560 [nioEventLoopGroup-3-3] INFO com.ll.demo2.CodeHandler - 服務(wù)端接收消息是:你好
10:41:54.561 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] WRITE: 4B
+-------------------------------------------------+
| 0 1 2 3 4 5 6 7 8 9 a b c d e f |
+--------+-------------------------------------------------+----------------+
|00000000| c4 e3 ba c3 |.... |
+--------+-------------------------------------------------+----------------+
10:41:54.561 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] READ COMPLETE
10:41:54.561 [nioEventLoopGroup-3-3] INFO io.netty.handler.logging.LoggingHandler - [id: 0x9da24e21, L:/192.168.0.118:8001 - R:/192.168.0.105:49630] FLUSH
5. 總結(jié)
日志對比之后,發(fā)現(xiàn)可以根據(jù)不同IP區(qū)分開,并且中文編解碼都正常。這樣就解決了面對不同客戶端主體的時候,可以進(jìn)行編碼的靈活配置了。
本文僅代表作者觀點(diǎn),版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請在文中注明來源及作者名字。
免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請及時與我們聯(lián)系進(jìn)行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com





