SpringBoot+Vue使用WebSocket

这篇具有很好参考价值的文章主要介绍了SpringBoot+Vue使用WebSocket。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:什么是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 {

    @Bean
    public 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="";

    /**
     * 连接建立成功调用的方法
     * */
    @OnOpen
    public 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+",网络异常!!!!!!");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //从set中删除
            subOnlineCount();
        }
        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("用户消息:"+userId+",报文:"+message);
        //可以群发消息
        //消息保存到数据库、redis
        if(StringUtils.isNotBlank(message)){
            try {
                //解析发送的报文
                JSONObject jsonObject = JSONObject.parseObject(message);
                //追加发送人(防止串改)
                jsonObject.put("fromUserId",this.userId);
                String fromUserId=jsonObject.getString("fromUserId");
                //传送给对应toUserId用户的websocket
                if(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
     */
    @OnError
    public 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等同于https
      let 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) return
			this.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() { // 关闭websocket
        that.websocket.close()
    },
    //  // 收到消息处理
	  // getSocketData (res) {
	  // 	if (res.detail.data === 'success' || res.detail.data === 'heartBath') return
	  // 	// ...业务处理
	  // }
  },

 这样配置好后就可以在自己想要使用的页面添加以下示例就可以用了文章来源地址https://www.toymoban.com/news/detail-430336.html

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

到了这里,关于SpringBoot+Vue使用WebSocket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot+Vue整合WebSocket实现实时通讯

            在开发过程中,我们经常遇到需要对前台的列表数据,实现实时展示最新的几条数据,或者是调度的任务进度条实现实时的刷新......,而对于这种需求,无状态的http协议显然无法满足我们的需求,于是websocket协议应运而生。websocket协议本质上是一个基于tcp的协议

    2024年02月13日
    浏览(41)
  • 在线聊天室(Vue+Springboot+WebSocket)

    实现了一个简单的在线聊天室的前后端。前端用Vue实现,后端用Springboot实现。         在线聊天室的功能包括创建用户和显示在线用户列表、发送消息和显示消息列表、用户和消息列表实时更新这几点。以下是整体功能的活动图: 用户身份         进入聊天室的用户需

    2024年01月15日
    浏览(49)
  • SpringBoot+Vue 单页面多组WebSocket

    1.在SpringBoot的pom.xml文件里添加依赖:** 2.在配置中加入 WebSocketConfig.java** 3. 新建component文件夹,加入WebSocketServer.java** 4.Vue 5. 前后端交互 在异步请求前创建websocket,在后端用WebSocketServer.sendInfo(id,message)将信息从服务端发送给客户端,然后前端会通过setOnmessageMessage(event)来处理后

    2024年02月11日
    浏览(38)
  • SpringBoot+Vue 整合websocket实现简单聊天窗口

    1 输入临时名字充当账号使用 2 进入聊天窗口 3 发送消息 (复制一个页面,输入其他名字,方便展示效果) 4 其他窗口效果 pom依赖 WebSocketConfig.java WebSocketServer.java MessageVo.java App.vue

    2024年02月09日
    浏览(43)
  • vue+springboot+websocket实现消息通知,含应用场景

    vue、springboot 实现场景 点击同步之后更新数据,更新时间比较长,因此使用异步,之后该按钮置灰,在数据更新完成之后,服务端通知客户端已经同步成功,通知提示框,用户即可查看数据 前端 1、在对应的页面编写初始化、连接成功,错误,接受信息方法 2、mounted或者cre

    2024年02月11日
    浏览(76)
  • Vue3+springboot通过websocket实现实时通信

    本文章使用vue3+springboot通过websocket实现两个用户之间的实时通信,聊天信息使用mongodb非关系型数据库进行存储。 效果图如下: 用户发送信息  农户收到信息并发送回去 后台消息打印 引入依赖   配置 在config目录下, 创建WebSocketConfig类 创建一个WebSocketServer来 处理连接 用户

    2024年02月05日
    浏览(44)
  • 基于SpringBoot+Vue+WebSocket的在线聊天室

    WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久连接,允许客户端和服务器之间进行实时数据传输,而无需进行频繁的请求和响应。 相对于传统的 HTTP 请求-响应模式,WebSocket 在客户端和服务器之间建立起一条长久的双向通信通道。这意味着服务器可

    2024年01月16日
    浏览(67)
  • SpringBoot整合Websocket(Java websocket怎么使用)

    WebSocket 是一种基于 TCP 协议的全双工通信协议,可以在浏览器和服务器之间建立 实时、双向的数据通信 。可以用于在线聊天、在线游戏、实时数据展示等场景。与传统的 HTTP 协议不同,WebSocket 可以保持 长连接 ,实时传输数据,避免了频繁的 HTTP 请求和响应,节省了网络带

    2024年02月10日
    浏览(40)
  • SpringBoot+Netty+Vue+Websocket实现在线推送/聊天系统

    ok,那么今天的话也是带来这个非常常用的一个技术,那就是咱们完成nutty的一个应用,今天的话,我会介绍地很详细,这样的话,拿到这个博文的代码就基本上可以按照自己的想法去构建自己的一个在线应用了。比如聊天,在线消息推送之类的。其实一开始我原来的想法做在

    2024年02月03日
    浏览(39)
  • SpringBoot+WebSocket+VUE实现一个简单的聊天机器人

    要实现一个简单的聊天机器人,可以使用Spring Boot框架作为后端,使用WebSocket协议实现实时通信,使用VUE作为前端实现聊天界面。 引入jar包 在Spring Boot的配置类中添加WebSocket配置 这里的WebSocketHandler是自定义的WebSocket处理器,用于处理WebSocket消息。 做了一个简单的拦截器,实

    2023年04月19日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包