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通信全部代码,即扣即用。的更多相关文章

  1. springboot集成websocket的两种实现方式

    WebSocket跟常规的http协议的区别和优缺点这里大概描述一下 一.websocket与http http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能 ...

  2. springboot集成websocket实现向前端浏览器发送一个对象,发送消息操作手动触发

    工作中有这样一个需示,我们把项目中用到代码缓存到前端浏览器IndexedDB里面,当系统管理员在后台对代码进行变动操作时我们要更新前端缓存中的代码怎么做开始用想用版本方式来处理,但这样的话每次使用代码 ...

  3. springboot集成websocket实现大文件分块上传

    遇到一个上传文件的问题,老大说使用http太慢了,因为http包含大量的请求头,刚好项目本身又集成了websocket,想着就用websocket来做文件上传. 相关技术 springboot web ...

  4. SpringBoot集成websocket发送后台日志到前台页面

    业务需求 后台为一个采集系统,需要将采集过程中产生的日志实时发送到前台页面展示,以便了解采集过程. 技能点 SpringBoot 2.x websocket logback thymeleaf Rab ...

  5. SpringBoot集成WebSocket【基于纯H5】进行点对点[一对一]和广播[一对多]实时推送

    代码全部复制,仅供自己学习用 1.环境搭建 因为在上一篇基于STOMP协议实现的WebSocket里已经有大概介绍过Web的基本情况了,所以在这篇就不多说了,我们直接进入正题吧,在SpringBoot ...

  6. SpringBoot集成websocket(java注解方式)

    第一种:SpringBoot官网提供了一种websocket的集成方式 第二种:javax.websocket中提供了元注解的方式 下面讲解简单的第二种 添加依赖 <dependency> ...

  7. SpringBoot集成WebSocket【基于STOMP协议】进行点对点[一对一]和广播[一对多]实时推送

    原文详细地址,有点对点,还有广播的推送:https://blog.csdn.net/ouyzc/article/details/79884688 下面是自己处理的一些小bug 参考原文demo,结合工 ...

  8. springboot集成websocket点对点推送、广播推送

    一.什么都不用说,导入个依赖先 <dependency> <groupId>org.springframework.boot</groupId> <artif ...

  9. springboot集成webSocket能启动,但是打包不了war

    1.pom.xml少packing元素 https://www.cnblogs.com/zeussbook/p/10790339.html 2.SpringBoot项目中增加了WebSocket功能无 ...

随机推荐

  1. 做个简单的Redis监控(源码分享)[转载]

    Redis监控 Redis 是目前应用广泛的NoSQL,我做的项目中大部分都是与Redis打交道,发现身边的朋友也更多人在用,相对于memcached 来说,它的优势也确实是可圈可点.在随着业务,数据 ...

  2. idea 提示Resource registered by this uri is not recognized (Settings | Languages & Frameworks | Schemas and DTDs)

    idea出现如上图所示的错误提示时,可以用如下方式解决 点击红色代码部分,鼠标悬停后出现红色灯泡,如下图所示 点击灯泡后,选择第一个选项就可以解决了

  3. 试题 A: 组队 蓝桥杯

    试题 A: 组队本题总分: 5 分[问题描述]作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员,组成球队的首发阵容.每位球员担任 1 号位至 5 号位时的评分如下表所示.请你计算 ...

  4. model.find(options)

    options {Object} 操作选项,会通过 parseOptions 方法解析 return {Promise} 返回单条数据 查询单条数据,返回的数据类型为对象.如果未查询到相关数据,返回值 ...

  5. Mysql自动设置时间(自动获取时间,填充时间)

    应用场景: 1.在数据表中,要记录每条数据是什么时候创建的,不需要应用程序去特意记录,而由数据数据库获取当前时间自动记录创建时间: 2.在数据库中,要记录每条数据是什么时候修改的,不需要应用程序去特意 ...

  6. HTML5+CSS3+jQuery Mobile轻松构造APP与移动网站 (陈婉凌) 中文pdf扫描版

    <HTML5+CSS3+jQuery Mobile轻松构造APP与移动网站>以HTML与CSS为主,配合jQuery制作网页,并搭配jQueryMobile制作移动网页,通过具体的范例从基 ...

  7. VS2010下安装OpenCV2.4.3

    本文记录Windows 7 X86 SP1操作系统环境下,安装与配置OpenCV2.4.3的详细步骤.前置需求:已安装有VS2010. 下载并安装OpenCV 从http://www.opencv.o ...

  8. git command cheat sheet

    clone:克隆 --non-bare:(默认值)一般的克隆方式 --bare:只克隆.git目录 --mirror:只克隆.git目录,并且还保持与origin的关联,可以fetch commit: ...

  9. Django ajax方法提交表单,及后端接受数据

    前台代码: {% block content %} <div class="wrapper wrapper-content"> <div class=" ...

  10. 并行架构技术 EasyMR

    EasyMR简介 一个并行计算软件框架 基于此框架的软件可以运行在多台计算机组成的计算集群上,并且每个计算机的计算任务也是多线程方式并行进行的,对于处理复杂的业务和巨量数据时非常用于. 有着MapRe ...