一:什么是Websocket?

  • WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)
  • 它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
  • Websocket是一个持久化的协议

二:websocket的原理

1.websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个            类似tcp的连接,从而方便它们之间的通信,在websocket出现之前,web交互一般是基于http            协议的短连接或者长连接
         2.websocket是一种全新的协议,不属于http无状态协议,协议名为"ws"

三:后端代码

        1.导入maven

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

2.配置Config

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/**
* @Author: 海绵宝宝
* @Explain: 开启webSocket  在线测试地址:http://www.websocket-test.com/
* @DateTime: 2022/5/29 15:54
* @Params:
* @Return
*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter(){return new ServerEndpointExporter();}
}

3.配置Server

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.HashMap;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author: 海绵宝宝
* @Explain: WebSocket
* @DateTime: 2022/5/29 15:54
* @Params: WebSocketServer.sendInfo(使用JSON,用户名);
* @Return
*/
@ServerEndpoint("/websocket/{userId}")
@Component
@Slf4j
public class WebSocketServer {/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/private static int onlineCount = 0;/**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/private static ConcurrentHashMap<String, WebSocketServer> webSocketMap = new ConcurrentHashMap<>();/**与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;/**接收userId*/private String userId="";/*** 连接建立成功调用的方法* */@OnOpenpublic void onOpen(Session session, @PathParam("userId") String userId) {this.session = session;this.userId=userId;if(webSocketMap.containsKey(userId)){webSocketMap.remove(userId);//加入set中}else{webSocketMap.put(userId,this);//加入set中addOnlineCount();//在线数加1}log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());try {HashMap<Object, Object> map = new HashMap<>();map.put("key","连接成功");sendMessage(JSON.toJSONString(map));} catch (IOException e) {log.error("用户:"+userId+",网络异常!!!!!!");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {if(webSocketMap.containsKey(userId)){webSocketMap.remove(userId);//从set中删除subOnlineCount();}log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());}/*** 收到客户端消息后调用的方法** @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, Session session) {log.info("用户消息:"+userId+",报文:"+message);//可以群发消息//消息保存到数据库、redisif(StringUtils.isNotBlank(message)){try {//解析发送的报文JSONObject jsonObject = JSONObject.parseObject(message);//追加发送人(防止串改)jsonObject.put("fromUserId",this.userId);String fromUserId=jsonObject.getString("fromUserId");//传送给对应toUserId用户的websocketif(StringUtils.isNotBlank(fromUserId) && webSocketMap.containsKey(fromUserId)){webSocketMap.get(fromUserId).sendMessage(jsonObject.toJSONString());//自定义-业务处理//                    DeviceLocalThread.paramData.put(jsonObject.getString("group"),jsonObject.toJSONString());}else{log.error("请求的userId:"+fromUserId+"不在该服务器上");//否则不在这个服务器上,发送到mysql或者redis}}catch (Exception e){e.printStackTrace();}}}/***  发生错误时候* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("用户错误:"+this.userId+",原因:"+error.getMessage());error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {//加入线程锁synchronized (session){try {//同步发送信息this.session.getBasicRemote().sendText(message);} catch (IOException e) {log.error("服务器推送失败:"+e.getMessage());}}}/*** 发送自定义消息* *//*** 发送自定义消息* @param message 发送的信息* @param toUserId  如果为null默认发送所有* @throws IOException*/public static void sendInfo(String message,String toUserId) throws IOException {//如果userId为空,向所有群体发送if(StringUtils.isEmpty(toUserId)) {//向所有用户发送信息Iterator<String> itera = webSocketMap.keySet().iterator();while (itera.hasNext()) {String keys = itera.next();WebSocketServer item = webSocketMap.get(keys);item.sendMessage(message);}}//如果不为空,则发送指定用户信息else if(webSocketMap.containsKey(toUserId)){WebSocketServer item = webSocketMap.get(toUserId);item.sendMessage(message);}else{log.error("请求的userId:"+toUserId+"不在该服务器上");}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}public static synchronized ConcurrentHashMap<String, WebSocketServer> getWebSocketMap(){return WebSocketServer.webSocketMap;}
}

后端配置好后可以在  http://www.websocket-test.com/ 中测试 :

地址示例: ws://127.0.0.1:8082/websocket/test

四:配置前端

1.在App.vue中

配置参数


data() {return {// socket参数socket: null,timeout: 10 * 1000, // 45秒一次心跳timeoutObj: null, // 心跳心跳倒计时serverTimeoutObj: null, // 心跳倒计时timeoutnum: null, // 断开 重连倒计时lockReconnect: false, // 防止websocket: null}},

在mounted中初始化

mounted () {this.initWebSocket();},

在methods中写方法

methods: {initWebSocket() {// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于httpslet wsUrl = 后端地址;this.websocket = new WebSocket(wsUrl);this.websocket.onopen = this.websocketonopen;this.websocket.onerror = this.websocketonerror;this.websocket.onmessage = this.setOnmessageMessage;this.websocket.onclose = this.websocketclose;// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。// window.onbeforeunload = that.onbeforeunload},start() {console.log('start');console.log(this.$store.getters.name)//清除延时器this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(() => {if (this.websocket && this.websocket.readyState == 1) {let actions = {"test":"12345"};this.websocket.send(JSON.stringify(actions));//发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数} else {this.reconnect();}//定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接this.serverTimeoutObj = setTimeout(() => {this.websocket.close();}, this.timeout)}, this.timeout)},reset() { // 重置心跳// 清除时间clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);// 重启心跳this.start();},// 重新连接reconnect() {if (this.lockReconnect) returnthis.lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多this.timeoutnum && clearTimeout(this.timeoutnum);this.timeoutnum = setTimeout(() => {this.initWebSocket();this.lockReconnect = false;}, 5000)},async setOnmessageMessage(event) {// console.log(event.data, '获得消息');this.reset();// 自定义全局监听事件window.dispatchEvent(new CustomEvent('onmessageWS', {detail: {data: event.data}}))// //发现消息进入    开始处理前端触发逻辑// if (event.data === 'success' || event.data === 'heartBath') return},websocketonopen() {//开启心跳this.start();console.log("WebSocket连接成功!!!"+new Date()+"----"+this.websocket.readyState);clearInterval(this.otimer);//停止},websocketonerror(e) {console.log("WebSocket连接发生错误" + e);},websocketclose(e) {this.websocket.close();clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);console.log("WebSocket连接关闭");},websocketsend(messsage) {that.websocket.send(messsage)},closeWebSocket() { // 关闭websocketthat.websocket.close()},//  // 收到消息处理// getSocketData (res) {//  if (res.detail.data === 'success' || res.detail.data === 'heartBath') return//    // ...业务处理// }},

这样配置好后就可以在自己想要使用的页面添加以下示例就可以用了

mounted() {// 添加socket通知监听window.addEventListener('onmessageWS', this.getSocketData)},
methods: {// 收到消息处理getSocketData (res) {console.log(res.detail.data)},
}

SpringBoot+Vue使用WebSocket相关推荐

  1. SpringBoot+Vue整合WebSocket实现前后端消息推送

    场景 WebSocket HTTP 协议是一种无状态的.无连接的.单向的应用层协议.它采用了请求/响应模型.通信请求只能由客户端发起,服务端对请求做出应答处理. 这种通信模型有一个弊端:HTTP 协议 ...

  2. springboot+VUE整合websocket

    引入maven <!--webSocket--><dependency><groupId>org.springframework.boot</groupId& ...

  3. springboot+vue用websocket消息推送和监听端口

    文章目录 后端代码 websocket接口: 开启线程监听tcp连接: 前端代码 流程: 后端开启线程监听某个端口是否接收到tcp的数据,如果接收到数据则向前端推送消息,前端接收到消息后进行接收消息的 ...

  4. SpringBoot + Vue 实现基于 WebSocket 的聊天室(单聊)

    前言 在前一篇文章SpringBoot 集成 STOMP 实现一对一聊天的两种方法中简单介绍了如何利用 STOMP 实现单聊,本文则将以一个比较完整的示例展示实际应用,不过本文并未使用 STOMP,而 ...

  5. 基于springBoot、Vue、websocket的聊天系统:数据库设计

    一般来说,需求出来之后,经过需求评审后,就需要进行数据库的设计了,毕竟后续功能的开发,很大程度上依赖于表结构的设计,下面简单聊聊web聊天系统的数据库是如何设计的.如需更全面的了解该系统,可以阅读相关 ...

  6. 【系统开发】WebSocket + SpringBoot + Vue 搭建简易网页聊天室

    文章目录 一.数据库搭建 二.后端搭建 2.1 引入关键依赖 2.2 WebSocket配置类 2.3 配置跨域 2.4 发送消息的控制类 2.5 R类 三.前端搭建 3.1 自定义文件websock ...

  7. springboot+vue前后端分离实现宿舍管理系统

    ​ 作者主页:编程指南针简介:Java领域优质创作者.CSDN博客专家 Java项目.简历模板.学习资料.面试题库.技术互助文末获取源码​ 项目编号:BS-GX-032 开发技术: 后台:Spring ...

  8. SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版)

    场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_BADAO_LIUMANG_QIZHI的博客-CSDN博客 SpringBoot+Vue+O ...

  9. 阿里首推的“SpringBoot+Vue全栈项目”有多牛X?

    Spring Boot致力于简化开发配置并为企业级开发提供一系列非业务性功能, 而Vue则采用数据驱动视图的方式将程序员从繁琐的DOM操作中解救出来.利用Spring Boot+Vue,我们可以快速开 ...

最新文章

  1. 雄鹰与蜗牛 2017-10-26
  2. C++ setprecision()用法
  3. ActiveMQ群集,持久订阅者和虚拟主题可助您一臂之力
  4. Memcached总结三:Memcached常用命令及使用说明
  5. 深入沟通的重要性——《大道至简》第四章读后感
  6. 每晚有1700万人逛淘宝但什么都不买,马云:我们仍可以靠他们赚钱
  7. [python] ZZ 随机数生成
  8. 前后端分离 与 不分离
  9. PPT双屏抽奖,大气,能Hold住全场!与其它PPT内容可融为一体,实现无缝切换!
  10. html5抖动效果代码,JS文字抖动特效代码
  11. 中文汉化AE扩展脚本 AtomX 3.0.0 不断更新预设包文件
  12. 2020 03 15 蚂蚁金服实习电话一面
  13. 2022年人工智能数据标注产业现状分析
  14. 使用Python脚本进行批量造数据
  15. 论文浏览(45) MiCT: Mixed 3D/2D Convolutional Tube for Human Action Recognition
  16. 笔记本win10安装教程
  17. App架构师实践指南四之性能优化一
  18. 线性函数,C语言方式实现
  19. 计算机一级等级考试模拟试题,全国计算机一级等级考试模拟试题.docx
  20. 技术美术面试问题整理

热门文章

  1. 基于SPRINGBOOT果多多水果电商平台
  2. 杰理之AC695_3.0.4_SDK做发射器连接接收器无声问题解决方法【篇】
  3. andorid开发关键技术
  4. 2018 in Restrospect
  5. 想升职?不妨和老板争一争!
  6. 面试题:选择一篇英语文章,统计文章中所有单词出现的次数,单词的长度以及每个单词中每个字母出现的次数
  7. linux 批量查找关键词,Linux上批量查找文件里面带的关键字(grep 关键字的用法)
  8. 信息系统开发与管理【六】之 系统设计
  9. 信号与传输介质和计算机进制转换
  10. “哥伦布”华为,与智能联接新大陆