Nettyは基本的にMinaよりずっと安定しています.
4902 ワード
プロジェクトにはチャットの機能があり、以前はminaを使っていたが、ずっとバグが解決されていなかった.それは断包、少包、粘包の問題だ.
グーグルは多くの文章を書いたが、残念ながら失敗に終わった.
この問題はおかしいから、処理してもだめだ.
以下の場合そのバグが発生します
第一に、クライアントがサーバと接続している間に、長い間長いメッセージ(心拍数がずっとある)を送信していない場合、突然長いjson文字列が送信されると、この問題が発生します.
第二に、クライアントが頻繁にサーバとデータ転送を行う場合、この問題も発生します.
元の文字列:
受信文字列:
あなたは間違っていないで、2回で受信して、1回目の受信の頭と尾、2回目の受信の中間、本当にわけがわからない.
後にNettyに変更されましたが、上手になりました.
netty-all-5.0.0を追加します.Alpha1.jarでいいです
まずサービスを起動して、注意して、必ずスレッドの中で起動して、しかしあなたの全体のプロジェクトに参加してただ1つの簡単なmainの方法だけあるならば、無視することができます
HttpHelloWorldServerInitializer.class
MyHandler.classは心拍数を遮断し、心拍数を送信する
HttpHelloWorldServerHandler.classは前のMyHandlerと同じです
大成功!メッセージの送信と受信は最後にしてください.
グーグルは多くの文章を書いたが、残念ながら失敗に終わった.
この問題はおかしいから、処理してもだめだ.
以下の場合そのバグが発生します
第一に、クライアントがサーバと接続している間に、長い間長いメッセージ(心拍数がずっとある)を送信していない場合、突然長いjson文字列が送信されると、この問題が発生します.
第二に、クライアントが頻繁にサーバとデータ転送を行う場合、この問題も発生します.
元の文字列:
{"message":{"content":"gghh ","msgid":"1413260146146","userlogo":"http:\/\/192.168.1."userlogo":"http:\/\/192.168.1.21:8888\/upload\/image\/201435\/e0feff917266411290f1.jpg","nickname":" ","msgtype":0,"receiverUid":"8",21:8888\/upload\/image\/201435\/e0feff917266411290f1.jpg","nickname":" ","msgtype":0,"receiverUid":"8","userid":"7","sendUid":"7","timel":0,"ctime":"2014-10-14 12:15:46"},"sendUid":"7","msgid":"1413260146146","cmd":"order_sendmessage","receiverUid":"8"}
受信文字列:
{"message":{"content":"gghh ","msgid":"1413260146146","userid":"7","sendUid":"7","timel":0,"ctime":"2014-10-14 12:15:46"},"sendUid":"7","msgid":"1413260146146","cmd":"order_sendmessage","receiverUid":"8"}
"userlogo":"http:\/\/192.168.1.21:8888\/upload\/image\/201435\/e0feff917266411290f1.jpg","nickname":" ","msgtype":0,"receiverUid":"8",
あなたは間違っていないで、2回で受信して、1回目の受信の頭と尾、2回目の受信の中間、本当にわけがわからない.
後にNettyに変更されましたが、上手になりました.
netty-all-5.0.0を追加します.Alpha1.jarでいいです
まずサービスを起動して、注意して、必ずスレッドの中で起動して、しかしあなたの全体のプロジェクトに参加してただ1つの簡単なmainの方法だけあるならば、無視することができます
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new HttpHelloWorldServerInitializer());
Channel ch = b.bind(SocketManage.WORDPORT).sync().channel();
ch.closeFuture().sync();
}catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
HttpHelloWorldServerInitializer.class
public class HttpHelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("timeout", new IdleStateHandler(60, 15, 0));//
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(
8192, Delimiters.lineDelimiter()));
pipeline.addLast("decoder", new StringDecoder(Charset.forName("utf-8")));
pipeline.addLast("encoder", new StringEncoder(Charset.forName("utf-8")));
pipeline.addLast("heartbeat", new MyHandler());//
pipeline.addLast("handler",new HttpHelloWorldServerHandler());//
}
}
MyHandler.classは心拍数を遮断し、心拍数を送信する
public class MyHandler extends SimpleChannelInboundHandler<String> {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if (e.state() == IdleState.READER_IDLE) {
// System.out.println("--- Reader Idle ---");
// ctx.close();
} else if (e.state() == IdleState.WRITER_IDLE) {
// System.out.println("--- Write Idle ---");
ctx.writeAndFlush("#
");
}
}
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, String str)
throws Exception {
if(str.equals("#")){
return;
}
ctx.fireChannelRead(str);// , HttpHelloWorldServerInitializer handelr,
}
}
HttpHelloWorldServerHandler.classは前のMyHandlerと同じです
public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, String str)
throws Exception {
//str ,
}
}
大成功!メッセージの送信と受信は最後にしてください.