互联网应用架构:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习。

断更快两个月了,6月份工作忙到飞起,7月份家里又有事,已经累到躺下就想睡觉的程度了。

现在我们做WebSocket服务,很多时候都是会整合Netty作为服务器,但是有个问题,就是发现网上的整合起来,比较繁琐,各种配置,各种对应,最关键是千篇一律的网文,看得好辛苦了,今天咱们来介绍一个开源的组件,帮你快速搭建基于Netty的WebSocket服务,让你更加轻松,更加专注于业务开发。

组件介绍

netty-websocket-spring-boot-starter是基于Netty服务器来做的WebSocket服务器,不需要配置Netty服务器信息,只需要配置Webscoket的注解就行,目前用起来还是很方便的。

加载包体

<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><modelVersion>4.0.0modelVersion><parent><groupId>com.bootsgroupId><artifactId>bootsartifactId><version>1.1.0.RELEASEversion>parent><groupId>boots.weboscketgroupId><artifactId>boots-weboscketartifactId><version>2.0.0.RELEASEversion><name>boots-weboscketname><url>http://maven.apache.orgurl><properties><project.build.sourceEncoding>UTF-8project.build.sourceEncoding>properties><dependencies>

<dependency><groupId>com.bootsgroupId><artifactId>module-boots-apiartifactId><version>2.0.0.RELEASEversion>dependency>

<dependency><groupId>io.nettygroupId><artifactId>netty-allartifactId>dependency>

<dependency><groupId>org.yeautygroupId><artifactId>netty-websocket-spring-boot-starterartifactId><version>0.9.5version>dependency>dependencies>project>

配置文件

######配置基本信息########配置应用名称spring.application.name: boots-websocket##配置时间格式,为了避免精度丢失,全部换成字符串spring.jackson.timeZone: GMT+8spring.jackson.dateFormat: yyyy-MM-dd HH:mm:ssspring.jackson.generator.writeNumbersAsStrings: true

单个推送后端代码

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.boots.websocket.websocket;import org.yeauty.annotation.OnClose;import org.yeauty.annotation.OnError;import org.yeauty.annotation.OnMessage;import org.yeauty.annotation.OnOpen;import org.yeauty.annotation.ServerEndpoint;import org.yeauty.pojo.Session;import com.module.boots.exception.CommonRuntimeException;import io.netty.handler.codec.http.HttpHeaders;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;/** * 单个推送服务 * @author:溪云阁 * @date:2020年8月4日 */@Slf4j@ServerEndpoint(path = "/SingleSocket", host = "127.0.0.1", port = "8900")public class SingleSocket {    /**     * 新建WebSocket的时候,执行该方法     * @author 溪云阁     * @param session     * @param headers void     */@OnOpen    @SneakyThrows(CommonRuntimeException.class)    public void onOpen(Session session, HttpHeaders headers) {        log.info("WebSocket服务连接成功");    }    /**     * 关闭WebSocket的时候,执行该方法     * @author 溪云阁     * @param session void     */@OnClose    @SneakyThrows(CommonRuntimeException.class)    public void onClose(Session session) {        log.info("WebSocket服务关闭成功");    }    /**     * WebSocket发生异常的时候,执行该方法     * @author 溪云阁     * @param session     * @param th void     */@OnError    public void onError(Session session, Throwable th) {        log.error("{}", th.fillInStackTrace());th.printStackTrace();    }    /**     * WebSocket接收到的消息为字符串的时候,指定该方法     * @author 溪云阁     * @param session     * @param msg void     */@OnMessage    @SneakyThrows(CommonRuntimeException.class)    public void OnMessage(Session session, String msg) {        log.info("接收到的信息:{}", msg);session.sendText(msg);    }}

单个推送前端页面

span style="-webkit-tap-highlight-color: transparent;box-sizing: border-box;border-width: 0px;border-style: initial;border-color: initial;">html><html><head><meta charset="utf-8"><title>单个推送title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/layui/css/layui.css" media="all">head><body><fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px; margin-left: 310px; margin-right: 310px"><legend>输出内容legend>fieldset><form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px"><div class="layui-form-item layui-form-text"><div class="layui-input-block"><textarea placeholder="请输入内容" class="layui-textarea" rows="20" id="contentArea">textarea>div>div>form><form class="layui-form layui-form-pane" style="margin-left: 310px; margin-right: 310px" action=""><div class="layui-form-item"><label class="layui-form-label">输入label><div class="layui-input-block"><input type="text" name="content" id="content" autocomplete="off" placeholder="请输入内容" class="layui-input">div>div>form><div class="layui-form-item" style="margin-left: 310px; margin-right: 310px"><button class="layui-btn" onclick="sendMsg()">发送button>div><script src="/js/jquery.min.js" >script><script src="/layui/layui.js" charset="utf-8">script><script>     var websocket = new WebSocket("ws://127.0.0.1:8900/SingleSocket");     //WebSocket打开     websocket.onopen = function(evt) {           $('#contentArea').html("WebSocket服务连接成功");        };        //WebSocket推送     websocket.onmessage = function(evt) {            var val = $('#contentArea').val() + "";           $('#contentArea').html(val + evt.data);        };        //WebSocket关闭     websocket.onclose = function(evt) {          $('#contentArea').html("WebSocket服务关闭成功");        };        function sendMsg() {          var text = $('#content').val();            websocket.send(text);     } script>body>html>

群发推送后端代码

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.boots.websocket.websocket;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import org.yeauty.annotation.OnClose;import org.yeauty.annotation.OnError;import org.yeauty.annotation.OnMessage;import org.yeauty.annotation.OnOpen;import org.yeauty.annotation.ServerEndpoint;import org.yeauty.pojo.Session;import com.module.boots.exception.CommonRuntimeException;import io.netty.handler.codec.http.HttpHeaders;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;/** * 群组推送服务 * @author:溪云阁 * @date:2020年8月4日 */@Slf4j@ServerEndpoint(path = "/groupSocket", host = "127.0.0.1", port = "8901")public class GroupSocket {// 定义存放Session的缓存对象    private Map map = new ConcurrentHashMap<>();    /**     * 新建WebSocket的时候,执行该方法     * @author 溪云阁     * @param session     * @param headers void     */    @OnOpen    @SneakyThrows(CommonRuntimeException.class)    public void onOpen(Session session, HttpHeaders headers) {        // 把Session放到缓存中,后面群发使用        map.put(session.id().toString(), session);        log.info("WebSocket服务连接成功");    }    /**     * 关闭WebSocket的时候,执行该方法     * @author 溪云阁     * @param session void     */    @OnClose    @SneakyThrows(CommonRuntimeException.class)    public void onClose(Session session) {        // 当关闭的时候,删除缓存中的session        if (map.containsKey(session.id().toString())) {            map.remove(session.id().toString());        }        log.info("WebSocket服务关闭成功");    }    /**     * WebSocket发生异常的时候,执行该方法     * @author 溪云阁     * @param session     * @param th void     */    @OnError    public void onError(Session session, Throwable th) {        log.error("{}", th.fillInStackTrace());        th.printStackTrace();    }    /**     * WebSocket接收到的消息为字符串的时候,指定该方法     * @author 溪云阁     * @param session     * @param msg void     */    @OnMessage    @SneakyThrows(CommonRuntimeException.class)    public void OnMessage(String msg) {        map.forEach((key, session) -> {            log.info("接收到的信息:{}", msg);            session.sendText(msg);        });    }}

群发推送前端页面

span style="-webkit-tap-highlight-color: transparent;box-sizing: border-box;border-width: 0px;border-style: initial;border-color: initial;">html><html><head><meta charset="utf-8"><title>群发推送title><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><link rel="stylesheet" href="/layui/css/layui.css" media="all">head><body><fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px; margin-left: 310px; margin-right: 310px"><legend>输出内容legend>fieldset><form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px"><div class="layui-form-item layui-form-text"><div class="layui-input-block"><textarea placeholder="请输入内容" class="layui-textarea" rows="10" id="contentArea1">textarea>div>div>form><form class="layui-form" action="" style="margin-left: 200px; margin-right: 310px"><div class="layui-form-item layui-form-text"><div class="layui-input-block"><textarea placeholder="请输入内容" class="layui-textarea" rows="10" id="contentArea2">textarea>div>div>form><form class="layui-form layui-form-pane" style="margin-left: 310px; margin-right: 310px" action=""><div class="layui-form-item"><label class="layui-form-label">输入label><div class="layui-input-block"><input type="text" name="content" id="content" autocomplete="off" placeholder="请输入内容" class="layui-input">div>div>form><div class="layui-form-item" style="margin-left: 310px; margin-right: 310px"><button class="layui-btn" onclick="sendMsg()">发送button>div><script src="/js/jquery.min.js" >script><script src="/layui/layui.js" charset="utf-8">script><script>      var websocket1 = new WebSocket("ws://127.0.0.1:8901/groupSocket");     var websocket2 = new WebSocket("ws://127.0.0.1:8901/groupSocket");     //第一个WebSocket打开      websocket1.onopen = function(evt) {          $('#contentArea1').html("第一个WebSocket服务连接成功");        };        //第一个WebSocket推送      websocket1.onmessage = function(evt) {           var val = $('#contentArea1').val() + "";          $('#contentArea1').html(val + evt.data);       };        //第一个WebSocket关闭      websocket1.onclose = function(evt) {         $('#contentArea1').html("第一个WebSocket服务关闭成功");        };

      //第二个WebSocket打开      websocket2.onopen = function(evt) {          $('#contentArea2').html("第二个WebSocket服务连接成功");        };        //第二个WebSocket推送      websocket2.onmessage = function(evt) {           var val = $('#contentArea2').val() + "";          $('#contentArea2').html(val + evt.data);       };        //第二个WebSocket关闭      websocket2.onclose = function(evt) {         $('#contentArea2').html("第二个WebSocket服务关闭成功");        };        function sendMsg() {          var text = $('#content').val();            websocket1.send(text);            websocket2.send(text);        } script>body>html>

启动类

package com.boots.websocket;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ComponentScan;/** * 服务启动类 * @author:溪云阁 * @date:2020年5月2日 */@SpringBootApplication@ComponentScan(basePackages = { "com.module", "com.boots" })public class BootsWebSocketApplication {public static void main(String[] args) {        SpringApplication.run(BootsWebSocketApplication.class, args);    }}

单个推送测试

群发推送测试

总结及拓展

相比于需要自己整合Netty的配置,目前用起来还是很方便的,Netty的配置可以在注解类ServerEndpoint看到,里面一进去就会发现还是很清楚的。

目前发现有个不足的,就是超过一定时间不连接的时候,就会自动断开,不过这个可以在前端做个超时设置或者心跳检测,就可以了,问题不大,用起来还是很爽的。

--END--

maven netty 配置_springboot2.3手册:5分钟用Netty搭建高性能异步WebSocket服务相关推荐

  1. springboot2.3手册:5分钟用Netty搭建高性能异步WebSocket服务

    溪云阁:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习. 断更快两个月了,6月份工作忙到飞起,7月份家里又有事,已经累到躺下就想睡觉的程度了. 现在我们做Web ...

  2. maven netty 配置_网络编程(二)Netty编程之一

    一直想将自己使用netty框架的经验.所学多得进行整理,但因为各方面的原因一直拖到今天才可以抽出时间进行梳理总结.写关于netty文章的目的,在于对自己所学的东西进行梳理总结,归纳抽象,同时将这个东西 ...

  3. 三分钟构建高性能 WebSocket 服务 | 超优雅的 SpringBoot 整合 Netty 方案

    前言 每当使用SpringBoot进行Weboscket开发时,最容易想到的就是spring-boot-starter-websocket(或spring-websocket).它可以让我们使用注解, ...

  4. maven netty 配置_Netty是业界最流行的NIO框架之一:初识Netty

    为什么使用Netty Netty是业界最流行的NIO框架之一,它的健壮性.功能.性能.可定制性.可扩展性在同类框架中都是首屈一指的,它已经得到了成百上千的商用项目的证明.对于为什么使用Netty这个话 ...

  5. 物料分类账业务配置及操作手册

    物料分类账业务配置及操作手册 物料分类账业务配置及操作手册 Overview 业务说明 物料分类账的主要作用在于将实际成本和标准成本的差异分摊到库存和销售成本中,从而实现差异在实际的使用者中进行分摊, ...

  6. VMware vSphere 6.7 虚拟化搭建及配置完整详细手册 | 周末送资料

    VMware vSphere 6.7 虚拟化搭建及配置完整详细手册 | 周末送资料 https://mp.weixin.qq.com/s?__biz=MjM5NTk0MTM1Mw==&mid= ...

  7. maven配置自动部署到服务器上,jenkins+svn+maven安装配置并自动化部署成功(超级详细)...

    jenkins+svn+maven安装配置并自动化部署成功(超级详细) jenkins+svn+maven安装配置并自动化部署成功(超级详细) 简言 写这篇博客的原因是因为每次部署服务器的流程都是在做 ...

  8. Maven Nexus 配置和使用

    导航 博客园 首页 新随笔 联系 订阅 管理 < 2018年8月 > 日 一 二 三 四 五 六 29 30 31 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  9. Java-Maven(四):Eclipse集成Maven环境配置

    一般maven都需要集成到IDE上使用的,而不是单独的使用,常见的maven可集成IDE:eclipse.IntelliJ IDEA.但这里就只学习eclipse集成maven的基础上,进行maven ...

最新文章

  1. K-Means聚类算法原理
  2. 新年来临,给大家送上机器学习,人工智能相关书籍,这可能是中奖率最高的一次送书活动...
  3. 【C语言入门教程】3.4 循环控制语句
  4. 第十六周程序阅读(7)
  5. JVM参数设置、分析(转)
  6. 前端学习(892):bom概述
  7. linux之service命令
  8. 新科高德发布2009.03版电子眼升级数据升级方法: 1. 新科2440方案机器内
  9. 阿酷三合一版_阿酷插件下载|3dmax阿酷插件下载 v3.2 开源版 - 比克尔下载
  10. 手机上的python编辑器_菜鸟教程在线编辑器|菜鸟教程app手机版下载(html/java/python3)v1.0-乐游网安卓下载...
  11. 在IE中打开或下载文件
  12. 2018.06.25 一个不知道叫什么好的U盘启动工具集
  13. SharePoint On Premise 数据迁移到 SharePoint Online的几点考虑
  14. Vue + nightwatch + Chrome76进行e2e测试的正确配置(二)
  15. MySQL数据库13——插入数据(INSERT)
  16. SI好文翻译:铜箔表面纹理对损耗的影响:一个有效的模型(一)
  17. Android menu属性详解
  18. 安卓个人中心头像模块(从相册选择和照相功能,适配7.0)
  19. 查询校园网是否支持IPv6绕过校园网
  20. 100条令人啼笑皆非的幽默墓志铭

热门文章

  1. 二叉查找树的简单实现
  2. hdu 5072 Coprime
  3. 明早1点去青岛,可能要两天不能写博客了
  4. linux下remove函数
  5. 吴恩达机器学习(第三章)——线性代数回顾
  6. 近世代数--整环上的唯一分解问题--唯一分解整环上有算术分解定理
  7. 两数之和 II - 输入有序数组
  8. leetcode刷题练习
  9. Web安全之命令执行漏洞
  10. std:forward 完美转发