摘要:結構作為服務端作為序列化數據的協議前端通訊演示地址服務端實現啟動類長連接示例主線程組從線程組請求的解碼和編碼把多個消息轉換為一個單一的或是,原因是解碼器會在每個消息中生成多個消息對象主要用于處理大數據流,比如一個大小的文件如果你直接傳輸肯定
結構
netty 作為服務端
protobuf 作為序列化數據的協議
websocket 前端通訊
演示GitHub 地址netty 服務端實現
Server.java 啟動類
import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import java.net.InetSocketAddress; //websocket長連接示例 public class Server { public static void main(String[] args) throws Exception{ // 主線程組 EventLoopGroup bossGroup = new NioEventLoopGroup(); // 從線程組 EventLoopGroup wokerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup,wokerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ServerChannelInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); wokerGroup.shutdownGracefully(); } } }
ServerChannelInitializer.java
import com.example.nettydemo.protobuf.MessageData; import com.google.protobuf.MessageLite; import com.google.protobuf.MessageLiteOrBuilder; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.stream.ChunkedWriteHandler; import java.util.List; import static io.netty.buffer.Unpooled.wrappedBuffer; public class ServerChannelInitializer extends ChannelInitializer{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // HTTP請求的解碼和編碼 pipeline.addLast(new HttpServerCodec()); // 把多個消息轉換為一個單一的FullHttpRequest或是FullHttpResponse, // 原因是HTTP解碼器會在每個HTTP消息中生成多個消息對象HttpRequest/HttpResponse,HttpContent,LastHttpContent pipeline.addLast(new HttpObjectAggregator(65536)); // 主要用于處理大數據流,比如一個1G大小的文件如果你直接傳輸肯定會撐暴jvm內存的; 增加之后就不用考慮這個問題了 pipeline.addLast(new ChunkedWriteHandler()); // WebSocket數據壓縮 pipeline.addLast(new WebSocketServerCompressionHandler()); // 協議包長度限制 pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true)); // 協議包解碼 pipeline.addLast(new MessageToMessageDecoder () { @Override protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List
ServerFrameHandler.java
import com.example.nettydemo.protobuf.MessageData; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.util.concurrent.GlobalEventExecutor; import java.util.List; //處理文本協議數據,處理TextWebSocketFrame類型的數據,websocket專門處理文本的frame就是TextWebSocketFrame public class ServerFrameHandler extends SimpleChannelInboundHandlerprotobuf 文件的使用{ private final ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); //讀到客戶端的內容并且向客戶端去寫內容 @Override protected void channelRead0(ChannelHandlerContext ctx, MessageData.RequestUser msg) throws Exception { // channelGroup.add(); Channel channel = ctx.channel(); System.out.println(msg.getUserName()); System.out.println(msg.getAge()); System.out.println(msg.getPassword()); MessageData.ResponseUser bank = MessageData .ResponseUser.newBuilder() .setUserName("你好,請問有什么可以幫助你!") .setAge(18).setPassword("11111").build(); channel.writeAndFlush(bank); } //每個channel都有一個唯一的id值 @Override public void handlerAdded(ChannelHandlerContext ctx) throws Exception { //打印出channel唯一值,asLongText方法是channel的id的全名 // System.out.println("handlerAdded:"+ctx.channel().id().asLongText()); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { // System.out.println("handlerRemoved:" + ctx.channel().id().asLongText()); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("異常發生"); ctx.close(); } }
proto 文件
syntax ="proto2"; package com.example.nettydemo.protobuf; //optimize_for 加快解析的速度 option optimize_for = SPEED; option java_package = "com.example.nettydemo.protobuf"; option java_outer_classname="MessageData"; // 客戶端發送過來的消息實體 message RequestUser{ optional string user_name = 1; optional int32 age = 2; optional string password = 3; } // 返回給客戶端的消息實體 message ResponseUser{ optional string user_name = 1; optional int32 age = 2; optional string password = 3; }生成 proto 的Java 類
批量生成工具,直接找到這個 bat 或者 sh 文件,在對應的平臺執行就可以了具體可以自行百度 protobuf 怎么使用
Windows 版本
set outPath=../../java set fileArray=(MessageDataProto ATestProto) # 將.proto文件生成java類 for %%i in %fileArray% do ( echo generate cli protocol java code: %%i.proto protoc --java_out=%outPath% ./%%i.proto ) pause
sh 版本 地址: https://github.com/lmxdawn/ne...
#!/bin/bash outPath=../../java fileArray=(MessageDataProto ATestProto) for i in ${fileArray[@]}; do echo "generate cli protocol java code: ${i}.proto" protoc --java_out=$outPath ./$i.proto donewebsocket 實現
擴展閱讀WebSocket客戶端 歡迎訪問客服系統
spring boot 實現的后臺管理系統
vue + element-ui 實現的后臺管理界面,接入 spring boot API接口
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72801.html
摘要:結構作為服務端作為序列化數據的協議前端通訊演示地址服務端實現啟動類長連接示例主線程組從線程組請求的解碼和編碼把多個消息轉換為一個單一的或是,原因是解碼器會在每個消息中生成多個消息對象主要用于處理大數據流,比如一個大小的文件如果你直接傳輸肯定 結構 netty 作為服務端 protobuf 作為序列化數據的協議 websocket 前端通訊 演示 GitHub 地址 showImg(...
摘要:當用戶注銷或退出時,釋放連接,清空對象中的登錄狀態。聊天管理模塊系統的核心模塊,這部分主要使用框架實現,功能包括信息文件的單條和多條發送,也支持表情發送。描述讀取完連接的消息后,對消息進行處理。 0.前言 最近一段時間在學習Netty網絡框架,又趁著計算機網絡的課程設計,決定以Netty為核心,以WebSocket為應用層通信協議做一個互聯網聊天系統,整體而言就像微信網頁版一樣,但考慮...
摘要:是一個面向字節流的協議,它是性質是流式的,所以它并沒有分段。可基于分隔符解決。編解碼的主要目的就是為了可以編碼成字節流用于在網絡中傳輸持久化存儲。 showImg(https://segmentfault.com/img/remote/1460000015895049); 前言 記得前段時間我們生產上的一個網關出現了故障。 這個網關邏輯非常簡單,就是接收客戶端的請求然后解析報文最后發送...
閱讀 928·2023-04-26 01:34
閱讀 3363·2023-04-25 20:58
閱讀 3286·2021-11-08 13:22
閱讀 2117·2019-08-30 14:17
閱讀 2526·2019-08-29 15:27
閱讀 2679·2019-08-29 12:45
閱讀 3003·2019-08-29 12:26
閱讀 2816·2019-08-28 17:51