Nettyは基本的にMinaよりずっと安定しています.

4902 ワード

プロジェクトにはチャットの機能があり、以前はminaを使っていたが、ずっとバグが解決されていなかった.それは断包、少包、粘包の問題だ.
グーグルは多くの文章を書いたが、残念ながら失敗に終わった.
この問題はおかしいから、処理してもだめだ.
以下の場合そのバグが発生します
第一に、クライアントがサーバと接続している間に、長い間長いメッセージ(心拍数がずっとある)を送信していない場合、突然長い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     ,             
	}
	
}

大成功!メッセージの送信と受信は最後にしてください.