Springboot集成WebSocket通信全部代码,即扣即用。
websocket通信主要来自两个类以及一个测试的html页面。
MyHandler 和 WebSocketH5Config,下面全部代码
MyHandler类全部代码:
package com.union.common.config; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set; import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession; @Service
public class MyHandler implements WebSocketHandler { //在线用户列表
private static final Map<String, WebSocketSession> webSocketUsers; static {
webSocketUsers = new HashMap<>();
}
//新增socket
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String ID = session.getUri().toString().split("uid=")[1];
if (ID != null) {
webSocketUsers.put(ID, session);
session.sendMessage(new TextMessage("成功建立socket连接")); }
} //接收socket信息
@Override
public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
try{
JSONObject jsonobject = JSONObject.parseObject((String) webSocketMessage.getPayload());
String message = (String) jsonobject.get("message");
if (message == null) {
message = "服务器收到了,hello!";
}
sendMessageToUser(jsonobject.get("id")+"",message);
}catch(Exception e){
e.printStackTrace();
}
} /**
* 发送信息给指定用户
* @param clientId
* @param message
* @return
*/
public boolean sendMessageToUser(String clientId, String message) {
if(webSocketUsers.get(clientId) == null){
return false;
}
WebSocketSession session = webSocketUsers.get(clientId);
if(!session.isOpen()) {
return false;
}
try {
session.sendMessage(new TextMessage(message));
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
} /**
* 广播信息
* @param message
* @return
*/
public boolean sendMessageToAllUsers(String message) {
boolean allSendSuccess = true;
Set<String> clientIds = webSocketUsers.keySet();
WebSocketSession session = null;
for (String clientId : clientIds) {
try {
session = webSocketUsers.get(clientId);
if (session.isOpen()) {
session.sendMessage(new TextMessage(message));
}
} catch (IOException e) {
e.printStackTrace();
allSendSuccess = false;
}
} return allSendSuccess;
} /**
* 关闭连接
* @param clientId
* @return
*/
public void afterConnectionClosed(String clientId) {
try {
if(webSocketUsers.get(clientId) != null){
WebSocketSession session = webSocketUsers.get(clientId);
afterConnectionClosed(session,CloseStatus.NORMAL);
}
webSocketUsers.remove(clientId);
}catch (Exception e){
e.printStackTrace();
}
} @Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
String uid = session.getUri().toString().split("uid=")[1];
webSocketUsers.remove(uid);
if (session.isOpen()) {
session.close();
}
} @Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String uid = session.getUri().toString().split("uid=")[1];
webSocketUsers.remove(uid);
session.close(status);
} @Override
public boolean supportsPartialMessages() {
return false;
}
}
WebSocketH5Config 类全部代码:
package com.union.common.config; import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; //实现接口来配置Websocket请求的路径和拦截器。
@Configuration
@EnableWebSocket
public class WebSocketH5Config implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
//handler是webSocket的核心,配置入口
registry.addHandler(new MyHandler(), "/myHandler/{uid}").setAllowedOrigins("*");
}
}
测试用的html页面:
<!DOCTYPE html>
<html>
<head>
<title>socket.html</title>
<meta name="content-type" content="text/html" charset="UTF-8">
</head>
<body> Welcome<br/>
登录的uid:<input id="uid" type="text"/><br/>
<button onclick="connectWebSocket()">connectWebSocket</button><br/>
发送出去的信息:<input id="text" type="text"/><br/>
发送送给谁的uid:<input id="sendToUid" type="text"/><br/>
<button onclick="send()">Send</button><br/>
收到的信息:<input id="getMessage" type="text"/><br/>
<button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script type="text/javascript">
var websocket = null;
//强制关闭浏览器 调用websocket.close(),进行正常关闭
window.onunload = function () {
//关闭连接
closeWebSocket();
} //建立WebSocket连接
function connectWebSocket() {
var userID = document.getElementById("uid");
console.log(userID);
console.log("开始..."); //建立webSocket连接
websocket = new WebSocket("ws://localhost:8080/myHandler/uid=" + userID.value); //打开webSokcet连接时,回调该函数
websocket.onopen = function () {
console.log("onpen");
} //关闭webSocket连接时,回调该函数
websocket.onclose = function () {
//关闭连接
console.log("onclose");
} //接收信息
websocket.onmessage = function (msg) {
var getMessage = document.getElementById("getMessage");
getMessage.value = msg.data;
console.log(msg.data);
}
} //发送消息
function send() {
var sendToUid = document.getElementById("sendToUid");
var messageText = document.getElementById("text");
var postValue = {};
postValue.id = sendToUid.value;
postValue.message = messageText.value;
websocket.send(JSON.stringify(postValue));
} //关闭连接
function closeWebSocket() {
if (websocket != null) {
websocket.close();
}
} </script>
</html>
因为websocket使用的是ws协议。所以我在nginx上做了一个请求转发,这样服务器就可以使用:
在nginx.conf文件里面的http部分加入如下代码。
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
在server{}部分加了如下代码。放在最前面,就可以在ws部分使用域名访问了:
ws和wss就像http和https一样的
wss://api.****.com/union-front/myHandler/uid=
location ~* /union-front/myHandler {
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Origin "";
}
当使用websocket的时候,再使用定时任务,则会报错,在Application启动类上加上如下代码即可解决这个问题
@Bean
public TaskScheduler taskScheduler() {
//使用 websockt注解的时候,使用@EnableScheduling注解启动的时候一直报错,增加这个bean 则报错解决。
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.initialize();
return taskScheduler;
}
Springboot集成WebSocket通信全部代码,即扣即用。的更多相关文章
- springboot集成websocket的两种实现方式
WebSocket跟常规的http协议的区别和优缺点这里大概描述一下 一.websocket与http http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能 ...
- springboot集成websocket实现向前端浏览器发送一个对象,发送消息操作手动触发
工作中有这样一个需示,我们把项目中用到代码缓存到前端浏览器IndexedDB里面,当系统管理员在后台对代码进行变动操作时我们要更新前端缓存中的代码怎么做开始用想用版本方式来处理,但这样的话每次使用代码 ...
- springboot集成websocket实现大文件分块上传
遇到一个上传文件的问题,老大说使用http太慢了,因为http包含大量的请求头,刚好项目本身又集成了websocket,想着就用websocket来做文件上传. 相关技术 springboot web ...
- SpringBoot集成websocket发送后台日志到前台页面
业务需求 后台为一个采集系统,需要将采集过程中产生的日志实时发送到前台页面展示,以便了解采集过程. 技能点 SpringBoot 2.x websocket logback thymeleaf Rab ...
- SpringBoot集成WebSocket【基于纯H5】进行点对点[一对一]和广播[一对多]实时推送
代码全部复制,仅供自己学习用 1.环境搭建 因为在上一篇基于STOMP协议实现的WebSocket里已经有大概介绍过Web的基本情况了,所以在这篇就不多说了,我们直接进入正题吧,在SpringBoot ...
- SpringBoot集成websocket(java注解方式)
第一种:SpringBoot官网提供了一种websocket的集成方式 第二种:javax.websocket中提供了元注解的方式 下面讲解简单的第二种 添加依赖 <dependency> ...
- SpringBoot集成WebSocket【基于STOMP协议】进行点对点[一对一]和广播[一对多]实时推送
原文详细地址,有点对点,还有广播的推送:https://blog.csdn.net/ouyzc/article/details/79884688 下面是自己处理的一些小bug 参考原文demo,结合工 ...
- springboot集成websocket点对点推送、广播推送
一.什么都不用说,导入个依赖先 <dependency> <groupId>org.springframework.boot</groupId> <artif ...
- springboot集成webSocket能启动,但是打包不了war
1.pom.xml少packing元素 https://www.cnblogs.com/zeussbook/p/10790339.html 2.SpringBoot项目中增加了WebSocket功能无 ...
随机推荐
- 设计模式21:State 状态模式(行为型模式)
State 状态模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态的行为就可能完全不同. ...
- ioctlsocket()函数是干什么用的?它返回值是什么?共有几个参数?它的各个参数是干什么用的?
1. ioctlsocket() 简述: 控制套接口的模式. #include <winsock.h> int PASCAL FAR ioctlsocket( SOCKET s, l ...
- ES 遇到的一个坑too_many_clauses: maxClauseCount
异常: Caused by: org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper: too_many_clauses: ...
- ModelMap
首先介绍ModelMap[Model]和ModelAndView的作用 Model 是一个接口, 其实现类为ExtendedModelMap,继承了ModelMap类. ModelMapModelMa ...
- 15、Semantic-UI之导航
15.1 面包屑导航 在Semantic-UI中有多种样式实现面包屑导航,类似 / > 等. 示例:定义定义基础面包屑导航 <div class="ui container& ...
- redis整理の配置
redis有一个很强大也很重要的配置文件redis.conf.此文件可以随服务启动,为服务配置各种不同场景所需的参数: daemonize: 默认情况下,redis 不是在后台运行的,如果需要在后台运 ...
- Linux系统忘记管理员密码(CentOS、RHEL、Ubuntu)
Linux系统忘记管理员密码(CentOS.RHEL.Ubuntu) 系统使用过程中,尤其是生产环境中.万一忘记管理员密码,该怎么办?是不是很绝望? 1.RHEL 7.0 重启主机进入引导界面键入e键 ...
- [HNOI2003]消防局的设立(树上距离为k的最小覆盖问题)
题目的大概意思现在有一棵树,在树上找半径小于等于2的最小覆盖点的最小个数. 题目链接 讲一讲此类题的贪心策略: 就是每次寻找最低没有被覆盖的点,显然对于覆盖它的所有点中,在他的祖先处设立一个点最优.所 ...
- pandas set_index() reset_index()
set_index() 官方定义: 使用一个或多个现有列设置索引, 默认情况下生成一个新对象 DataFrame.set_index(keys, drop=True, append=False, ...
- kali linux之Msf
目前最流行,最强大,最具扩展性的渗透测试平台软件 基于metasploit进行渗透测试和漏洞分析的流程和方法 框架集成了渗透测试标准(PETS)思想 一定程度上统一了渗透测试和漏洞研究的工作环境 新的 ...