一、什么是websocket?

WebSocket 协议是基于 TCP 的一种新的网络协议。

它实现了客户端与服务器之间的全双工通信,学过计算机网络都知道,既然是全双工,就说明了服务器可以主动发送信息给客户端

这与我们的推送技术或者是多人在线聊天的功能不谋而合。

为什么不使用 HTTP 协议呢?

这是因为HTTP是单工通信,通信只能由客户端发起,客户端请求一下,服务器处理一下,这就太麻烦了。

于是 websocket 应运而生。

下面我们就直接开始使用 Spring Boot 开始整合。以下案例都在我自己的电脑上测试成功,你可以根据自己的功能进行修改即可。

我的项目结构如下:

二、使用步骤

1.添加依赖

Maven 依赖:

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.启用Springboot对WebSocket的支持

启用 WebSocket 的支持也是很简单,几句代码搞定。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/*** @ Auther: 马超伟* @ Date: 2020/06/16/14:35* @ Description: 开启WebSocket支持*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

3.核心配置:WebSocketServer

因为 Web Socket 是类似客户端服务端的形式(采用 ws 协议),那么这里的 WebSocketServer 其实就相当于一个 ws 协议的 Controller。

@ServerEndpoint 注解这是一个类层次的注解,它的功能主要是将目前的类定义成一个 websocket 服务器端。注解的值将被用于监听用户连接的终端访问 URL 地址,客户端可以通过这个 URL 来连接到 WebSocket 服务器端

再新建一个 ConcurrentHashMap webSocketMap 用于接收当前 userId 的 WebSocket,方便传递之间对 userId 进行推送消息。

下面是具体业务代码:

package cc.mrbird.febs.external.webScoket;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;/*** Created with IntelliJ IDEA.* @ Auther: 马超伟* @ Date: 2020/06/16/14:35* @ Description:* @ ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,* 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端*/
@Component
@Slf4j
@Service
@ServerEndpoint("/api/websocket/{sid}")
public class WebSocketServer {//当前在线连接数private static int onlineCount = 0;//存放每个客户端对应的MyWebSocket对象private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();private Session session;//接收sidprivate String sid = "";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {this.session = session;webSocketSet.add(this);     //加入set中this.sid = sid;addOnlineCount();           //在线数加1try {sendMessage("conn_success");log.info("有新窗口开始监听:" + sid + ",当前在线人数为:" + getOnlineCount());} catch (IOException e) {log.error("websocket IO Exception");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {webSocketSet.remove(this);  //从set中删除subOnlineCount();           //在线数减1log.info("释放的sid为:"+sid);log.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 收到客户端消息后调用的方法* @ Param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("收到来自窗口" + sid + "的信息:" + message);//群发消息for (WebSocketServer item : webSocketSet) {try {item.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}/*** @ Param session* @ Param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误");error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 群发自定义消息*/public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {log.info("推送消息到窗口" + sid + ",推送内容:" + message);for (WebSocketServer item : webSocketSet) {try {//为null则全部推送if (sid == null) {
//                    item.sendMessage(message);} else if (item.sid.equals(sid)) {item.sendMessage(message);}} catch (IOException e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {return webSocketSet;}
}

4.测试Controller

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;/*** Created with IntelliJ IDEA.** @ Auther: 马超伟* @ Date: 2020/06/16/14:38* @ Description:*/
@Controller("web_Scoket_system")
@RequestMapping("/api/socket")
public class SystemController {//页面请求@GetMapping("/index/{userId}")public ModelAndView socket(@PathVariable String userId) {ModelAndView mav = new ModelAndView("/socket1");mav.addObject("userId", userId);return mav;}//推送数据接口@ResponseBody@RequestMapping("/socket/push/{cid}")public Map pushToWeb(@PathVariable String cid, String message) {Map<String,Object> result = new HashMap<>();try {WebSocketServer.sendInfo(message, cid);result.put("code", cid);result.put("msg", message);} catch (IOException e) {e.printStackTrace();}return result;}
}

5.测试页面index.html

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Java 后端 WebSocket 的 Tomcat 实现</title><script type="text/javascript" src="js/jquery.min.js"></script></head><body><div id="main" style="width: 1200px;height:800px;"></div>Welcome<br/><input id="text" type="text" /><button onclick="send()">发送消息</button><hr/><button onclick="closeWebSocket()">关闭WebSocket连接</button><hr/><div id="message"></div></body><script type="text/javascript">var websocket = null;//判断当前浏览器是否支持WebSocketif('WebSocket' in window) {websocket = new WebSocket("ws://192.168.100.196:8082/api/websocket/100");} else {alert('当前浏览器 Not support websocket')}//连接发生错误回调方法websocket.onerror = function() {setMessageInnerHTML("WebSocket连接发生错误");};//连接成功建立回调方法websocket.onopen = function() {setMessageInnerHTML("WebSocket连接成功");}var U01data, Uidata, Usdata//接收消息回调方法websocket.onmessage = function(event) {console.log(event);setMessageInnerHTML(event);setechart()}//连接关闭回调方法websocket.onclose = function() {setMessageInnerHTML("WebSocket连接关闭");}//监听窗口关闭事件window.onbeforeunload = function() {closeWebSocket();}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {document.getElementById('message').innerHTML += innerHTML + '<br/>';}//关闭WebSocket连接function closeWebSocket() {websocket.close();}//发送消息function send() {var message = document.getElementById('text').value;websocket.send('{"msg":"' + message + '"}');setMessageInnerHTML(message + "
");}</script></html>

6.结果展示

后台:

如果有连接请求

前台显示:

总结

这中间我遇到一个问题,就是说 WebSocket 启动的时候优先于 spring 容器,从而导致在 WebSocketServer 中调用业务Service会报空指针异常。

所以需要在 WebSocketServer 中将所需要用到的 service 给静态初始化一下:

如图所示:

还需要做如下配置:

原文:blog.csdn.net/MacWx/article/details/111319558

版权声明:本文为CSDN博主「大树先生.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

IT技术分享社区
个人博客网站:https://programmerblog.xyz文章推荐程序员效率:画流程图常用的工具程序员效率:整理常用的在线笔记软件远程办公:常用的远程协助软件,你都知道吗?51单片机程序下载、ISP及串口基础知识硬件:断路器、接触器、继电器基础知识

Spring Boot 集成 WebSocket通信信息推送!相关推荐

  1. spring boot 集成socketIo 做消息推送

    spring boot 集成socketIo 做消息推送 项目需求 代码展示 客户端代码 服务端代码 项目需求 后台管理系统用户小铃铛,消息推送功能并展示有多少条消息或者小红点 代码展示 客户端代码 ...

  2. spring boot 集成 websocket 实现消息主动推送

    前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单向的,在很多场景就不适合,比如实时的推送,消息通知或者股票等信息 ...

  3. springboot集成webSocket实现实时推送

    springboot集成webSocket实现实时推送 webSocket实现推送 webSocket是什么? 需求说明 websocket集成步骤 pom.xml webSocket实现 自定义处理 ...

  4. SpringBoot2.x系列教程(四十五)Spring Boot集成WebSocket实现技术交流群功能

    在上篇文章中,我们了解了WebSocket的基本功能及相关概念.本篇文章中我们以具体的实例来演示,在Spring Boot中整合WebSocket,同时实现一个场景的业务场景功能. 针对在Spring ...

  5. java websocket注解_【websocket】spring boot 集成 websocket 的四种方式

    集成 websocket 的四种方案 1. 原生注解 pom.xml org.springframework.boot spring-boot-starter-websocket WebSocketC ...

  6. Spring clound+VUE+WebSocket实现消息推送 一(即时通讯)

    需求: 当用户进行某个操作,需要通知其他用户时,其他用户可以实时接收消息. 工程为 Spring cloud + VUE . 技术实现: Spring Cloud.Spring boot.vue.we ...

  7. Springboot集成websocket实现消息推送和在线用户统计

    一.HTTP 说到websocket首先要说Http,Http大家都知道是一个网络通信协议,每当客户端浏览器需要访问后台时都会发一个请求,服务器给出响应后该连接就会关闭,请求只能有客户端发起,服务端是 ...

  8. Spring Boot 实现企业微信消息推送

    1 Maven依赖 <!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba</groupId><ar ...

  9. 2小时学习Spring Boot 2019版本 代码一样推送至github上面去

    简介:<2小时学习Spring Boot>后续进阶课程,主要讲述了Spring Boot针对Web方面的相关技巧 讲师实战课程<Spring Boot微信点餐系统> http: ...

最新文章

  1. 3D Point Cloud Library install
  2. opengl版本发展史及各种概念的厘清
  3. DeepMind新语言模型SUNDAE:教自动编码器学会「自我纠正」,WMT14英德互译任务获SOTA...
  4. strhcr函数的使用简单示例
  5. 关于meta便签详解
  6. 如何有效地使用t-SNE | How to Use t-SNE Effectively
  7. 使用强类型DataSet增加数据并获取自动增长的ID
  8. 拓端tecdat|R语言时变波动率和ARCH,GARCH,GARCH-in-mean模型分析股市收益率时间序列
  9. matlab模糊闭包,基于matlab的模糊聚类分析
  10. 回归老博客(no zuo no dead)
  11. 镜像文件iso有什么用
  12. 论文阅读笔记《Principal characteristic networks for few-shot learning》
  13. SpringBoot集成Dubbo
  14. 三星a52屏幕刷新率设置方法分享
  15. Android色彩特效处理之色调、饱和度、亮度、ColorMatrix精炼详解
  16. scrollTop兼容性问题
  17. STC89C51——定时器/计数器介绍及程序配置
  18. 大数据之电商分析系统(一)
  19. 【深度学习】肺结节分割项目实战二:分割肺实质
  20. matlab怎么选择高频变压器,高频变压器的建模与仿真定.doc

热门文章

  1. ASP.NET学习笔记
  2. linux显示中文乱码
  3. VS2017 C++工程 执行python脚本
  4. Ti的DM368系列芯片的所有PDF资料汇总
  5. C#using static
  6. HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格
  7. ABB RAPID 在 Notepad++ 中语法高亮的实现
  8. 现代制造工程笔记05-表面工程技术
  9. 学习笔记(45):Python实战编程-键盘事件
  10. win10+anaconda安装tensorflow和keras遇到的坑小结