当前位置: 首页 > news >正文

Springboot整合WebSocket实现浏览器和服务器交互

Websocket定义

代码实现

引入maven依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>

配置类

  import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类*/@Configurationpublic class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

WebSocketServer 服务端

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.hc.dialer_server.service.SendMessageService;
import com.hc.dialer_server.utils.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;/*** WebSocket的操作类*/
@Component
@Slf4j
@ServerEndpoint("/websocket/{number}")
@DependsOn("springContext")
public class WebSocketServer {SendMessageService sendMessageServiceImpl = SpringContextUtils.getBean("sendMessageServiceImpl");// 记录当前在线连接数private static AtomicInteger onlineSessionClientCount = new AtomicInteger(0);// 记录number和 session的对应关系public static Map<String, Session> connectionMap = new ConcurrentHashMap<>();private String number;@OnOpenpublic void onOpen(@PathParam("number") String number, Session session) throws IOException {log.info("连接建立中 ==> session_id = {}, number = {}", session.getId(), number);// 在线人数+1onlineSessionClientCount.incrementAndGet();this.number = number;connectionMap.put(number, session);session.getBasicRemote().sendText("连接建立成功");log.info("连接建立成功, 当前在线数为: {}, session_id = {}, number = {}", onlineSessionClientCount, session.getId(), number);}@OnClosepublic void onClose(@PathParam("number") String number, Session session) {connectionMap.remove(number);onlineSessionClientCount.decrementAndGet();log.info("连接关闭成功, 当前在线数为: {} ==> 关闭该连接信息: session_id = {}, number = {}", onlineSessionClientCount, session.getId(), number);}@OnMessagepublic void onMessage(String message, Session session) throws Exception {if (StringUtils.isBlank(message)) {return;}JSONObject jsonObject = JSON.parseObject(message);String eventType = jsonObject.getString("eventType");String msg = jsonObject.getString("message");log.info("服务端收到客户端消息 ==> number = {}, eventType = {}, message = {}", number, eventType, msg);session.getBasicRemote().sendText("服务端给客户端发送消息");}@OnDisconnectpublic void onDisconnect(Session session) {connectionMap.remove(number);onlineSessionClientCount.decrementAndGet();log.info("disconnect event ==> number: {}, session_id: {}, 当前在线数: {}", number, session.getId(), onlineSessionClientCount);}@OnErrorpublic void onError(Session session, Throwable error) {log.error("WebSocket发生错误, session id = {}, 错误信息为:{}", session.getId(), error.getMessage());}}

工具类


import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component("springContext")
public class SpringContextUtils implements ApplicationContextAware {/*** Spring应用上下文环境*/private static ApplicationContext applicationContext;/*** 获取对象** @return Object 一个以所给名字注册的bean的实例*/@SuppressWarnings("unchecked")public static <T> T getBean(String name) {return (T) applicationContext.getBean(name);}/*** 获取类型为requiredType的对象*/public static <T> T getBean(Class<T> clz) {return applicationContext.getBean(clz);}/*** 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true** @return boolean*/public static boolean containsBean(String name) {return applicationContext.containsBean(name);}/*** 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)** @return boolean*/public static boolean isSingleton(String name) {return applicationContext.isSingleton(name);}/*** @return Class 注册对象的类型*/public static Class<?> getType(String name) {return applicationContext.getType(name);}@Overridepublic synchronized void setApplicationContext(ApplicationContext applicationContext) {if (SpringContextUtils.applicationContext == null) {SpringContextUtils.applicationContext = applicationContext;}}
}

前端

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>测试webSocket</title>
</head>
<body>
Client传来的number:
<!--<input type="text" th:value="${number}" id="number"/>-->
<p>【eventType】:
<div><input id="toUserId" name="toUserId" type="text" value="message"></div>
<p>【messageText】:
<div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
<p>【操作】:
<div><button type="button" onclick="sendMessage()">发送消息</button><button type="button" onclick="sendMessage1()">1626</button></div>
</body><script type="text/javascript">var socket;if (typeof (WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");} else {console.log("您的浏览器支持WebSocket");//实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接var number = '1626';console.log("number-->" + number);// socket服务器端的ip和端口var reqUrl = "http://localhost:8080/websocket/" + number;socket = new WebSocket(reqUrl.replace("http", "ws"));//打开事件socket.onopen = function () {console.log("Socket 已打开");//socket.send("这是来自客户端的消息" + location.href + new Date());};//获得消息事件socket.onmessage = function (msg) {console.log("onmessage--" + msg.data);//发现消息进入,开始处理前端触发逻辑};//关闭事件socket.onclose = function () {console.log("Socket已关闭");};//发生了错误事件socket.onerror = function () {alert("Socket发生了错误");//此时可以尝试刷新页面}}function sendMessage() {if (typeof (WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");} else {// console.log("您的浏览器支持WebSocket");var toUserId = document.getElementById('toUserId').value;var contentText = document.getElementById('contentText').value;var msg = '{"eventType":"' + toUserId + '","message":"' + contentText + '"}';console.log(msg);socket.send(msg);}}//发送json串function sendMessage1() {if (typeof (WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");} else {// console.log("您的浏览器支持WebSocket");var toUserId = document.getElementById('toUserId').value;var contentText = document.getElementById('contentText').value;// var msg = '{"eventType":"' + toUserId + '","message":"' + contentText + '"}';var msg = '{"eventType":"' + toUserId + '","message":{"number":"1626","serviceNumber":"60600","req":"event01"}}';console.log(msg);socket.send(msg);}}</script>
</html>

测试

在这里插入图片描述

http://www.lryc.cn/news/196309.html

相关文章:

  • 这些 channel 用法你都用起来了吗?
  • 纽交所上市公司安费诺宣布将以1.397亿美元收购无线解决方案提供商PCTEL
  • 二分查找算法(Python)
  • “第四十二天”
  • Qt/C++编写物联网组件/支持modbus/rtu/tcp/udp/websocket/mqtt/多线程采集
  • windows常用命令
  • 数据结构--堆
  • Android12之报错 error: BUILD_COPY_HEADERS is obsolete(一百六十七)
  • vue前端中v-model与ref的区别
  • 探索未来:硬件架构之路
  • Linux 系统安装 Redis7 —— 超详细操作演示!
  • 首次建站用香港服务器有影响没?
  • 大数据Flink(九十八):SQL函数的归类和引用方式
  • Python文件共享+cpolar内网穿透:轻松实现公网访问
  • Flink之源算子Data Source
  • 在雷电模拟器9上安装magisk并安装LSPosed模块以及其Manager管理器(一)
  • Apache atlas 元数据管理治理平台使用和架构
  • MFF论文笔记
  • Leetcode 02.07 链表相交(链表)
  • Bootstrap的媒体对象组件(图文展示组件),挺有用的一个组件。
  • Day2力扣打卡
  • 项目经理每天,每周,每月的工作清单
  • Java —— 运算符
  • 【C++ 中的友元函数:解密其神秘面纱】
  • YOLOv8涨点技巧:手把手教程,注意力机制如何在不同数据集上实现涨点的工作,内涵多种网络改进方法
  • 牛客:FZ12 牛牛的顺时针遍历
  • 函数防抖(javaScript)
  • 日常学习记录随笔-redis实战
  • MySQL事务MVCC详解
  • SQL RDBMS 概念