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功能无 ...
随机推荐
- Hibernate查询对象所有字段,单个字段 ,几个字段取值的问题
HQL 是Hibernate Query Language的简写,即 hibernate 查询语言:HQL采用面向对象的查询方式.HQL查询提供了更加丰富的和灵活的查询特性,因此Hibernate将H ...
- 获取cpu频率的代码
taskset是linux自带的一个命令,可用来将进程绑定到指定CPU 相关的函数有: sched_setaffinity, CPU_CLR, CPU_ISSET, CPU_SET, CPU_ZERO ...
- SVN错误:Attempted to lock an already-locked dir及不能提交.so文件
当使用svn提交代码时,如果中断提交,就会进入工作拷贝的锁定状态. 这是需要用svn cleanup上次关闭时的锁定 如果没有Tortises,则直接进入到上面的文件夹下的.svn目录,删除lock文 ...
- 解决svn:E155037错误(另附查看.db文件的工具)
今天使用svn提交代码的时候出问题了,Error:svn: E155037.....Previous operation has not finished; run 'cleanup' if it w ...
- Duplicate entry '127' for key 'PRIMARY'的解决方法
如果这个时候数据表里面没有数据,而且我们用使用 INSERT INTO VALUES 这样的语句插入,就会提示 Duplicate entry '127' for key 'PRIMARY'
- [LeetCode题解]: Sort Colors
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given an a ...
- win10与子系统Ubuntu 相关配置
系统间 文件访问: 1. 在win10环境下访问Ubuntu文件系统的home目录:C:\Users\xxx\AppData\Local\Packages\CanonicalGroupLimited. ...
- ASP.NET MVC中的控制器激活与反射之间的联系(帮助理解)
ASP.NET Mvc是ASP.NET的一个框架,同样也是基于管道的设计结构.HttpModule和HttpHandler是ASP.NET的两个重要组件,同样的在Mvc中也是非常重要的组件.在应用程序 ...
- django cookie、session
Cookie.Session简介: Cookie.Session是一种会话跟踪技术,因为http请求都是无协议的,无法记录上一次请求的状态,所以需要cookie来完成会话跟踪,Seesion的底层是由 ...
- 279. 完全平方数 leetcode JAVA
题目: 给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n.你需要让组成和的完全平方数的个数最少. 示例 1: 输入: n = 12 输出: 3 解释: ...