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功能无 ...
随机推荐
- Sql优化,面试经验总结
(1)列优先 如图有表A和表B 对其查询时,会有如下语句: select a.*,b.* from a,b where a.id = b.a_id; 注意from 后边的表名, a.如果多表查询是完全 ...
- Typora的图片根目录设置,
需求:使Typora的图片,设置到指定的文件里. 方便上传与转移. 步骤: 1 位置: 编辑 ->图片工具->设置图片根目录. 2 .Preference -> Editor -&g ...
- [LintCode笔记了解一下]80.Median
Given a unsorted array with integers, find the median of it. A median is the middle number of the ar ...
- NIOS II 自定义IP核的静态地址对齐和动态地址对齐
如果使用静态地址对齐(每个寄存器在Avalon总线上占4个字节的地址)设置IP使用静态地址对齐的方式为,在hw.tcl脚本里加上一局话:set_interface_property as addres ...
- MVC4 Filter (筛选器)
Filter,在MVC中我们通常将Filter定义成Attribute特性 来供Controller 或者Action 方法调用. FilterAttribute 是所有Filter 的基类. 而 F ...
- 20145233《网络对抗》Exp8 Web基础
20145233<网络对抗>Exp8 Web基础 实验问题思考 什么是表单? 表单在网页中主要负责数据采集功能 一个表单有三个基本组成部分: 表单标签 表单域:包含了文本框.密码框.隐藏域 ...
- 常用SQL语句集锦
MySQL适用 1.如图所示,根据Coord字段内容填充X/Y字段,并调整Coord字段格式(Coord字段原为[Latitude,Longitude]格式,需要将其调整为[Longitude,Lat ...
- Label下FormattedText中的Span无法使用Binding的解决方法
在Xamarin.Forms中,Xaml的模板功能并没有原生WPF丰富,比如Label中虽然有FormattedText可以添加Span来丰富Label的功能,但是下面的Span中的Text并没有绑定 ...
- RobotFramework做接口自动化(post请求)
接口成功时返回: { "reCorde": "SUCCESS", "data": { ", "verify": ...
- django drf Filter
1.定义get_queryset()方法 from django.shortcuts import render from rest_framework.views import APIView fr ...