前段时间有个小项目, 项目中有用Netty框架写长连接, 设置编解码
new StringDecoder(Charset.forName("UTF-8"))
有各种问题, 比如接收不完整数据, 直接拼接字符串会出现乱码的问题.
如果接收不完整数据, 设置编解码只能是
new ByteArrayDecoder()
这样即便拆分, 在网络传输中也是byte字节. 把字节拼接起来, 然后转义成字符串, 再做判断.
由于对Netty框架不熟悉, 大家如果有好的建议, 请多指点, 谢谢.
上菜~~~~
public class NettySocketClient {
private Bootstrap mBootstrap;
private NioEventLoopGroup mNioEventLoopGroup;
private ByteArrayOutputStream mByteCache = new ByteArrayOutputStream();
private void init() {
if (mBootstrap == null) {
mBootstrap = new Bootstrap();
mNioEventLoopGroup = new NioEventLoopGroup();
mBootstrap.group(mNioEventLoopGroup);
mBootstrap.channel(NioSocketChannel.class);
mBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
mBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000);
mBootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel socketChannel)
throws Exception {
socketChannel.pipeline()
.addLast("decoder", new ByteArrayDecoder())
.addLast("encoder", new ByteArrayDecoder())
.addLast("handler", new CustomSimpleChannelInboundHandler());
}
});
}
}
public void connect() {
try {
init();
mBootstrap.connect(ip, port).sync().channel();
} catch (Exception e) {
e.printStackTrace();
}
}
public void disConnect() {
if (mNioEventLoopGroup != null) {
mNioEventLoopGroup.shutdownGracefully();
}
if (mByteCache != null) {
try {
mByteCache.close();
mByteCache = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class CustomSimpleChannelInboundHandler extends SimpleChannelInboundHandler {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
log("channelActive...");
...
resetByteCache();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object data) throws Exception {
log("channelRead... ");
if (data == null)
return;
byte[] buffer = (byte[]) data;
mByteCache.write(buffer, 0, buffer.length);
String resultStr = mByteCache.toString("UTF-8");
log("channelRead...resultStr : " + resultStr);
if (checkJsonStr(resultStr)) {
resetByteCache();
...
}
}
@Override
protected void messageReceived(ChannelHandlerContext channelHandlerContext, Object data) throws Exception {
log("messageReceived data : " + data);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log("channelInactive ..................");
resetByteCache();
...
super.channelInactive(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
resetByteCache();
log("exceptionCaught----");
}
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
log("channelReadComplete----");
}
}
private boolean checkJsonStr(String str) {
boolean flag = true;
try {
new JSONObject(str);
} catch (Exception e) {
flag = false;
}
return flag;
}
private void resetByteCache() {
if (mByteCache != null) {
mByteCache.reset();
}
}
}
随手mark~~~