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

@Sharable
public 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);}}}

至此,实现了简单的客户端服务端长连接。

Netty实现长连接简单例子相关推荐

  1. Netty 实现长连接服务的难点和优化点

    推送服务 还记得一年半前,做的一个项目需要用到 Android 推送服务.和 iOS 不同,Android 生态中没有统一的推送服务.Google 虽然有 Google Cloud Messaging ...

  2. SQL左连接,右连接,内连接简单例子

    SQL左连接,右连接,内连接简单例子 左连接:以左表为主 select column_a , column_b from table_a left join table_b on table_a.id ...

  3. Netty-案例 WebSocket与netty实现长连接案例(代码注释详解)

    Netty 记录学习,开心学习,来源尚硅谷韩顺平netty视频 1 NettyServer package com.fs.netty.simple;import io.netty.bootstrap. ...

  4. Http长连接的例子_亲测可用哦

    一.什么事Http长连接:在网上有很多很多关于Http长连接的文章,但是我看了很多都看不懂.自己总结的所谓的http长连接就是在一请求一个页面后,在服务器端不断开http连接,而是通过response ...

  5. 京东的Netty实践,京麦TCP网关长连接容器架构

    背景 早期京麦搭建 HTTP 和 TCP 长连接功能主要用于消息通知的推送,并未应用于 API 网关.随着逐步对 NIO 的深入学习和对 Netty 框架的了解,以及对系统通信稳定能力越来越高的要求, ...

  6. Netty 实现百万连接的难点和优化点

    推送服务 还记得一年半前,做的一个项目需要用到 Android 推送服务.和 iOS 不同,Android 生态中没有统一的推送服务.Google 虽然有 Google Cloud Messaging ...

  7. 移动互联网长连接方案实例

    1.笔者本人现在在一家创业公司担当整个平台架构的角色,而这家公司是做一移动互联网相关的一些应用产品,由其现在正在和中国最大的互联网公司之一进行合作,负责该互联网公司的手机终端的长连接推送服务,所以有一 ...

  8. websocket 长连接

    首先看一下什么是长连接,短连接 长连接的定义: 长连接 是一旦一个客户端登陆上服务器,其与服务器之间的连接就不关闭,不管他们之间进行了多少次交易,直到客户端退出登陆或网络出现故障.这种技术在联机交易系 ...

  9. atr netty长连接_基于Netty实现Web容器Netty版Tomcat(三)

    一首<感谢你曾经来过>,谢谢支持..... 本次所涉及代码已上传至GitHub:https://github.com/lgli/lgli-netty-tomcat/tree/master前 ...

最新文章

  1. 抓取apache2的进程pid
  2. 基于蚂蚁金服「如何管理好10万行代码」搭建了 Vue 项目架构
  3. DCMTK:类DcmUnsigned64bitVeryLong的测试程序
  4. 确认密码参数php,laravel unique验证、确认密码confirmed验证以及密码修改验证的方法...
  5. oracle raw类型 索引,为什么RAW数据类型可以建立索引,但是不走索引
  6. XML是什么,它能够做什么?——写给XML入门者
  7. linux ps用法大全,linux 性能篇 -- ps的用法
  8. leetcode每日刷题计划-简单篇day6
  9. SAS时间序列分析案例--有季节效应的非平稳序列分析
  10. 加密狗映射至虚拟服务器,XenServer6.x U盘、加密狗等USB设备映射到VM虚拟机教程.pdf...
  11. SpringBoot整合Redis_Jedis版(二十)
  12. delphi10.2 将网页页面带格式复制到word中。
  13. c语言帮助记忆单词的小程序,帮助记忆单词的书课堂活动微信小程序软件_速记背单词...
  14. Stream报错:stream has already been operated upon or closed
  15. 核心乐理---音程名称
  16. 使用 DBCA 命令 删除 Oracle 数据库
  17. 相伴十六载,讲讲我和数据仓库的故事(一)
  18. Python int基本用法
  19. 如何改变坏习惯,形成新习惯
  20. JavaScript中函数里的arguments属性

热门文章

  1. Html TextArea 长度限制
  2. IP得到天气预报(3)———XML中CDATA的提取
  3. GY39传感器C语言代码,详解Arduino GY-30数字光强传感器应用
  4. java easyui 分页_Spring mvc+easyui做列表展示及分页
  5. linux 查看安装的系统版本,linux之查看版本信息命令
  6. 分式混合运算20道题_FAG剖分式调心滚子轴承的性能
  7. 设计师分享社区,展示风采平台
  8. 设计师吃饭的家伙还问别人要?必要软件、效率工具、插件搜集给你
  9. 双十一要来了,设计没思路看看案例
  10. 干货分享|UI设计可临摹编辑的线框素材,还会觉得交互原型画得丑?