基于java nio netty websocket protobuf javascript等技术实现前后端高性能实时数据传输
基于java nio + netty + websocket + protobuf +javascript等技术实现前后端高性能实时数据传输的demo模型。
github地址:https://github.com/18438301593/NettyWebsocketProtoDemo
主要过程分析:
一、.proto文件编写,生成java类,以及javacript文件。
参考文章:
http://www.jiajiajia.club/blog/artical/351psy9r6l0g/464,
http://www.jiajiajia.club/blog/artical/ydn9dpg64gkf/466
二、集成websocket
websocket协议的建立连接的阶段采用了http协议的方式,所以会看到http协议相关的解码器和编码器。如下:
pipeline.addLast(new HttpServerCodec());
//支持写大数据流
pipeline.addLast(new ChunkedWriteHandler());
//http聚合器
pipeline.addLast(new HttpObjectAggregator(1024*62));
//websocket支持,设置路由
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
// 协议包解码
pipeline.addLast(new MessageToMessageDecoder<WebSocketFrame>() {
@Override
protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> objs) throws Exception {
System.out.println("received client msg ------------------------");
if (frame instanceof TextWebSocketFrame) {
// 文本消息
TextWebSocketFrame textFrame = (TextWebSocketFrame)frame;
System.out.println("MsgType is TextWebSocketFrame");
} else if (frame instanceof BinaryWebSocketFrame) {
// 二进制消息
ByteBuf buf = ((BinaryWebSocketFrame) frame).content();
objs.add(buf);
// 自旋累加
buf.retain();
System.out.println("MsgType is BinaryWebSocketFrame");
} else if (frame instanceof PongWebSocketFrame) {
// PING存活检测消息
System.out.println("MsgType is PongWebSocketFrame ");
} else if (frame instanceof CloseWebSocketFrame) {
// 关闭指令消息
System.out.println("MsgType is CloseWebSocketFrame");
channel.close();
}
}
});
三、 支持protobuf协议
主要配置解码器和编码器
//解码器,通过Google Protocol Buffers序列化框架动态的切割接收到的ByteBuf
pipeline.addLast(new ProtobufVarint32FrameDecoder());
//Google Protocol Buffers 长度属性编码器
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
// 协议包编码,编码成二进制数据,通过websocket发送
pipeline.addLast(new MessageToMessageEncoder<MessageLiteOrBuilder>() {
@Override
protected void encode(ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out) throws Exception {
ByteBuf result = null;
if (msg instanceof MessageLite) {
result = wrappedBuffer(((MessageLite) msg).toByteArray());
}
if (msg instanceof MessageLite.Builder) {
result = wrappedBuffer(((MessageLite.Builder) msg).build().toByteArray());
}
// 封装二进制数据
WebSocketFrame frame = new BinaryWebSocketFrame(result);
out.add(frame);
}
});
// protobuf解码器
channel.pipeline().addLast("decoder",new ProtobufDecoder(MyMessage.MyMessageInfo.getDefaultInstance()));
四、支持心跳检测,超时关闭连接
解码器配置
// 超时心跳检测
channel.pipeline().addLast(new IdleStateHandler(5,5,5, TimeUnit.SECONDS));
业务处理在NettyServerHandler类的userEventTriggered()方法。
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt)throws Exception{
System.out.println("::::"+evt);
if(evt instanceof IdleStateEvent){
IdleStateEvent event = (IdleStateEvent)evt;
String eventType = null;
switch (event.state()){
case READER_IDLE:
eventType = "读空闲";
readIdleTimes ++; // 读空闲的计数加1
break;
case WRITER_IDLE:
eventType = "写空闲";
// 不处理
break;
case ALL_IDLE:
eventType ="读写空闲";
// 不处理
break;
}
System.out.println(ctx.channel().remoteAddress() + "超时事件:" +eventType);
if(readIdleTimes > 3){
System.out.println(" [server]读空闲超过3次,关闭连接");
ctx.channel().close();
}
}
}
五、前端websocket接受到数据如何解析?
websocket是一帧一帧发送的,所以要读取所有数据,在转成字节数据,才能反序列化成js对象。
ws.onmessage = function (event) {
var reader = new FileReader();
reader.readAsArrayBuffer(event.data);
reader.onload = function (e) {
var buf = new Uint8Array(reader.result);
var j = proto.MyMessageInfo.deserializeBinary(buf);
var t = document.getElementById("message");
t.innerHTML = j.getName();
}
};
评论区
请写下您的评论...
猜你喜欢
official
1449
基于javanio+netty+websocket+protobuf+javascript等技术实现前后端高性能实时数据传输的demo模型。 github地址:https
official
1246
之前的文章介绍了protobuf的概念参考:http://www.jiajiajia.club/blog/artical/351psy9r6l0g/464以及protobuf的编码方式参考:http
official
1157
Websocket协议和http协议的关系websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过
official
1285
在上一节《一起学netty(6)》的文章中,简要说明了用nio原生代码写程序的一些不足和问题,以及netty在nio的基础上大致做了那些工作。其中提到一点就是当活跃客户端的数量太多,单线程处理时所带
official
1143
。ServiceSocketChannel本身不具备数据传输的能力,它只能监听新进来的TCP链接通道。当有新的TCP链接通道建立后,它会创建一个SocketChannel的对象,代表和客户端的唯一连接通道
blog
springmvc集成websocket
spring/springmvc
4101
springmvc集成websocket环境:spring+springmvc+tomcat8注意:本测试项目运行环境不能低于tomcat81.websocket配置
official
1294
在netty的包中,发现也有ServerSocketChannel和SocketChannel,以及NioServerSocketChannel和NioSocketChannel,概念上来说
算法基础
1459
自然结果也就是省电:因为大数据量的传输必然需要更久的网络操作、数据序列化及反序列化操作,这些都是电量消耗过快的根源。当前即时通讯应用中最热门的通信协议无疑就是Google的Protobuf了,基于它的优
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。