国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

nodejs 中使用websocket 并且區(qū)分空間,實現(xiàn)收到客服端消息 同步給房間內(nèi)所有連接,小程序中使用websocket,區(qū)分房間、空間

這篇具有很好參考價值的文章主要介紹了nodejs 中使用websocket 并且區(qū)分空間,實現(xiàn)收到客服端消息 同步給房間內(nèi)所有連接,小程序中使用websocket,區(qū)分房間、空間。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??砥礪前行,不負余光,永遠在路上??

前言

因為業(yè)務需要我這里是小程序 結合 nodejs來實現(xiàn)的websocket通信

一、服務端

1、主要是通過node+express+websocket搭建

2、代碼大概結構

nodejs 中使用websocket 并且區(qū)分空間,實現(xiàn)收到客服端消息 同步給房間內(nèi)所有連接,小程序中使用websocket,區(qū)分房間、空間

3、nodejs 啟動入口文件 引入自己的websocket文件,這里是為了和 http 服務結合起來,將server傳入

自己的文件中,http.createServer(app)
客戶端那邊就可以通過以下網(wǎng)址去訪問了

ws://${IP}:3000/    // 3000也就是自己node啟動的端口 另外 + 本機ip
const { port } = require('../config/index')
var app = require('../app');
var debug = require('debug')('projectname:server');
var http = require('http');
app.set('port', port);
var server = http.createServer(app);

try {
	const Websocket = require('../utils/websocket')(server)
} catch (error) {
	console.log(error);
}

4、websocket.js 工具文件完整代碼

做個說明,這個是包含了我自己的部分業(yè)務需要,如果自己用不上數(shù)據(jù)庫相關的東西可以刪除,
我是在 headres 拿到token自己去去解析用戶信息,還在headers 中攜帶了一個用戶信息,
區(qū)分空間主要是在 連接websocket 的url上處理的,相同的房間請求同一個url,代碼中也包含了詳細注釋。

/*
 * @Date: 2023-05-24 09:23:47
 * @LastEditTime: 2023-05-26 13:51:52
 */

const jwt = require('../utils/jwt')
const { literal, Op, Sequelize } = require("sequelize");
const { User, Room, RoomUser, Record, Standings } = require('../models/index')
const { uuid } = require('../utils/index');


const WebSocket = require('ws');
module.exports = function (server) {
	try {
		// 創(chuàng)建WebSocket服務器
		const wss = new WebSocket.Server({ server });
		// 管理連接和空間的數(shù)據(jù)結構
		const connections = new Map(); // 存儲連接的Map,key為空間名稱,value為連接數(shù)組

		// 監(jiān)聽連接事件
		wss.on('connection', async function connection (ws, req) {
			addToSpace(ws, req.url.split('/')[1]);
			console.log('New client connected', '------------------------------>');
			// 在這里可以訪問 WebSocket 請求的請求頭
			let { id } = jwt.verifyToken(req.headers.token);
			const roomId = req.headers['room-id']


			//通過 id去獲取用戶信息  / 不然可能用戶更新了信息但是還是原來的token
			const res = await User.findOne({
				where: { id },
				raw: true,
			});
			//查看用戶是否加入到房間
			let userIsJoin = await Record.findOne({
				where: { roomId, fromId: id, type: '2' },
				raw: true,
			});
			if (!userIsJoin) { //沒有就加一個
				await Record.create({ id: uuid(), roomId, fromId: id, type: '2', createTime: Sequelize.fn('NOW') })
			}
			//有新的連接 也要下發(fā)信息
			console.log(`${res.nickName}加入了房間`, roomId);
			const data = { spaceName: req.url.split('/')[1], userJoin: `${res.nickName}加入了房間` }
			handleIncomingMessage(ws, JSON.stringify(data));

			// 監(jiān)聽消息接收事件
			ws.on('message', function incoming (message) {
				console.log('Received message:', message.toString('utf8'), '----------->', message);
				handleIncomingMessage(ws, message.toString('utf8'));
			});

			// 監(jiān)聽連接關閉事件
			ws.on('close', async function close () {
				console.log('Client disconnected');
				//查看用戶是否加入到房間
				let userIsJoin = await Record.findOne({
					where: { roomId, fromId: id, type: '3' },
					raw: true,
				});
				if (!userIsJoin) { //沒有就加一個
					await Record.create({ id: uuid(), roomId, fromId: id, type: '3', createTime: Sequelize.fn('NOW') })
				}

				const data = { spaceName: req.url.split('/')[1], userLeave: `${res.nickName}退出了房間` }
				handleIncomingMessage(ws, JSON.stringify(data));

				removeConnectionFromAllSpaces(ws);
			});
		});

		// 處理接收到的消息
		function handleIncomingMessage (ws, message) {
			const messageString = JSON.parse(message);
			// 假設消息格式為 "SPACE_NAME|MESSAGE_CONTENT"
			const { spaceName } = messageString
			// connection.send(content);
			const connectionsInSpace = connections.get(spaceName);
			if (connectionsInSpace) {
				// 向當前空間的所有連接發(fā)送消息
				connectionsInSpace.forEach(connection => {
					// if (connection == ws && connection.readyState === WebSocket.OPEN) {
					// 	console.log('send----------------------------');
					connection.send(JSON.stringify(messageString));
					// }
				});
			}
		}

		// 將連接添加到指定空間
		function addToSpace (ws, spaceName) {
			console.log(spaceName, '房間名稱');
			let connectionsInSpace = connections.get(spaceName);
			if (!connectionsInSpace) {
				connectionsInSpace = new Set();
				connections.set(spaceName, connectionsInSpace);
			}
			connectionsInSpace.add(ws);
		}

		// 將連接從所有空間中移除
		function removeConnectionFromAllSpaces (ws) {
			connections.forEach(connectionsInSpace => {
				connectionsInSpace.delete(ws);
			});
		}
	} catch (error) {
		console.log(error);
	}
}

二、客戶端部分

1、小程序在oonload中 連接websocket

onLoad(options) {
        console.log(options);
        const { roomNum, roomId } = options
        if (roomNum) {
                this.setData({ roomNum })
        }
        // this.getRoomInfo(wx.getStorageSync('roomId')) 這是拉取房間信息的接口  相當yu是在收到服務端消息之后自己去獲取最新的信息
        this.connectWebSocket()  // 連接WebSocket服務器
},

2、this.connectWebSocket 代碼和向服務器發(fā)送消息的代碼如下

下面的WS_URL有標注。roomNum 就是房間編號是需要客戶端這邊確定 。
// WS_URL = ws://${IP}:3000/

/**
 * 連接WebSocket服務器
 */
connectWebSocket: function () {
        var _this = this
        wx.connectSocket({
                url: WS_URL + wx.getStorageSync('roomNum'),
                header: {
                        "token": wx.getStorageSync('token'),
                        "room-id": wx.getStorageSync('roomId'),
                },
                success: (res) => {
                        console.log('WebSocket連接成功:', res)
                        // wechatSIPlayAudio('WebSocket連接成功')
                        // _this.getRoomInfo(wx.getStorageSync('roomId'))
                },
                fail: function (res) {
                        console.log('WebSocket連接失敗:', res)
                }
        })
        wx.onSocketOpen(function (res) {
                console.log('WebSocket連接已打開')
                _this.setData({ socketOpen: true })
        })
        wx.onSocketError(function (res) {
                console.log('WebSocket連接打開失敗:', res)
        })
        wx.onSocketClose(function (res) {
                console.log('WebSocket連接已關閉:', res)
                _this.setData({
                        socketOpen: false
                })
        })
        wx.onSocketMessage(function (res) {
                //  收到服務器發(fā)送的數(shù)據(jù)之后  重新拉取 更新列表  
                const data = JSON.parse(res.data)
                console.log('接收到服務器發(fā)送的數(shù)據(jù):', data)
                if (data.toId === wx.getStorageSync('userId')) {
                        getApp().util.toast(data.toMsg)
                        wechatSIPlayAudio(data.toMsg)
                        setTimeout(() => {
                                _this.getRoomInfo(wx.getStorageSync('roomId'))
                        }, 3000);
                } else {
                        _this.getRoomInfo(wx.getStorageSync('roomId'))
                }
                //用戶加入 播報
                if (data.userJoin) {
                        wechatSIPlayAudio(data.userJoin)
                }

                //用戶退出 播報
                if (data.userLeave) {
                        wechatSIPlayAudio(data.userLeave)
                }
        })
},
/**
 * 發(fā)送WebSocket消息
 */
sendSocketMessage: function (params) {
        if (this.data.socketOpen) {
                wx.sendSocketMessage({
                        data: JSON.stringify({
                                spaceName: wx.getStorageSync('roomNum'),
                                ...params
                        })
                })
        }
},

3、客戶端說明

小程序這邊邏輯 主要是在 收到服務端發(fā)送的消息之后去拉取最新的數(shù)據(jù),來更新界面。文章來源地址http://www.zghlxwxcb.cn/news/detail-469699.html

到了這里,關于nodejs 中使用websocket 并且區(qū)分空間,實現(xiàn)收到客服端消息 同步給房間內(nèi)所有連接,小程序中使用websocket,區(qū)分房間、空間的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包