Netty实现长连接简单例子
来源:互联网 发布:微信转换淘宝链接 编辑:程序博客网 时间:2024/05/22 06:06
Netty实现长连接的简单例子
服务端
NettyServerBootstrap提供长连接服务
public class NettyServerBootstrap {private static final Log log = LogFactory.getLog(NettyServerBootstrap.class);private Integer port;private SocketChannel socketChannel;public NettyServerBootstrap(Integer port) throws Exception {this.port = port;bind(port);}public Integer getPort() {return port;}public void setPort(Integer port) {this.port = port;}public SocketChannel getSocketChannel() {return socketChannel;}public void setSocketChannel(SocketChannel socketChannel) {this.socketChannel = socketChannel;}private void bind(int serverPort) throws Exception {// 连接处理groupEventLoopGroup boss = new NioEventLoopGroup();// 事件处理groupEventLoopGroup worker = new NioEventLoopGroup();ServerBootstrap bootstrap = new ServerBootstrap();// 绑定处理groupbootstrap.group(boss, worker);bootstrap.channel(NioServerSocketChannel.class);// 保持连接数bootstrap.option(ChannelOption.SO_BACKLOG, 1024 * 1024);// 有数据立即发送bootstrap.option(ChannelOption.TCP_NODELAY, true);// 保持连接bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); // 处理新连接bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel sc) throws Exception {// 增加任务处理ChannelPipeline p = sc.pipeline();p.addLast(new MessageDecoder(), new MessageEncoder(), new NettyServerHandler()); }});ChannelFuture f = bootstrap.bind(serverPort).sync();if (f.isSuccess()) {log.info("long connection started success");} else {log.error("long connection started fail");}}}
启动服务,监听9999端口
public static void main(String[] args) {try {new NettyServerBootstrap(9999);} catch (Exception e) {e.printStackTrace();}}
定义客户端服务端通信协议,一下是一个简单的通信协议
协议分为header和body两部分,都是用网络字节序(BIG ENDIAN)
header{
magic 32bit; //校验用固定值0x0CAFFEE0
version 8bit; //版本号
type 8bit; //类型,请求或者响应
seq 32bit; //序号标记一对请求响应
length 32bit; //body长度
}
body{
}
根据通信协议,编写解码器和编码器
解码器MessageDecoder
public class MessageDecoder extends ByteToMessageDecoder {private static final int MAGIC_NUMBER = 0x0CAFFEE0;public MessageDecoder() {}@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {if (in.readableBytes() < 14) {return;}// 标记开始读取位置in.markReaderIndex();int magic_number = in.readInt();if (MAGIC_NUMBER != magic_number) {ctx.close();return;}@SuppressWarnings("unused")byte version = in.readByte();byte type = in.readByte();int squence = in.readInt();int length = in.readInt();if (length < 0) {ctx.close();return;}if (in.readableBytes() < length) {// 重置到开始读取位置in.resetReaderIndex();return;}byte[] body = new byte[length];in.readBytes(body);RequestInfoVO req = new RequestInfoVO();req.setBody(new String(body, "utf-8"));req.setType(type);req.setSequence(squence);out.add(req);}}
编码器MessageEncoder
public class MessageEncoder extends MessageToByteEncoder<RequestInfoVO> {private static final String DEFAULT_ENCODE = "utf-8";private static final int MAGIC_NUMBER = 0x0CAFFEE0;public MessageEncoder() {}@Overrideprotected void encode(ChannelHandlerContext ctx, RequestInfoVO msg, ByteBuf out) throws Exception {@SuppressWarnings("resource")ByteBufOutputStream writer = new ByteBufOutputStream(out);byte[] body = null;if (null != msg && null != msg.getBody() && "" != msg.getBody()) {body = msg.getBody().getBytes(DEFAULT_ENCODE);}writer.writeInt(MAGIC_NUMBER);writer.writeByte(1);writer.writeByte(msg.getType());writer.writeInt(msg.getSequence());if (null == body || 0 == body.length) {writer.writeInt(0);} else {writer.writeInt(body.length);writer.write(body);}}}
服务端事件处理NettyServerHandler
@Sharablepublic class NettyServerHandler extends SimpleChannelInboundHandler<RequestInfoVO> {private static final Log log = LogFactory.getLog(NettyServerHandler.class);@Overrideprotected void channelRead0(ChannelHandlerContext ctx, RequestInfoVO msg) throws Exception {//}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {}@Overridepublic void channelUnregistered(ChannelHandlerContext ctx) throws Exception {}}
客户端
NettyClientBootstrap连接长连接服务
public class NettyClientBootstrap {private int port;private String host;private SocketChannel socketChannel;public NettyClientBootstrap(int port, String host) throws Exception {this.host = host;this.port = port;start();}private void start() throws Exception {EventLoopGroup eventLoopGroup = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();bootstrap.channel(NioSocketChannel.class);bootstrap.option(ChannelOption.SO_KEEPALIVE, true);bootstrap.option(ChannelOption.TCP_NODELAY, true);bootstrap.group(eventLoopGroup);bootstrap.remoteAddress(this.host, this.port);bootstrap.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {socketChannel.pipeline().addLast(new MessageDecoder(), new MessageEncoder(), new NettyClientHandler());}});ChannelFuture future = bootstrap.connect(this.host, this.port).sync();if (future.isSuccess()) {socketChannel = (SocketChannel) future.channel();System.out.println("connect server success|");}}public int getPort() {return this.port;}public void setPort(int port) {this.port = port;}public SocketChannel getSocketChannel() {return socketChannel;}public void setSocketChannel(SocketChannel socketChannel) {this.socketChannel = socketChannel;}public String getHost() {return host;}public void setHost(String host) {this.host = host;}}
初始化客户端
public static void main(String[] args) throws Exception {NettyClientBootstrap bootstrap = new NettyClientBootstrap(9999, "127.0.0.1");int i = 1;while (true) {TimeUnit.SECONDS.sleep(2);RequestInfoVO req = new RequestInfoVO();req.setSequence(123456);req.setType((byte) 1);req.setSequence(0);req.setBody(String.valueOf((new Date()).getTime()));bootstrap.getSocketChannel().writeAndFlush(req);i++;}}
根据协议编写编码器,解码器,同服务端编码器、解码器
客户端事件处理
public class NettyClientHandler extends SimpleChannelInboundHandler<RequestInfoVO> {@Overrideprotected void messageReceived(ChannelHandlerContext ctx, RequestInfoVO msg) throws Exception {System.out.println(msg.getBody());RequestInfoVO req = new RequestInfoVO();req.setSequence(msg.getSequence());req.setType(msg.getType());if (2 == msg.getType()) {req.setBody("client");ctx.channel().writeAndFlush(req);} else if (3 == msg.getType()) {req.setBody("zpksb");ctx.channel().writeAndFlush(req);}}}
至此,实现了简单的客户端服务端长连接。
阅读全文
0 0
- Netty实现长连接简单例子
- Java Netty长连接实现Android推送
- netty 5实现长连接心跳检测
- Netty 长连接服务
- Netty 长连接服务
- netty长连接实例
- Netty 长连接服务
- Netty 长连接服务
- Netty 长连接服务
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- Netty实现服务端客户端长连接通讯及心跳检测
- netty实现tcp长连接和心跳检测
- Netty长连接测试,参数设置
- 简单的,基于长连接的小例子
- 基于Netty的服务端长连接
- Netty-WebSocket长连接推送服务
- Netty-WebSocket长连接推送服务
- leetcode题解c++ | 76. Minimum Window Substring
- 数据结构与算法1.概念及术语
- Nginx安装
- 栈的应用之表达式求值(二)
- C# WinForm 中 MessageBox的使用详解
- Netty实现长连接简单例子
- 【Android实测】WebView的JS注入
- Android 在Service中弹出窗口及SYSTEM_ALERT_WINDOW权限解决方法
- LeetCode 169. Majority Element
- 343. Integer Break 题解
- HTML 颜色色号
- hdu3613(Manacher)
- 不能将CSV复制到postgreSQL表中:列不接受空字符串
- document常用方法