国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Springboot整合Netty,自定義協(xié)議實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了Springboot整合Netty,自定義協(xié)議實(shí)現(xiàn)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

Springboot整合Netty,自定義協(xié)議實(shí)現(xiàn)

Springboot整合Netty

新建springboot項(xiàng)目,并在項(xiàng)目以來中導(dǎo)入netty包,用fastjson包處理jsonStr。

        <!-- netty -->
 ? ? ? ?<dependency>
 ? ? ? ? ? ?<groupId>io.netty</groupId>
 ? ? ? ? ? ?<artifactId>netty-all</artifactId>
 ? ? ? ? ? ?<version>4.1.42.Final</version>
 ? ? ? ?</dependency>
?
 ? ? ? ?<!-- Json處理 -->
 ? ? ? ?<dependency>
 ? ? ? ? ? ?<groupId>com.alibaba.fastjson2</groupId>
 ? ? ? ? ? ?<artifactId>fastjson2</artifactId>
 ? ? ? ? ? ?<version>2.0.16</version>
 ? ? ? ?</dependency>

創(chuàng)建netty相關(guān)配置信息文件

  1. yml配置文件——application.yml

# netty 配置
netty:
 ?# boss線程數(shù)量
  boss: 4
 ?# worker線程數(shù)量
  worker: 2
 ?# 連接超時(shí)時(shí)間
  timeout: 6000
 ?# 服務(wù)器主端口
  port: 18023
 ?# 服務(wù)器備用端口
  portSalve: 18026
 ?# 服務(wù)器地址
  host: 127.0.0.1
  1. netty配置實(shí)體類——NettyProperties與yml配置文件綁定 通過@ConfigurationProperties(prefix = "netty")注解讀取配置文件中的netty配置,通過反射注入值,需要在實(shí)體類中提供對應(yīng)的setter和getter方法。

@ConfigurationProperties(prefix = "netty")對應(yīng)的實(shí)體類屬性名稱不要求一定相同,只需保證“set”字符串拼接配置文件的屬性和setter方法名相同即可。

@Configuration
@ConfigurationProperties(prefix = "netty")
public class NettyProperties {
?
 ? ?/**
 ? ? * boss線程數(shù)量
 ? ? */
 ? ?private Integer boss;
?
 ? ?/**
 ? ? * worker線程數(shù)量
 ? ? */
 ? ?private Integer worker;
?
 ? ?/**
 ? ? * 連接超時(shí)時(shí)間
 ? ? */
 ? ?private Integer timeout = 30000;
?
 ? ?/**
 ? ? * 服務(wù)器主端口
 ? ? */
 ? ?private Integer port = 18023;
?
 ? ?/**
 ? ? * 服務(wù)器備用端口
 ? ? */
 ? ?private Integer portSalve = 18026;
?
 ? ?/**
 ? ? * 服務(wù)器地址 默認(rèn)為本地
 ? ? */
 ? ?private String host = "127.0.0.1";
    
    // setter、getter 。。。。
}
  1. 對netty進(jìn)行配置,綁定netty相關(guān)配置設(shè)置 Netty通常由一個(gè)Bootstrap開始,主要作用是配置整個(gè)Netty程序,串聯(lián)各個(gè)組件,Netty中Bootstrap類是客戶端程序的啟動引導(dǎo)類,ServerBootstrap是服務(wù)端啟動引導(dǎo)類。

@Configuration
@EnableConfigurationProperties
public class NettyConfig {
 ? ?final NettyProperties nettyProperties;
?
 ? ?public NettyConfig(NettyProperties nettyProperties) {
 ? ? ? ?this.nettyProperties = nettyProperties;
 ?  }
?
 ? ?/**
 ? ? * boss線程池-進(jìn)行客戶端連接
 ? ? *
 ? ? * @return
 ? ? */
 ? ?@Bean
 ? ?public NioEventLoopGroup boosGroup() {
 ? ? ? ?return new NioEventLoopGroup(nettyProperties.getBoss());
 ?  }
?
 ? ?/**
 ? ? * worker線程池-進(jìn)行業(yè)務(wù)處理
 ? ? *
 ? ? * @return
 ? ? */
 ? ?@Bean
 ? ?public NioEventLoopGroup workerGroup() {
 ? ? ? ?return new NioEventLoopGroup(nettyProperties.getWorker());
 ?  }
?
 ? ?/**
 ? ? * 服務(wù)端啟動器,監(jiān)聽客戶端連接
 ? ? *
 ? ? * @return
 ? ? */
 ? ?@Bean
 ? ?public ServerBootstrap serverBootstrap() {
 ? ? ? ?ServerBootstrap serverBootstrap = new ServerBootstrap()
 ? ? ? ? ? ? ? ?// 指定使用的線程組
 ? ? ? ? ? ? ?  .group(boosGroup(), workerGroup())
 ? ? ? ? ? ? ? ?// 指定使用的通道
 ? ? ? ? ? ? ?  .channel(NioServerSocketChannel.class)
 ? ? ? ? ? ? ? ?// 指定連接超時(shí)時(shí)間
 ? ? ? ? ? ? ?  .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyProperties.getTimeout())
 ? ? ? ? ? ? ? ?// 指定worker處理器
 ? ? ? ? ? ? ?  .childHandler(new NettyServerHandler());
 ? ? ? ?return serverBootstrap;
 ?  }
}
  1. worker處理器,初始化通道以及配置對應(yīng)管道的處理器 自定義了##@##分割符,通過DelimiterBasedFrameDecoder來處理拆包沾包問題; 通過MessageDecodeHandler將接收消息解碼處理成對象實(shí)例; 通過MessageEncodeHandler將發(fā)送消息增加分割符后并編碼; 最后通過ServerListenerHandler根據(jù)消息類型對應(yīng)處理不同消息。

public class NettyServerHandler extends ChannelInitializer<SocketChannel> {
 ? ?@Override
 ? ?protected void initChannel(SocketChannel socketChannel) throws Exception {
 ? ? ? ?// 數(shù)據(jù)分割符
 ? ? ? ?String delimiterStr = "##@##";
 ? ? ? ?ByteBuf delimiter = Unpooled.copiedBuffer(delimiterStr.getBytes());
 ? ? ? ?ChannelPipeline pipeline = socketChannel.pipeline();
 ? ? ? ?// 使用自定義處理拆包/沾包,并且每次查找的最大長度為1024字節(jié)
 ? ? ? ?pipeline.addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
 ? ? ? ?// 將上一步解碼后的數(shù)據(jù)轉(zhuǎn)碼為Message實(shí)例
 ? ? ? ?pipeline.addLast(new MessageDecodeHandler());
 ? ? ? ?// 對發(fā)送客戶端的數(shù)據(jù)進(jìn)行編碼,并添加數(shù)據(jù)分隔符
 ? ? ? ?pipeline.addLast(new MessageEncodeHandler(delimiterStr));
 ? ? ? ?// 對數(shù)據(jù)進(jìn)行最終處理
 ? ? ? ?pipeline.addLast(new ServerListenerHandler());
 ?  }
}
  1. 數(shù)據(jù)解碼 數(shù)據(jù)解碼和編碼都采用UTF8格式

public class MessageDecodeHandler extends ByteToMessageDecoder {
?
 ? ?@Override
 ? ?protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> list) throws Exception {
 ? ? ? ?ByteBuf frame = in.retainedDuplicate();
 ? ? ? ?final String content = frame.toString(CharsetUtil.UTF_8);
 ? ? ? ?Message message = new Message(content);
 ? ? ? ?list.add(message);
 ? ? ? ?in.skipBytes(in.readableBytes());
 ?  }
}
  1. 數(shù)據(jù)解碼轉(zhuǎn)換的實(shí)例 Message類用于承載消息、轉(zhuǎn)JsonString

public class Message {
 ? ?/**
 ? ? * 數(shù)據(jù)長度
 ? ? */
 ? ?private Integer len;
?
 ? ?/**
 ? ? * 接收的通訊數(shù)據(jù)body
 ? ? */
 ? ?private String content;
?
 ? ?/**
 ? ? * 消息類型
 ? ? */
 ? ?private Integer msgType;
?
 ? ?public Message(Object object) {
 ? ? ? ?String str = object.toString();
 ? ? ? ?JSONObject jsonObject = JSONObject.parseObject(str);
 ? ? ? ?msgType = Integer.valueOf(jsonObject.getString("msg_type"));
 ? ? ? ?content = jsonObject.getString("body");
 ? ? ? ?len = str.length();
 ?  }
?
 ? ?public String toJsonString() {
 ? ? ? ?return "{" +
 ? ? ? ? ? ? ? ?"\"msg_type\": " + msgType + ",\n" +
 ? ? ? ? ? ? ? ?"\"body\": " + content +
 ? ? ? ? ? ? ? ?"}";
 ?  }
    // setter、getter 。。。。
}
  1. 數(shù)據(jù)編碼 netty服務(wù)端回復(fù)消息時(shí),對消息轉(zhuǎn)JsonString增加分割符,并進(jìn)行編碼。

public class MessageEncodeHandler extends MessageToByteEncoder<Message> {
 ? ?// 數(shù)據(jù)分割符
 ? ?String delimiter;
?
 ? ?public MessageEncodeHandler(String delimiter) {
 ? ? ? ?this.delimiter = delimiter;
 ?  }
?
 ? ?@Override
 ? ?protected void encode(ChannelHandlerContext channelHandlerContext, Message message, ByteBuf out) throws Exception {
 ? ? ? ?out.writeBytes((message.toJsonString() + delimiter).getBytes(CharsetUtil.UTF_8));
 ?  }
}
  1. 數(shù)據(jù)處理器,針對不同類型數(shù)據(jù)分類處理 在處理不同接收數(shù)據(jù)時(shí)使用了枚舉類型,在使用switch時(shí)可以做下處理,具體參考代碼,這里只演示如何操作,并沒實(shí)現(xiàn)數(shù)據(jù)處理業(yè)務(wù)類。

public class ServerListenerHandler extends SimpleChannelInboundHandler<Message> {
 ? ?private static final Logger log = LoggerFactory.getLogger(ServerListenerHandler.class);
?
 ? ?/**
 ? ? * 設(shè)備接入連接時(shí)處理
 ? ? *
 ? ? * @param ctx
 ? ? */
 ? ?@Override
 ? ?public void handlerAdded(ChannelHandlerContext ctx) {
 ? ? ? ?log.info("有新的連接:[{}]", ctx.channel().id().asLongText());
 ?  }
?
 ? ?/**
 ? ? * 數(shù)據(jù)處理
 ? ? *
 ? ? * @param ctx
 ? ? * @param msg
 ? ? */
 ? ?@Override
 ? ?protected void channelRead0(ChannelHandlerContext ctx, Message msg) {
 ? ? ? ?// 獲取消息實(shí)例中的消息體
 ? ? ? ?String content = msg.getContent();
 ? ? ? ?// 對不同消息類型進(jìn)行處理
 ? ? ? ?MessageEnum type = MessageEnum.getStructureEnum(msg);
 ? ? ? ?switch (type) {
 ? ? ? ? ? ?case CONNECT:
 ? ? ? ? ? ? ? ?// TODO 心跳消息處理
 ? ? ? ? ? ?case STATE:
 ? ? ? ? ? ? ? ?// TODO 設(shè)備狀態(tài)
 ? ? ? ? ? ?default:
 ? ? ? ? ? ? ? ?System.out.println(type.content + "消息內(nèi)容" + content);
 ? ? ?  }
 ?  }
?
 ? ?/**
 ? ? * 設(shè)備下線處理
 ? ? *
 ? ? * @param ctx
 ? ? */
 ? ?@Override
 ? ?public void handlerRemoved(ChannelHandlerContext ctx) {
 ? ? ? ?log.info("設(shè)備下線了:{}", ctx.channel().id().asLongText());
 ?  }
?
 ? ?/**
 ? ? * 設(shè)備連接異常處理
 ? ? *
 ? ? * @param ctx
 ? ? * @param cause
 ? ? */
 ? ?@Override
 ? ?public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
 ? ? ? ?// 打印異常
 ? ? ? ?log.info("異常:{}", cause.getMessage());
 ? ? ? ?// 關(guān)閉連接
 ? ? ? ?ctx.close();
 ?  }
}
  1. 數(shù)據(jù)類型枚舉類

public enum MessageEnum {
 ? ?CONNECT(1, "心跳消息"),
 ? ?STATE(2, "設(shè)備狀態(tài)");
?
 ? ?public final Integer type;
 ? ?public final String content;
?
 ? ?MessageEnum(Integer type, String content) {
 ? ? ? ?this.type = type;
 ? ? ? ?this.content = content;
 ?  }
?
 ? ?// case中判斷使用
 ? ?public static MessageEnum getStructureEnum(Message msg) {
 ? ? ? ?Integer type = Optional.ofNullable(msg)
 ? ? ? ? ? ? ?  .map(Message::getMsgType)
 ? ? ? ? ? ? ?  .orElse(0);
 ? ? ? ?if (type == 0) {
 ? ? ? ? ? ?return null;
 ? ? ?  } else {
 ? ? ? ? ? ?List<MessageEnum> objectEnums = Arrays.stream(MessageEnum.values())
 ? ? ? ? ? ? ? ? ?  .filter((item) -> item.getType() == type)
 ? ? ? ? ? ? ? ? ?  .distinct()
 ? ? ? ? ? ? ? ? ?  .collect(Collectors.toList());
 ? ? ? ? ? ?if (objectEnums.size() > 0) {
 ? ? ? ? ? ? ? ?return objectEnums.get(0);
 ? ? ? ? ?  }
 ? ? ? ? ? ?return null;
 ? ? ?  }
 ?  }
    // setter、getter。。。。
}

到此Netty整個(gè)配置已經(jīng)完成,但如果要跟隨springboot一起啟動,仍需要做一些配置。

  1. netty啟動類配置

@Component
public class NettyServerBoot {
 ? ?private static final Logger log = LoggerFactory.getLogger(NettyServerBoot.class);
 ? ?@Resource
 ? ?NioEventLoopGroup boosGroup;
 ? ?@Resource
 ? ?NioEventLoopGroup workerGroup;
 ? ?final ServerBootstrap serverBootstrap;
 ? ?final NettyProperties nettyProperties;
?
 ? ?public NettyServerBoot(ServerBootstrap serverBootstrap, NettyProperties nettyProperties) {
 ? ? ? ?this.serverBootstrap = serverBootstrap;
 ? ? ? ?this.nettyProperties = nettyProperties;
 ?  }
?
?
 ? ?/**
 ? ? * 啟動netty
 ? ? *
 ? ? * @throws InterruptedException
 ? ? */
 ? ?@PostConstruct
 ? ?public void start() throws InterruptedException {
 ? ? ? ?// 綁定端口啟動
 ? ? ? ?serverBootstrap.bind(nettyProperties.getPort()).sync();
 ? ? ? ?// 備用端口
 ? ? ? ?serverBootstrap.bind(nettyProperties.getPortSalve()).sync();
 ? ? ? ?log.info("啟動Netty: {},{}", nettyProperties.getPort(), nettyProperties.getPortSalve());
 ?  }
?
 ? ?/**
 ? ? * 關(guān)閉netty
 ? ? */
 ? ?@PreDestroy
 ? ?public void close() {
 ? ? ? ?log.info("關(guān)閉Netty");
 ? ? ? ?boosGroup.shutdownGracefully();
 ? ? ? ?workerGroup.shutdownGracefully();
 ?  }
}

增加NettyServerBoot配置后,啟動application時(shí),netty服務(wù)端會跟隨一起啟動。 springboot整合netty框架,編程學(xué)習(xí),算法,java,開發(fā)語言,后端,spring boot

同時(shí),在springboot關(guān)閉前,會先銷毀netty服務(wù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-735954.html

到了這里,關(guān)于Springboot整合Netty,自定義協(xié)議實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • netty學(xué)習(xí)(3):SpringBoot整合netty實(shí)現(xiàn)多個(gè)客戶端與服務(wù)器通信

    netty學(xué)習(xí)(3):SpringBoot整合netty實(shí)現(xiàn)多個(gè)客戶端與服務(wù)器通信

    創(chuàng)建一個(gè)SpringBoot工程,然后創(chuàng)建三個(gè)子模塊 整體工程目錄:一個(gè)server服務(wù)(netty服務(wù)器),兩個(gè)client服務(wù)(netty客戶端) pom文件引入netty依賴,springboot依賴 NettySpringBootApplication NettyServiceHandler SocketInitializer NettyServer NettyStartListener application.yml Client1 NettyClientHandler SocketInitializ

    2024年02月11日
    瀏覽(56)
  • SpringBoot整合Netty

    SpringBoot整合Netty

    簡介 Netty是一個(gè)基于Java的開源網(wǎng)絡(luò)應(yīng)用框架,它提供了高性能、異步事件驅(qū)動的網(wǎng)絡(luò)編程能力。Netty旨在幫助開發(fā)者構(gòu)建高性能、高可靠性的網(wǎng)絡(luò)應(yīng)用程序。 Netty提供了簡潔的API和豐富的功能,可以輕松處理各種網(wǎng)絡(luò)通信協(xié)議,如TCP、UDP、WebSocket等。它的設(shè)計(jì)理念是基于事件

    2024年02月08日
    瀏覽(19)
  • springboot整合netty的正確姿勢

    近期做一些物聯(lián)網(wǎng)方面項(xiàng)目,使用到了tcp協(xié)議,之前公司做過socket短連接,網(wǎng)上找了一個(gè)簡單的demo,很早便學(xué)習(xí)到nio方面知識,學(xué)習(xí)了《netty從入門到精通》這本書,同時(shí)也根據(jù)網(wǎng)上視頻做了幾個(gè)demo,但學(xué)習(xí)不太深入,剛好物聯(lián)網(wǎng)項(xiàng)目,就直接使用netty,前期直接使用這個(gè)框

    2024年02月05日
    瀏覽(24)
  • 日常記錄-SpringBoot整合netty-socketio

    日常記錄-SpringBoot整合netty-socketio

    這次整合借鑒了以下博主的智慧 websocket和socketio的區(qū)別 socket.io.js最簡版單頁HTML測試工具 Netty-SocketIO多路復(fù)用 springboot學(xué)習(xí)(四十三) springboot使用netty-socketio實(shí)現(xiàn)消息推送 SpringBoot集成SocketIO socketio的核心依賴就只有這個(gè) 我在啟動類里面定義了啟動或者關(guān)閉SocketIOServer springboot整合

    2024年02月10日
    瀏覽(16)
  • Springboot中整合netty啟動后,項(xiàng)目無法正常啟動?

    Springboot中整合netty啟動后,項(xiàng)目無法正常啟動?

    ? 1.現(xiàn)象描述 netty等一般放在程序啟動后再啟動,多以下面方式啟動: 如果在 Order 后面還有其它模塊被啟動,那么其它模塊就會被阻塞。 2.原因分析 主線程啟動netty后,netty會將主線程阻塞。因此,需要采用異步方式或使用線程池來啟動netty。 3.解決辦法 添加異步注解@Async

    2024年02月13日
    瀏覽(23)
  • springboot+Netty搭建MQTT協(xié)議的服務(wù)端

    springboot+Netty搭建MQTT協(xié)議的服務(wù)端

    本文基于基礎(chǔ)版的netty實(shí)現(xiàn)mqtt 在此功能基礎(chǔ)上,進(jìn)行了功能強(qiáng)化,新增了用戶鑒權(quán)、多用戶訂閱推送,qos2級別消息處理,后續(xù)新增topic filter功能,本人會持續(xù)更新 Netty是業(yè)界最流行的nio框架之一,結(jié)合springboot可以滿足快速開發(fā) MQTT(Message Queuing Telemetry Transport,消息隊(duì)列遙測

    2024年02月16日
    瀏覽(34)
  • SpringBoot+Netty+Websocket實(shí)現(xiàn)消息推送

    SpringBoot+Netty+Websocket實(shí)現(xiàn)消息推送

    這樣一個(gè)需求:把設(shè)備異常的狀態(tài)每10秒推送到頁面并且以彈窗彈出來,這個(gè)時(shí)候用Websocket最為合適,今天主要是后端代碼展示。 添加依賴 定義netty端口號 netty服務(wù)器 Netty配置 管理全局Channel以及用戶對應(yīng)的channel(推送消息) 管道配置 自定義CustomChannelHandler 推送消息接口及

    2024年02月04日
    瀏覽(19)
  • Springboot中使用netty 實(shí)現(xiàn) WebSocket 服務(wù)

    依賴 創(chuàng)建啟動類 創(chuàng)建WebSocket 服務(wù) WsServerInitialzer 初始化 創(chuàng)建信息ChatHandler 處理類

    2024年02月14日
    瀏覽(19)
  • SpringBoot 2.7 集成 Netty 4 實(shí)現(xiàn) UDP 通訊

    Netty 作為異步通訊框架,支持多種協(xié)議。本文將介紹基于 SpringBoot 2.7 整合 Netty 4 實(shí)現(xiàn) UDP 通訊。 netty 版本: 3.1 服務(wù)端事務(wù)處理器(DemoUdpNettyServerHandler) 代碼說明: 這里使用線程池來異步處理事務(wù),提高系統(tǒng)并發(fā)性能 3.2 服務(wù)端連接類(InitUdpNettyServer) 代碼說明: UDP 協(xié)議需要使用

    2024年02月03日
    瀏覽(18)
  • SpringBoot+Netty+Vue+Websocket實(shí)現(xiàn)在線推送/聊天系統(tǒng)

    SpringBoot+Netty+Vue+Websocket實(shí)現(xiàn)在線推送/聊天系統(tǒng)

    ok,那么今天的話也是帶來這個(gè)非常常用的一個(gè)技術(shù),那就是咱們完成nutty的一個(gè)應(yīng)用,今天的話,我會介紹地很詳細(xì),這樣的話,拿到這個(gè)博文的代碼就基本上可以按照自己的想法去構(gòu)建自己的一個(gè)在線應(yīng)用了。比如聊天,在線消息推送之類的。其實(shí)一開始我原來的想法做在

    2024年02月03日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包