在koa中簡(jiǎn)單使用Websocket連接的方法示例
前言
在一次項(xiàng)目需求會(huì)上,有個(gè)新需求是要讓用戶從管理后臺(tái)主動(dòng)下發(fā)數(shù)據(jù)到app前端,從而讓前端那邊對(duì)這主動(dòng)下發(fā)的數(shù)據(jù)做一些用戶交互。實(shí)現(xiàn)思路很清晰,用Websocket的方式。
Websocket 是一種自然的全雙工、雙向、單套接字連接,是建立在 TCP 協(xié)議上的。 相比于 HTTP 協(xié)議,Websocket 鏈接一旦建立,即可進(jìn)行雙向的實(shí)時(shí)通信;
ws模塊安裝
由于后臺(tái)是基于node+koa2+mongo進(jìn)行開(kāi)發(fā)的。純node項(xiàng)目,基于node下的websocket中間件有很多,第一時(shí)間想要用的是koa-websocket。 這個(gè)中間件使用起來(lái)很簡(jiǎn)單,這是官網(wǎng)(很簡(jiǎn)單有時(shí)間去看一下https://www.npmjs.com/package/koa-websocket)。
可是最后,項(xiàng)目中還是放棄使用koa-websocket,一是因?yàn)檫@個(gè)中間件看著很久沒(méi)人維護(hù),后續(xù)有問(wèn)題不好解決。二是這個(gè)需要重新監(jiān)聽(tīng)新端口,如果只是為了一個(gè)功能而新監(jiān)聽(tīng)端口,有點(diǎn)浪費(fèi)多余。最后我選擇了ws模塊,ws文檔地址。
畢竟在Node.js中,使用最廣泛的WebSocket模塊是ws。
首先安裝ws模塊
npm install ws --save
websocket初始化
第一步:引入ws模塊
const WebSocket = require('ws')第二步: 需要?jiǎng)?chuàng)建一個(gè)ws服務(wù)模塊,掛載到現(xiàn)有server服務(wù)器上,目的是和原有server使用同一端口,path是指定這個(gè)websocket的請(qǐng)求路徑,避免無(wú)效連接。
class ws {
? ? static online = 0 // 在線連接
? ? static ws = WebSocket.Server //默認(rèn)實(shí)例
? ? static init(server) {
? ? ? ? // 創(chuàng)建實(shí)例
? ? ? ? this.ws = new WebSocket.Server({ server,path: '/**/**/websockets'});?
? ? }?
? ? // 發(fā)送客戶端數(shù)據(jù)
? ? static sendToCliect(Data) {}
}
module.exports = ws第三步:連接處理,在websocket與客戶連接中,我們需要處理各種的情況,來(lái)判斷是否要關(guān)閉斷開(kāi)連接。connection事件回調(diào)函數(shù)中我們能接收到當(dāng)前連接的ws實(shí)例與當(dāng)前請(qǐng)求信息request。這方便我們進(jìn)行當(dāng)前連接處理
static init(server) {
? ? // 創(chuàng)建實(shí)例
? ? this.ws = new WebSocket.Server({ server,path: '/**/**/websockets'});?
? ? this.ws.on('connection', async (ws, request) => {
? ? ? ? if(!(request.url.includes('/**/**/websockets'))){
? ? ? ? ? ? return ws.close();
? ? ? ? }
? ? ? ? this.online = this.ws._server._connections;
? ? ? ? console.log(`socket當(dāng)前在線${this.online}個(gè)連接`)
? ? ? ? const {
? ? ? ? ? ? query: { id }
? ? ? ? } = quertString.parseUrl(request.url);
? ? ? ? if (!id) {
? ? ? ? ? ? return ws.close();
? ? ? ? }?
? ? ? ? try {
? ? ? ? ? ?//do something
? ? ? ? ? ?// 這里可以做一些加強(qiáng)判斷查詢數(shù)據(jù)庫(kù)等行為
? ? ? ? ? ? ws.id = id // 添加ws實(shí)例的唯一標(biāo)識(shí)
? ? ? ? ? ? const obj = {"message":"連接成功","retCode": 200}
? ? ? ? ? ? ws.send(JSON.stringify(obj))
? ? ? ? } catch (error) {
? ? ? ? ? ? console.log('websocket connection error',error)
? ? ? ? ? ? return ws.close();
? ? ? ? }
? ? });
} ?第四步: 掛載到項(xiàng)目server下,koa項(xiàng)目的啟動(dòng)文件基本在bin/www文件下
const app = require('../app')
const http = require('http');
const WS = require('../wss/websocket')
/**
?* Create HTTP server.
?*/
const server = http.createServer(app.callback());
/**
?* Create Socket server.
?*/
?
?WS.init(server)
?
?/**
?* Listen on provided port, on all network interfaces.
?*/
server.listen(9000,'0.0.0.0');websocket下發(fā)數(shù)據(jù)
主動(dòng)下發(fā)數(shù)據(jù),需要找到對(duì)應(yīng)的請(qǐng)求方,將數(shù)據(jù)準(zhǔn)確的返回到對(duì)應(yīng)的接收方,這時(shí)候就用到了在連接是添加的唯一實(shí)例標(biāo)識(shí)?,F(xiàn)在創(chuàng)建一個(gè)發(fā)送數(shù)據(jù)的函數(shù)。
class ws {
? ??
? ? // 發(fā)送客戶端數(shù)據(jù)
? ? static sendToCliect(Data) {
? ? ? ? let iskeep = false // 加個(gè)變量做下發(fā)成功判斷
? ? ? ? if (!(this.ws instanceof WebSocket.Server)) {
? ? ? ? ? ? return iskeep;
? ? ? ? }
? ? ? ? const {id } = Data
? ? ? ? this.ws.clients.forEach((client) => {
? ? ? ? ? ? if (client.readyState === WebSocket.OPEN && client.id === id) {?
? ? ? ? ? ? ? ? // 發(fā)送給指定匹配id
? ? ? ? ? ? ? ? client.send(JSON.stringify(Data));
? ? ? ? ? ? ? ? iskeep = true
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? return iskeep;?
? ? }
}使用
const WS = require('../wss/websocket')
// do something?
const data ={}
const send = ?WS.sendToCliect(data) // 下發(fā)數(shù)據(jù)
if(send){
? ? return 'success'?
}return '下發(fā)失敗,連接實(shí)例斷開(kāi)或異常'
總結(jié)
在客戶端中,使用websocket很簡(jiǎn)單
const ws = new WebSocket(`ws://***.***.***/websocket`)
ws.onopen = () => {
? ? console.log('WebSocket onopen')
}
ws.onmessage = e => {
? ? //接收消息并處理
}注意:ws服務(wù)是獨(dú)立于koa執(zhí)行的一個(gè)服務(wù),雖然他們共用一個(gè)端口,但是并不會(huì)經(jīng)過(guò)koa中間件,所以koa中間件有一些鑒權(quán)將失效,需要在ws服務(wù)里獨(dú)立判斷。
以上就是koa項(xiàng)目中簡(jiǎn)單的使用ws模塊進(jìn)行websocket開(kāi)發(fā)。
到此這篇關(guān)于在koa中簡(jiǎn)單使用Websocket連接的方法示例的文章就介紹到這了,更多相關(guān)koa使用Websocket連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Node.js+Koa框架實(shí)現(xiàn)前后端交互的方法
這篇文章主要給大家介紹了利用Node.js+Koa框架實(shí)現(xiàn)前后端交互的方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-02-02
node.js使用yargs處理命令行參數(shù)操作示例
這篇文章主要介紹了node.js使用yargs處理命令行參數(shù)操作,結(jié)合實(shí)例形式分析了yargs庫(kù)的安裝及node.js使用yargs處理命令行參數(shù)具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2020-02-02
Node.js中的package.json與cnpm命令行工具介紹
這篇文章介紹了Node.js中的package.json與cnpm命令行工具,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
node的EventEmitter模塊基本用法簡(jiǎn)單實(shí)現(xiàn)示例
這篇文章主要為大家介紹了node的EventEmitter模塊基本用法簡(jiǎn)單實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
nodeJS實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁(yè)爬蟲(chóng)功能的實(shí)例(分享)
下面小編就為大家?guī)?lái)一篇nodeJS實(shí)現(xiàn)簡(jiǎn)單網(wǎng)頁(yè)爬蟲(chóng)功能的實(shí)例(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
Node實(shí)現(xiàn)前端本地開(kāi)發(fā)接口代理服務(wù)
本文主要介紹了Node實(shí)現(xiàn)前端本地開(kāi)發(fā)接口代理服務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

