webscoket实时通信实现demo【node模拟服务端】

开工前准备工作

1.前后端约定好长链接的URL

(本文举例:域名-127.0.0.1,端口号-8081,路径-/test)

2.前后端约定好发送message指令的格式

(本文格式为 {‘userId’:’ ', ‘message’: ’ '} )

前端封装可保持长链接的websocket构造函数

1.创建一个普通的websocket连接

function createWebsocket(link) {
    
    
	// 检查浏览器是否支持websocket
	if (!('WebSocket' in window) && !('MozWebSocket' in window)) {
    
    
		alert('浏览器暂不支持websocket');
	} else {
    
    
		var ws = new WebSocket(link);
		initWs(); // 初始化websocket相关的事件监听
	}
}

2.初始化websocket相关的事件监听

function initWs() {
    
    
	// 连接服务器成功触发
	ws.onopen = function(e){
    
    
    	logStatus("连接服务器成功"); // 打印log工具函数
    	...// 自定义操作
    	// 开始心跳
    	heartSend.start();
   }
   // 接收服务器的消息触发
   ws.onmessage = function(e){
    
    
   		let message = "接收到一条服务端信息,message:"+e.data+"";
    	logStatus(message);
   	 	...// 自定义操作
    	// 心跳计时器重启
   		 heartSend.reset().start();
   }   
   // 连接关闭触发
   ws.onclose = function(e){
    
    
    	logStatus("连接关闭:" + e.code + e.reason);
    	heartSend.reset();// 停止心跳
   	 	...// 自定义操作
   }
   // 连接异常触发
   ws.onerror = function(e){
    
    
    	logStatus("连接出错,error:" + e.data);
    	logStatus("正在尝试重新连接");
    	heartSend.reset();// 停止心跳
    	...// 自定义操作
    	reconnect(url);
   }
   // 封装自定义关闭连接[举例]
   ws.closeForUse = function(bool){
    
    
       // 参数、控制逻辑可依据业务具体需要自行封装,这里bool仅仅举例实现自动断开重连功能
		ws.close();
		bool && logStatus("正在尝试重新连接");
		bool && reconnect(url);
   }
   // 封装发送信息方法[同理举例,根据业务需要灵活封装即可]
   ws.sendForUse = function(clientId, msg, ...param){
    
    
		let msg = {
    
    
			'clientId': clientId,
			'msg': msg,
			 ...
		}
		ws.send(msg);
		logStatus('send: ' + msg);
   }
  
}

3.添加心跳机制[主动与服务端保持连接]

事出有因:长时间无信息通信,服务端会自动断开连接,因此可添加心跳机制间隔一段时间像服务端发送消息,主动保持联络。

var heartSend = {
    
    
	timeout: 200000, // 自定义
	timeObj: null,
	reset: function(){
    
    
		clearTimeOut(this.timeOutObj);
	},
	start: function(){
    
    
		this.timeOutObj = setTimeOut(function(){
    
    
			var msg = {
    
    'keepConnect': 'on'};
			logStatus('发送心跳信息');
			ws.send(msg);
		}, this,timeout)
	}
}

3.监听窗口关闭,处理异常

window.onbeforeunload = function(){
    
    
	ws.close(); // 关闭长连接
}

3.断开、连接异常 自动重连

function reconnect (url) {
    
    
	ws = null; // 清空上次的websocket
	setTimeOut(function(){
    
    
		createWebsocket(url)
	}, 2000)
}

4.客户端代码示例

export default function(domain) {
    
    
	let ws = null;
	let link = 'ws://' + domain + ':8081' + '/test';
	let WsFunc = function() {
    
    
		function createWebsocket(link) {
    
    ...};
		function initWs() {
    
    ...};
		var heartSend = {
    
    ...};
		function reconnect(link) {
    
    ...}createWebsocket(link); // 创建一个长连接
		// 监听窗口关闭时间,窗口关闭,主动关闭websocket连接
		window.onbeforeunload = function(){
    
    
			ws.close(); // 关闭长连接
		}

		return ws;
	}
	let logStatus = function(msg) {
    
    
		console.log(msg + '---' + new Date().toLocaleString());
	}
	window.top.wsObj = new WsFunc();
}

后端demo[简易]

var ws = require("nodejs-websocket");
var server = ws.createServer(function(obj){
    
    
  obj.on("text", function (str) {
    
    
    console.log("连接")
    obj.sendText("xxxx");
    ...
  })
  obj.on("close", function (code, reason) {
    
    
    console.log("关闭")
  });
  obj.on("error", function (code, reason) {
    
    
    console.log("异常")
  });
}).listen(8001)

猜你喜欢

转载自blog.csdn.net/m0_38073011/article/details/113354121