首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

netty的个人施用心得【转】

2012-10-09 
netty的个人使用心得【转】Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序

netty的个人使用心得【转】

Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

?

如果需要客户端和服务器端沟通 分别都需要编写一个 实现了SimpleChannelHandler接口的类,其中类中需要重写的主要方法为

channelConnected()?and channelOpen()? 这两个方法为? 当客户端链接到服务器端得时候和 客户端 channel被创建出来的时候所调用的

?

channelDisconnected?and ?channelClosed() 对应上面的两个方法

?

exceptionCaught 可以获得 对应handler端(服务器或客户端)的异常信息

?

messageReceived?每个 客户端 发送的信息后? 将调用此方法

?

当编写完某端得程序后(客户端或服务器端) 将编写好的handler需要配置在 实现了ChannelPipelineFactory的类里,ChannelPipelineFactory中有一个需要实现的方法getPipeline将写好的handler配置到其中,在这个 工厂里 可能要添加很多东西

比如说 编解码器,心跳等。。。。

?

如需要自定义编解码器需要继承:LengthFieldBasedFrameDecoder(解码),OneToOneEncoder(编码)

?

编解码器(encode,decode)

encode为? 调用messageReceived?方法之后调用的方法,则decode方法为 messageReceived?之前调用的方法 ,用于处理自定义包协议的解析于编辑

?

心跳: 当客户端socket在非正常情况家掉线,如: 断网,断电等特殊问题的时候, 客户端的channel对象不会自动关闭,需要一直接收到客户端的消息,从而判断是否可以和对象构成通信。。 如果 发现客户端空闲时间过长则视为掉线

?

?

?

服务端handler代码如下

?

package com.djyou.server;

import java.util.logging.Logger;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ChildChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;


public class ChatServerHandler extends SimpleChannelHandler{

?public static final ChannelGroup channelGroup = new DefaultChannelGroup();
?
?public int id;
?
?@Override
?public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
???throws Exception {
??System.out.println("进来一个");
?}

?@Override
?public void channelDisconnected(ChannelHandlerContext ctx,
???ChannelStateEvent e) throws Exception {
???super.channelDisconnected(ctx, e);
?}

?@Override
?public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
???throws Exception {
??Logger.getAnonymousLogger().info(e.getCause().getMessage());
??ctx.getChannel().close();
??// TODO Auto-generated method stub
??//super.exceptionCaught(ctx, e);
?}

?@Override
?public void childChannelClosed(ChannelHandlerContext ctx,
???ChildChannelStateEvent e) throws Exception {
??
??super.childChannelClosed(ctx, e);
?}

?@Override
?public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
???throws Exception {
??System.out.println(this.id++);
??
??//google protocol解码后返回为 ChannelBuffer类型
??if(!(e.getMessage() instanceof ChannelBuffer)) return;
??//获得 消息对象
??ChannelBuffer channelBuffer = (ChannelBuffer)e.getMessage();
??
??//MessageInfo info = Message.MessageInfo.newBuilder().mergeFrom(channelBuffer.copy().array()).build();
??//写回给客户端
??e.getChannel().write(channelBuffer);
??
??
?}
?
?
}

?

pieplelineFactory里的代码为

?

package com.djyou.server;
import static org.jboss.netty.channel.Channels.*;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;

public class ChatPipelineServerFactory implements ChannelPipelineFactory{
?
?private Timer timer;
?
?public ChatPipelineServerFactory(Timer timer){
??
??this.timer = timer;
?}
?
?@Override
?public ChannelPipeline getPipeline() throws Exception {
??
??ChannelPipeline pipeline = pipeline();
??
??//添加netty默认支持的 编解码器(可自动添加包头,并处理粘包问题)

pipeline.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());//对应
?pipeline.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());//此对象为?netty默认支持protocolbuf的编解码器
????pipeline.addLast("timeout", new IdleStateHandler(timer, 10, 10, 0));//此两项为添加心跳机制 10秒查看一次在线的客户端channel是否空闲,IdleStateHandler为netty jar包中提供的类
??pipeline.addLast("hearbeat", new Heartbeat());//此类 实现了IdleStateAwareChannelHandler接口

? //netty会定时扫描 空闲的channel
??//pipeline.addLast("frameDecoder", new ProtobufDecoder(Message.MessageInfo.getDefaultInstance()));
??//pipeline.addLast("frameEncoder", new ProtobufEncoder());//
??pipeline.addLast("handler", new ChatServerHandler());//将编写好的服务器端的handler添加到这里?????????????
???????????? //创建 赋值结束的 Build? 并生成 MessageInfo对象
???????????? MessageInfo messageInfo = builder.build();
???????????? //将messageInfo转换为字节
???????????? byte[] messageByte = messageInfo.toByteArray();
?????????????
???????????? //获得此对象的长度
???????????? ChannelBuffer channelBuffer = ChannelBuffers.buffer(messageByte.length);
???????????? //将 获得到的数组写入 channelBuffer中
???????????? channelBuffer.writeBytes(messageByte);
???????????? //发送到服务器端
???????????? for(int i = 0; i < 10;i++){
???????????? lastWriteFuture = channel.write(channelBuffer);
???????????? }
???????????? if (lastWriteFuture != null) {
????????????? lastWriteFuture.awaitUninterruptibly();
????????? }
??????? // }
??????? //???? Thread.sleep(50000);
???????? // Wait until all messages are flushed before closing the channel.
????????
??????????? Thread.sleep(50000);
???????? // Close the connection.? Make sure the close operation ends because
???????? // all I/O operations are asynchronous in Netty.
???????? channel.close().awaitUninterruptibly();

???????? // We should shut down all thread pools here to exit normally.
???????? // However, it is just fine to call System.exit(0) because we are
???????? // finished with the business.
???????? System.exit(0);
?}
}

1 楼 yuqilin001 2012-06-09   要转别人的东西,请转清楚点嘛,少了这么多类,误人子弟 2 楼 zhaohaolin 2012-07-25   抱歉,兄弟,只是留下作记录,方便学习,如果觉得资料不好,可以到官网去看看,如有问题再联系

热点排行