柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

    • SpringBoot
    • SpringBoot3基础特性
    • SpringBoot3核心原理
    • 框架整合

      • SpringBoot SpringMVC 整合
      • SpringBoot JDBC 整合
      • SpringBoot MyBatis 整合
      • SpringBoot tk-MyBatis 整合
      • SpringBoot Shiro 整合
      • SpringBoot Redis 整合
      • SpringBoot MyBatisPlus 整合
      • SpringBoot JSON 整合
      • SpringBoot Thymeleaf 整合
      • 整合WebSocket实现聊天功能
        • 对接流程
        • im-box接入
    • SpringBoot部署
  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • SpringBoot
  • 框架整合
柏竹
2023-07-02
目录

整合WebSocket实现聊天功能

服务端 与 客户端 全双工通信 , 双方均可推动消息至对方

# 对接流程

前端发起请求

  1. 发起通信请求

    websock = new WebSocket("ws://localhost:8878/im");
    
  2. 发送消息

    websock.send(JSON.stringify(agentData))
    
  3. 回调引用

    websock.onmessage = function(e) {
    	// 通信回调
    }
    websock.onclose = function(e) {
    	// 关闭通信回调
    }
    websock.onopen = function() {
        // 通信成功回调
    }
    websock.onerror = function() {
    	// 通信异常回调
    }
    

封装的 wssocket.js

var websock = null;
let rec; //断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码
let isConnect = false; //连接标识 避免重复连接
let wsurl = "";
let userId = null;
let hasLogin = false; // 是否登录
// 回调消息
let messageCallBack = null;
let openCallBack = null;

let createWebSocket = (url, id) => {
	wsurl = url;
	userId = id;
	initWebSocket();
};

let initWebSocket = () => {
	try {
		console.log("初始化WebSocket");
		hasLogin = false;
		websock = new WebSocket(wsurl);
		websock.onmessage = function(e) {
			let sendInfo = JSON.parse(e.data)
			if (sendInfo.cmd == 0) {
				hasLogin = true;
				heartCheck.start()
				console.log('WebSocket登录成功')
				// 登录成功才算连接完成
				openCallBack && openCallBack();
			}
			else if(sendInfo.cmd==1){
				// 重新开启心跳定时
				heartCheck.reset();
			} else {
				// 其他消息转发出去
				messageCallBack && messageCallBack(sendInfo.cmd,sendInfo.data)
			}
		}
		websock.onclose = function(e) {
			console.log('WebSocket连接关闭')
			isConnect = false; //断开后修改标识
		}
		websock.onopen = function() {
			console.log("WebSocket连接成功");
			isConnect = true;
			// 发送登录命令
			let loginInfo = {
				cmd: 0,
				data: {userId: userId}
			};
			websock.send(JSON.stringify(loginInfo));
			
		}

		// 连接发生错误的回调方法
		websock.onerror = function() {
			console.log('WebSocket连接发生错误')
			isConnect = false; //连接断开修改标识
			reConnect();
		}
	} catch (e) {
		console.log("尝试创建连接失败");
		reConnect(); //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接
	}
};

//定义重连函数
let reConnect = () => {
	console.log("尝试重新连接");
	if (isConnect) return; //如果已经连上就不在重连了
	rec && clearTimeout(rec);
	rec = setTimeout(function() { // 延迟5秒重连  避免过多次过频繁请求重连
		initWebSocket(wsurl);
	}, 5000);
};
//设置关闭连接
let closeWebSocket = () => {
	websock.close();
};


//心跳设置
var heartCheck = {
	timeout: 5000, //每段时间发送一次心跳包 这里设置为20s
	timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
	start: function() {
		if(isConnect){
			console.log('发送WebSocket心跳')
			let heartBeat = {
				cmd: 1,
				data: {
					userId: userId
				}
			};
			websock.send(JSON.stringify(heartBeat))
		}
	},

	reset: function(){
		clearTimeout(this.timeoutObj);
		this.timeoutObj = setTimeout(function() {
			heartCheck.start();
		}, this.timeout);
		
	}
};



// 实际调用的方法
function sendMessage(agentData) {
	// console.log(globalCallback)
	if (websock.readyState === websock.OPEN) {
		// 若是ws开启状态
		websock.send(JSON.stringify(agentData))
	} else if (websock.readyState === websock.CONNECTING) {
		// 若是 正在开启状态,则等待1s后重新调用
		setTimeout(function() {
			sendMessage(agentData)
		}, 1000)
	} else {
		// 若未开启 ,则等待1s后重新调用
		setTimeout(function() {
			sendMessage(agentData)
		}, 1000)
	}
}


function onmessage(callback) {
	messageCallBack = callback;
}


function onopen(callback) {
	openCallBack = callback;
	if (hasLogin) {
		openCallBack();
	}
}


// 将方法暴露出去
export {
	createWebSocket,
	closeWebSocket,
	sendMessage,
	onmessage,
	onopen
}

# im-box接入

引入

<dependency>
    <groupId>com.bx</groupId>
    <artifactId>im-client</artifactId>
    <version>1.1.0</version>
</dependency>

← SpringBoot Thymeleaf 整合 SpringBoot部署→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式