微信小程序websocket聊天室的實(shí)現(xiàn)示例代碼
背景
最近做了一個(gè)微信小程序的即時(shí)通訊功能,之前我也做過(guò)node.js的websocket服務(wù),不過(guò)是在web端應(yīng)用的socket.io服務(wù)。小程序本身對(duì)http、websocket等連接均有諸多限制,所以這次項(xiàng)目選擇了node.js自帶的ws模塊。
服務(wù)端
初始化一個(gè)node.js項(xiàng)目,引入ws模塊
const webSocket = require('ws');
創(chuàng)建websocket實(shí)例,并設(shè)置監(jiān)聽(tīng)端口
const wss = new webSocket.Server({
port: 3001
});
定義wss實(shí)例方法,實(shí)現(xiàn)socket監(jiān)聽(tīng)和信息發(fā)布。下面貼上簡(jiǎn)單的示例:
wss.on('connection', function connection(ws, req) {
console.log('連接開(kāi)啟')
//發(fā)生錯(cuò)誤
ws.on('error', function error(error) {
console.log('error', error);
});
//斷開(kāi)連接
ws.on('close', function close(close) {
console.log( '已關(guān)閉');
});
ws.on('message', function message(message) {
ws.send('客戶端發(fā)來(lái)了一條消息')
});
//發(fā)送消息
ws.send('連接已開(kāi)啟');
ws.send(id + '已連接')
});
這樣,一個(gè)簡(jiǎn)單的websocket服務(wù)就配置完成了。當(dāng)然,問(wèn)題遠(yuǎn)遠(yuǎn)不止這么簡(jiǎn)單。要想在小程序中進(jìn)行通信,還需要解決下面幾個(gè)問(wèn)題。
域名
關(guān)于小程序服務(wù)端域名配置,小程序開(kāi)發(fā)文檔中如下提到

小程序請(qǐng)求地址只支持https或者wss協(xié)議,因此首先要配置的就是SSL證書。拿到SSL證書之后,在服務(wù)端做一下https的配置即可。
var fs = require('fs');
const options = {
key: fs.readFileSync('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'utf8'),//證書地址
cert: fs.readFileSync('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'utf8'),//證書地址
};
var https = require('https');
var server = https.createServer(options, app);
另外值得注意的是,websocket監(jiān)聽(tīng)的端口號(hào)需要做一下代理,因?yàn)樾〕绦蛉绻慌渲枚丝谔?hào)時(shí),所有請(qǐng)求的url都不可以帶端口號(hào)。
多房間通信
先看一下廣播的實(shí)現(xiàn):
//廣播方法
wss.broadcast = function broadcast(data) {
wss.clients.forEach(function each(client) {
client.send(data)
});
};
wss對(duì)象的clients是一個(gè)存儲(chǔ)著所有socket連接對(duì)象的數(shù)組,每條連接對(duì)象都可以調(diào)用各自的send方法發(fā)送信息。
在此基礎(chǔ)上,我們可以進(jìn)行一定的封裝,用一個(gè)唯一的標(biāo)識(shí)符映射到每一條socket連接,這樣我們需要向特定的某個(gè)連接發(fā)送信息時(shí),就可以找到該連接。
可以通過(guò)連接的url作為唯一標(biāo)識(shí):
let sockets = {}
wss.on('connection', function connection(ws, req) {
let id = req.url.slice(5);//截幾位字符串根據(jù)自己實(shí)際獲得的url來(lái)看
sockets[id] = ws;
ws.send(id + '已連接');
...
客戶端每次連接時(shí)url后拼接一個(gè)唯一id,在服務(wù)端獲取req.url并截取字符串拿到唯一id,并將該連接對(duì)象存儲(chǔ)在全局的sockets下以便需要時(shí)使用。
在此基礎(chǔ)上,可以繼續(xù)封裝諸如加入房間、離開(kāi)房間、房間內(nèi)通信、向特定用戶私聊等功能,總體來(lái)說(shuō)是對(duì)send方法的封裝。值得注意的是send方法只能發(fā)送字符串,json對(duì)象需要轉(zhuǎn)化成字符串再傳入send。
下面是一個(gè)私聊的示例:
wss.notice = function notice(id, data, ws) {
// 向指定id發(fā)送
try {
ws.send('正在發(fā)送...')
var notice = JSON.stringify({
type: 'notice',
data: data
})
let target = sockets[id]
if (target) {
target.send('收到一條新消息')
target.send(notice)
} else {
ws.send('目標(biāo)信道已關(guān)閉')
}
} catch (err) {
console.log(err)
}
}
到這里,一個(gè)簡(jiǎn)單的聊天室服務(wù)端配置就基本完成了。
最終作品效果如下:

部分代碼細(xì)節(jié),請(qǐng)觀眾老爺們移步 微信小程序中聊天室的服務(wù)端和客戶端配置示例 ^.^
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于uniapp微信小程序左上角返回按鈕的監(jiān)聽(tīng)詳解
uniapp是一個(gè)支持多端的技術(shù),因此它是兼容性比較強(qiáng)的,而且速度也很快,下面這篇文章主要給大家介紹了關(guān)于uniapp微信小程序左上角返回按鈕監(jiān)聽(tīng)的相關(guān)資料,需要的朋友可以參考下2022-04-04
正則表達(dá)式在js前端的15個(gè)使用場(chǎng)景梳理總結(jié)
本篇帶來(lái)15個(gè)正則使用場(chǎng)景,按需索取,收藏恒等于學(xué)會(huì)?。∮行枰呐笥芽梢越梃b參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
原生js實(shí)現(xiàn)隨機(jī)點(diǎn)餐效果
一款十分簡(jiǎn)單的原生js實(shí)現(xiàn)的隨機(jī)點(diǎn)菜代碼,點(diǎn)擊點(diǎn)菜按鈕隨機(jī)點(diǎn)取上面菜單的菜品,可根據(jù)需求改成自己需要功能,比如說(shuō)隨機(jī)點(diǎn)名。感興趣的朋友來(lái)參考實(shí)現(xiàn)代碼吧2019-12-12
JS錯(cuò)誤處理與調(diào)試操作實(shí)例分析
這篇文章主要介紹了JS錯(cuò)誤處理與調(diào)試操作,結(jié)合實(shí)例形式分析了JavaScript錯(cuò)誤捕獲、處理、調(diào)試工具、斷點(diǎn)調(diào)試等相關(guān)操作技巧,需要的朋友可以參考下2020-04-04
JS實(shí)現(xiàn)刷新父頁(yè)面不彈出提示框的方法
這篇文章主要介紹了JS實(shí)現(xiàn)刷新父頁(yè)面不彈出提示框的方法,實(shí)例分析了javascript子窗口的打開(kāi)以及子窗口與父窗口的交互操作技巧,需要的朋友可以參考下2016-06-06

