溪云阁:专注编程教学,架构,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.0</modelVersion><parent><groupId>com.boots</groupId><artifactId>boots</artifactId><version>1.1.0.RELEASE</version></parent><groupId>boots.weboscket</groupId><artifactId>boots-weboscket</artifactId><version>2.0.0.RELEASE</version><name>boots-weboscket</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- 公共组件:swagger服务+入参出参+统一异常拦截 --><dependency><groupId>com.boots</groupId><artifactId>module-boots-api</artifactId><version>2.0.0.RELEASE</version></dependency><!-- netty工具类 --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId></dependency><!-- netty-websocket整合工具类 --><dependency><groupId>org.yeauty</groupId><artifactId>netty-websocket-spring-boot-starter</artifactId><version>0.9.5</version></dependency></dependencies>
</project>

配置文件

######配置基本信息######
##配置应用名称spring.application.name: boots-websocket
##配置时间格式,为了避免精度丢失,全部换成字符串spring.jackson.timeZone: GMT+8
spring.jackson.dateFormat: yyyy-MM-dd HH:mm:ss
spring.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*/@OnErrorpublic 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);}}

单个推送前端页面

<!DOCTYPE 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<String, Session> 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) {// 当关闭的时候,删除缓存中的sessionif (map.containsKey(session.id().toString())) {map.remove(session.id().toString());}log.info("WebSocket服务关闭成功");}/*** WebSocket发生异常的时候,执行该方法* @author 溪云阁* @param session* @param th void*/@OnErrorpublic 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);});}
}

群发推送前端页面

<!DOCTYPE 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--

作者:@互联网应用架构

原创作品,抄袭必究

如需要源码,转发,关注后私信我

部分图片或代码来源网络,如侵权请联系删除,谢谢!

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

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

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

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

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

  3. Springboot+Netty搭建UDP客户端

    使用Netty+SpringBoot方式可以快速地开发一套基于UDP协议的服务端程序,同样的也可以开发客户端,一般使用UDP都是使用原生的方式,发送消息后就不管不问,也就是不需要确定消息是否收到,这里 ...

  4. 前端app调起摄像头 只显示在页面_猫也能看得懂的教程之一分钟使用Vue搭建简单Web页面...

    本教程适合人群: 已经了解过过html.js.css,想深入学习前端技术的小伙伴 有前端开发经验.但是没有使用过Vue的小伙伴 有过其他编程经验,对前端开发感兴趣的小伙伴 学习本教程之后你将会: 了解 ...

  5. netty系列之:使用netty搭建websocket服务器

    文章目录 简介 netty中的websocket websocket的版本 FrameDecoder和FrameEncoder WebSocketServerHandshaker WebSocketF ...

  6. 零基础小白10分钟用Python搭建小说网站!网友:我可以!

    都说Python什么都能做,本来我是不信的!直到我在CSDN站内看到了一件真事儿:一位博主贴出了自己10分钟用Python搭建小说网站的全过程!全程只用了2步操作,简直太秀了!!-- 第一步:爬取小说 ...

  7. 5分钟 0元搭建个人独立博客网站(二)

    文/北妈 阅读本文需要 5.1分钟 一 接着第一篇 5分钟建立独立网站系列,戳这里:<5分钟 0元搭建个人独立博客网站(一)> 这个Hexo.GitPages系列,其实网络很多教程,但都不 ...

  8. 5分钟 0元搭建个人独立博客网站(一)

    文/北妈 阅读本文需要 3.5分钟 一 直接入正题,先看北妈个人博客地址:http://www.guoxiaobei.com 微信不允许加入外链,你只能复制去外部浏览器打开,或者看完文章在底部的 &q ...

  9. 基于netty搭建websocket,实现消息的主动推送

    基于netty搭建websocket,实现消息的主动推送 rpf_siwash https://www.jianshu.com/p/56216d1052d7 netty是由jboss提供的一款开源框架 ...

最新文章

  1. 机器学习中常用的高级数据结构和数据分析包工具——pandas
  2. 关于PID的如何修改的FAQ
  3. 第33讲:可见即可爬,Appium 的使用
  4. 《构建之法》阅读笔记02
  5. 【代码笔记】iOS-下拉选项cell
  6. html5 筛子,html5摇骰子游戏
  7. 【离散数学中的数据结构与算法】九 鸽巢原理
  8. 载波聚合或双连接的方式进行_智能电表常用远程抄表方式,您想知道吗?--老兵聊电之...
  9. 增值电信业务许可,经营性icp证书自助申请教程【详细】
  10. LeetCode之Rectangle Overlap(Kotlin)
  11. CMU 15-213 Introduction to Computer Systems学习笔记(13) Exceptional Control Flow: Exceptions and Process
  12. Web前端业界氛围极好的群——鬼懿IT
  13. MySQL DQL操作之基础查询
  14. 一文带你搞清楚USB、type-C、雷电三接口之间的区别与联系
  15. Android Studio 连接阿里云数据库【制作基于数据库的多人远程聊天APP】
  16. checkpoint NGFW VM安装
  17. 众筹开班你说了算!UI设计+前端开发一站式打包学
  18. 华为交换机常用命令(以s5700-SI为例)
  19. Nginx做负载均衡的模块
  20. AI智能联系人管理系统(二)

热门文章

  1. 基于stm32f407的智能风扇系统
  2. 51单片机风扇转动c语言代码,基于51单片机的智能风扇控制系统设计.doc
  3. PHP笔记 17 18 19 20 21
  4. Android Q中外部存储盘路径正则表达式的理解
  5. vue3小兔鲜商城项目学习笔记+资料分享08
  6. [联想官方工具]关闭Win10自动更新工具 最新版 2.6.21.816
  7. torchvision使用keypoint rcnn 进行人体关键点定位
  8. 蚂蚁感冒问题暴力解决
  9. nodejs+vue健身俱乐部网站
  10. 乐信季报图解:交易额达562亿 利润4.1亿环比增长59%