来源:https://www.cnblogs.com/leigepython/p/11058902.html

pom.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.1.1.RELEASE</version>
9 <relativePath/> <!-- lookup parent from repository -->
10 </parent>
11 <groupId>com.zhengcj</groupId>
12 <artifactId>spring-boot-09-websocket</artifactId>
13 <version>0.0.1-SNAPSHOT</version>
14 <name>spring-boot-09-websocket</name>
15 <description>Demo project for Spring Boot</description>
16
17 <properties>
18 <java.version>1.8</java.version>
19 </properties>
20
21 <dependencies>
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-thymeleaf</artifactId>
25 </dependency>
26 <dependency>
27 <groupId>org.springframework.boot</groupId>
28 <artifactId>spring-boot-starter-web</artifactId>
29 </dependency>
30 <dependency>
31 <groupId>org.springframework.boot</groupId>
32 <artifactId>spring-boot-starter-websocket</artifactId>
33 </dependency>
34
35 <dependency>
36 <groupId>org.springframework.boot</groupId>
37 <artifactId>spring-boot-starter-test</artifactId>
38 <scope>test</scope>
39 </dependency>
40 </dependencies>
41
42 <build>
43 <plugins>
44 <plugin>
45 <groupId>org.springframework.boot</groupId>
46 <artifactId>spring-boot-maven-plugin</artifactId>
47 </plugin>
48 </plugins>
49 </build>
50
51
52 </project>

SpringBoot09WebsocketApplication.java

 1 package com.zhengcj.websocket;
2
3 import org.springframework.boot.SpringApplication;
4 import org.springframework.boot.autoconfigure.SpringBootApplication;
5
6 /**
7 * 地址:https://www.cnblogs.com/leigepython/p/11058902.html
8 * @author zhengcj
9 *
10 */
11 @SpringBootApplication
12 public class SpringBoot09WebsocketApplication {
13
14 public static void main(String[] args) {
15 SpringApplication.run(SpringBoot09WebsocketApplication.class, args);
16 }
17
18 }

WebSocketConfig.java

 1 package com.zhengcj.websocket.config;
2
3 import org.springframework.context.annotation.Bean;
4 import org.springframework.context.annotation.Configuration;
5 import org.springframework.web.socket.server.standard.ServerEndpointExporter;
6
7 /**
8 * @author zhengcj
9 * @Date 2020年4月27日 上午11:37:26
10 * @version
11 * @Description socket配置类,往 spring 容器中注入ServerEndpointExporter实例
12 *
13 */
14 @Configuration
15 public class WebSocketConfig {
16 @Bean
17 public ServerEndpointExporter serverEndpointExporter() {
18 return new ServerEndpointExporter();
19 }
20
21 }

WebSocketServer.java

  1 package com.zhengcj.websocket.common;
2
3 import java.io.IOException;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.concurrent.atomic.AtomicInteger;
7
8 import javax.websocket.OnClose;
9 import javax.websocket.OnError;
10 import javax.websocket.OnMessage;
11 import javax.websocket.OnOpen;
12 import javax.websocket.Session;
13 import javax.websocket.server.PathParam;
14 import javax.websocket.server.ServerEndpoint;
15
16 import org.springframework.stereotype.Component;
17
18 /**
19 * WebSocket服务端代码,包含接收消息,推送消息等接口
20 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
21 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
22 * @author zhengcj
23 * @Date 2020年4月27日 下午1:36:13
24 * @version
25 * @Description
26 */
27 @Component
28 @ServerEndpoint(value = "/socket/{name}")
29 public class WebSocketServer {
30
31 // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
32 private static AtomicInteger online = new AtomicInteger();
33 // concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
34 // private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
35 private static Map<String, Session> sessionPools = new HashMap<>();
36
37 /**
38 * 发送消息方法
39 * @param session 客户端与socket建立的会话
40 * @param message 消息
41 * @throws IOException
42 */
43 public void sendMessage(Session session, String message) throws IOException {
44 if (session != null) {
45 session.getBasicRemote().sendText(message);
46 }
47 }
48
49 /**
50 * 连接建立成功调用
51 * @param sessionv 客户端与socket建立的会话
52 * @param userName 客户端的userName
53 */
54 @OnOpen
55 public void onOpen(Session session, @PathParam(value = "name") String userName) {
56 sessionPools.put(userName, session);
57 addOnlineCount();
58 System.out.println(userName + "加入webSocket!当前人数为" + online);
59 try {
60 sendMessage(session, "欢迎" + userName + "加入连接!");
61 } catch (IOException e) {
62 e.printStackTrace();
63 }
64 }
65
66 /**
67 * 关闭连接时调用
68 * @param userName 关闭连接的客户端的姓名
69 */
70 @OnClose
71 public void onClose(@PathParam(value = "name") String userName) {
72 sessionPools.remove(userName);
73 subOnlineCount();
74 System.out.println(userName + "断开webSocket连接!当前人数为" + online);
75 }
76
77 /**
78 * 收到客户端消息时触发(群发)
79 * @param message
80 * @throws IOException
81 */
82 @OnMessage
83 public void onMessage(String message) throws IOException {
84 System.out.println("群发信息:"+message);
85 for (Session session : sessionPools.values()) {
86 try {
87 sendMessage(session, message);
88 } catch (Exception e) {
89 e.printStackTrace();
90 continue;
91 }
92 }
93 }
94
95 /**
96 * 发生错误时候
97 * @param session
98 * @param throwable
99 */
100 @OnError
101 public void onError(Session session, Throwable throwable) {
102 System.out.println("发生错误");
103 throwable.printStackTrace();
104 }
105
106 /**
107 * 给指定用户发送消息
108 *
109 * @param userName
110 * 用户名
111 * @param message
112 * 消息
113 * @throws IOException
114 */
115 public void sendInfo(String userName, String message) {
116 Session session = sessionPools.get(userName);
117 try {
118 sendMessage(session, message);
119 } catch (Exception e) {
120 e.printStackTrace();
121 }
122 }
123
124 public static void addOnlineCount() {
125 online.incrementAndGet();
126 }
127
128 public static void subOnlineCount() {
129 online.decrementAndGet();
130 }
131 }

WebMvcConfig.java

 1 package com.zhengcj.websocket.config;
2
3 import org.springframework.context.annotation.Configuration;
4 import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
5 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
6
7 /**
8 * @author zhengcj
9 * @Date 2020年4月27日 下午1:38:31
10 * @version
11 * @Description
12 *
13 * 在SpringBoot2.0及Spring 5.0 WebMvcConfigurerAdapter已被废弃,目前找到解决方案就有
14 * 1 直接实现WebMvcConfigurer (官方推荐)
15 * 2 直接继承WebMvcConfigurationSupport
16 * @ https://blog.csdn.net/lenkvin/article/details/79482205
17 */
18 @Configuration
19 public class WebMvcConfig implements WebMvcConfigurer{
20 /**
21 * 为各个页面提供路径映射
22 * @param registry
23 */
24 @Override
25 public void addViewControllers(ViewControllerRegistry registry) {
26 registry.addViewController("/zhengcj").setViewName("zhengcj");
27 registry.addViewController("/yuzh").setViewName("yuzh");
28 }
29 }

SocketController.java

 1 package com.zhengcj.websocket.controller;
2
3 import java.io.IOException;
4
5 import javax.annotation.Resource;
6
7 import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.RequestParam;
9 import org.springframework.web.bind.annotation.RestController;
10
11 import com.zhengcj.websocket.common.WebSocketServer;
12
13 /**
14 * @author zhengcj
15 * @Date 2020年4月27日 下午1:44:32
16 * @version
17 * @Description
18 *
19 */
20 @RestController
21 public class SocketController {
22 @Resource
23 private WebSocketServer webSocketServer;
24
25 /**
26 * 给指定用户推送消息
27 * @param userName 用户名
28 * @param message 消息
29 * @throws IOException
30 */
31 @GetMapping("/socket")
32 public void pushOneUser(@RequestParam String userName, @RequestParam String message){
33 System.err.println("====socket===="+message);
34 webSocketServer.sendInfo(userName, message);
35 }
36
37 /**
38 * 给所有用户推送消息
39 * @param message 消息
40 * @throws IOException
41 */
42 @GetMapping("/socket/all")
43 public void pushAllUser(@RequestParam String message){
44 try {
45 System.err.println("====socket/all===="+message);
46 webSocketServer.onMessage(message);
47 } catch (IOException e) {
48 e.printStackTrace();
49 }
50 }
51 }

yuzh.html

<!DOCTYPE HTML>
<html>
<head>
<title>WebSocket</title>
</head> <body>
Welcome
<br />
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body> <script type="text/javascript">
var websocket = null; //判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/socket/yuzh");
} else {
alert('Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function() {
setMessageInnerHTML("error");
}; //连接成功建立的回调方法
websocket.onopen = function(event) {
setMessageInnerHTML("open");
} //接收到消息的回调方法
websocket.onmessage = function(event) {
setMessageInnerHTML(event.data);
} //连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("close");
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
websocket.close();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
} //关闭连接
function closeWebSocket() {
websocket.close();
} //发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>

  zhengcj.html

<!DOCTYPE HTML>
<html>
<head>
<title>WebSocket</title>
</head> <body>
Welcome
<br />
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body> <script type="text/javascript">
var websocket = null; //判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/socket/zhengcj");
} else {
alert('Not support websocket')
} //连接发生错误的回调方法
websocket.onerror = function() {
setMessageInnerHTML("error");
}; //连接成功建立的回调方法
websocket.onopen = function(event) {
setMessageInnerHTML("open");
} //接收到消息的回调方法
websocket.onmessage = function(event) {
setMessageInnerHTML(event.data);
} //连接关闭的回调方法
websocket.onclose = function() {
setMessageInnerHTML("close");
} //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
websocket.close();
} //将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '<br/>';
} //关闭连接
function closeWebSocket() {
websocket.close();
} //发送消息
function send() {
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>

  

spring boot 集成 websocket 实现消息主动的更多相关文章

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

    spring boot 集成 websocket 实现消息主动 前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单 ...

  2. Spring Boot 集成 WebSocket 实现服务端推送消息到客户端

    假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的 ...

  3. 【websocket】spring boot 集成 websocket 的四种方式

    集成 websocket 的四种方案 1. 原生注解 pom.xml <dependency> <groupId>org.springframework.boot</gr ...

  4. spring boot集成Websocket

    websocket实现后台像前端主动推送消息的模式,可以减去前端的请求获取数据的模式.而后台主动推送消息一般都是要求消息回馈比较及时,同时减少前端ajax轮询请求,减少资源开销. spring boo ...

  5. Spring boot集成Websocket,前端监听心跳实现

    第一:引入jar 由于项目是springboot的项目所以我这边简单的应用了springboot自带的socket jar <dependency> <groupId>org. ...

  6. spring boot集成websocket实现聊天功能和监控功能

    本文参考了这位兄台的文章: https://blog.csdn.net/ffj0721/article/details/82630134 项目源码url: https://github.com/zhz ...

  7. Spring Boot之WebSocket

    一.项目说明 1.项目地址:https://github.com/hqzmss/test01-springboot-websocket.git 2.IDE:IntelliJ IDEA 2018.1.1 ...

  8. spring boot 集成 zookeeper 搭建微服务架构

    PRC原理 RPC 远程过程调用(Remote Procedure Call) 一般用来实现部署在不同机器上的系统之间的方法调用,使得程序能够像访问本地系统资源一样,通过网络传输去访问远程系统资源,R ...

  9. Spring boot入门(二):Spring boot集成MySql,Mybatis和PageHelper插件

    上一篇文章,写了如何搭建一个简单的Spring boot项目,本篇是接着上一篇文章写得:Spring boot入门:快速搭建Spring boot项目(一),主要是spring boot集成mybat ...

随机推荐

  1. 实验4 汇编应用编程和c语言程序反汇编分析

    1. 实验任务1 教材「实验9 根据材料编程」(P187-189)编程:在屏幕中间分别显示绿色.绿底红色.白底蓝色的字符串'welcome to masm!'. 解题思路:根据学习的知识,我知道该页在 ...

  2. Eureka系列(八)服务剔除具体实现

    服务下线的大致流程图   下面这张图很简单地描述了服务剔除的大致流程: 服务剔除实现源码分析   首先我们得了解下服务剔除这个定时任务是什么被初始化启动的,在百度搜索中,在我们Eureka Serve ...

  3. 道高一丈,且看CWE4.2的新特性

    摘要:CWE在今年2/24发布4.0,首次将硬件安全漏洞纳入了CWE中,6/25发布4.1, 8/20就发布了4.2. 1. 按照惯例,先说故事 我们先说下CWE的幕后老板--MITRE[1]. MI ...

  4. 给2021年的我立几个FLAG

    看多了大牛的年终总结,我也懒得写了,反正写出来也没人看. 其实上面都是借口,我只是完全没有写年终总结的习惯. 为啥呢?因为这些年过的平平无奇,并没有什么特别出彩的事情. 如果有,嗯,2020年,我结婚 ...

  5. Linux 时间同步 01 简介

    Linux 时间同步 01 简介 目录 Linux 时间同步 01 简介 时间同步 公共NTP服务器地址及IP 系统时间相关文件 时间同步 大数据产生与处理系统是各种计算设备集群的,计算设备将统一.同 ...

  6. HystrixRequestContext实现Request级别的上下文

    一.简介 在微服务架构中,我们会有这样的需求,A服务调用B服务,B服务调用C服务,ABC服务都需要用到当前用户上下文信息(userId.orgId等),那么如何实现呢? 方案一: 拦截器加上Threa ...

  7. zookeeper选举算法

    一.ZAB协议三阶段 – 发现(Discovery),即选举Leader过程– 同步(Synchronization),选举出新的Leader后,Follwer或者Observer从Leader同步最 ...

  8. SQL Server批量向表中插入多行数据语句

    因自己学习测试需要,需要两个有大量不重复行的表,表中行数越多越好.手动编写SQL语句,通过循环,批量向表中插入数据,考虑到避免一致问题,设置奇偶行不同.个人水平有限,如有错误,还望指正. 语句如下: ...

  9. Apache的Mod_rewrite学习(RewriteRule重写规则的语法) 转

    RewriteRuleSyntax: RewriteRule Pattern Substitution [flags] 一条RewriteRule指令,定义一条重写规则,规则间的顺序非常重要.对Apa ...

  10. redis 6.0新特性

    防止忘记,记录一下 1.多线程IO Redis 6引入多线程IO,但多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程.之所以这么设计是不想因为多线程而变得复杂,需要去控制 key. ...