在koa中簡單使用Websocket連接的方法示例
前言
在一次項目需求會上,有個新需求是要讓用戶從管理后臺主動下發(fā)數(shù)據(jù)到app前端,從而讓前端那邊對這主動下發(fā)的數(shù)據(jù)做一些用戶交互。實現(xiàn)思路很清晰,用Websocket的方式。
Websocket 是一種自然的全雙工、雙向、單套接字連接,是建立在 TCP 協(xié)議上的。 相比于 HTTP 協(xié)議,Websocket 鏈接一旦建立,即可進(jìn)行雙向的實時通信;
ws模塊安裝
由于后臺是基于node+koa2+mongo進(jìn)行開發(fā)的。純node項目,基于node下的websocket中間件有很多,第一時間想要用的是koa-websocket。 這個中間件使用起來很簡單,這是官網(wǎng)(很簡單有時間去看一下https://www.npmjs.com/package/koa-websocket)。
可是最后,項目中還是放棄使用koa-websocket,一是因為這個中間件看著很久沒人維護(hù),后續(xù)有問題不好解決。二是這個需要重新監(jiān)聽新端口,如果只是為了一個功能而新監(jiān)聽端口,有點浪費多余。最后我選擇了ws模塊,ws文檔地址。
畢竟在Node.js中,使用最廣泛的WebSocket模塊是ws。
首先安裝ws模塊
npm install ws --save
websocket初始化
第一步:引入ws模塊
const WebSocket = require('ws')第二步: 需要創(chuàng)建一個ws服務(wù)模塊,掛載到現(xiàn)有server服務(wù)器上,目的是和原有server使用同一端口,path是指定這個websocket的請求路徑,避免無效連接。
class ws {
? ? static online = 0 // 在線連接
? ? static ws = WebSocket.Server //默認(rèn)實例
? ? static init(server) {
? ? ? ? // 創(chuàng)建實例
? ? ? ? this.ws = new WebSocket.Server({ server,path: '/**/**/websockets'});?
? ? }?
? ? // 發(fā)送客戶端數(shù)據(jù)
? ? static sendToCliect(Data) {}
}
module.exports = ws第三步:連接處理,在websocket與客戶連接中,我們需要處理各種的情況,來判斷是否要關(guān)閉斷開連接。connection事件回調(diào)函數(shù)中我們能接收到當(dāng)前連接的ws實例與當(dāng)前請求信息request。這方便我們進(jìn)行當(dāng)前連接處理
static init(server) {
? ? // 創(chuàng)建實例
? ? 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}個連接`)
? ? ? ? const {
? ? ? ? ? ? query: { id }
? ? ? ? } = quertString.parseUrl(request.url);
? ? ? ? if (!id) {
? ? ? ? ? ? return ws.close();
? ? ? ? }?
? ? ? ? try {
? ? ? ? ? ?//do something
? ? ? ? ? ?// 這里可以做一些加強判斷查詢數(shù)據(jù)庫等行為
? ? ? ? ? ? ws.id = id // 添加ws實例的唯一標(biāo)識
? ? ? ? ? ? const obj = {"message":"連接成功","retCode": 200}
? ? ? ? ? ? ws.send(JSON.stringify(obj))
? ? ? ? } catch (error) {
? ? ? ? ? ? console.log('websocket connection error',error)
? ? ? ? ? ? return ws.close();
? ? ? ? }
? ? });
} ?第四步: 掛載到項目server下,koa項目的啟動文件基本在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ù)
主動下發(fā)數(shù)據(jù),需要找到對應(yīng)的請求方,將數(shù)據(jù)準(zhǔn)確的返回到對應(yīng)的接收方,這時候就用到了在連接是添加的唯一實例標(biāo)識?,F(xiàn)在創(chuàng)建一個發(fā)送數(shù)據(jù)的函數(shù)。
class ws {
? ??
? ? // 發(fā)送客戶端數(shù)據(jù)
? ? static sendToCliect(Data) {
? ? ? ? let iskeep = false // 加個變量做下發(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ā)失敗,連接實例斷開或異常'
總結(jié)
在客戶端中,使用websocket很簡單
const ws = new WebSocket(`ws://***.***.***/websocket`)
ws.onopen = () => {
? ? console.log('WebSocket onopen')
}
ws.onmessage = e => {
? ? //接收消息并處理
}注意:ws服務(wù)是獨立于koa執(zhí)行的一個服務(wù),雖然他們共用一個端口,但是并不會經(jīng)過koa中間件,所以koa中間件有一些鑒權(quán)將失效,需要在ws服務(wù)里獨立判斷。
以上就是koa項目中簡單的使用ws模塊進(jìn)行websocket開發(fā)。
到此這篇關(guān)于在koa中簡單使用Websocket連接的方法示例的文章就介紹到這了,更多相關(guān)koa使用Websocket連接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Koa2微信公眾號開發(fā)之本地開發(fā)調(diào)試環(huán)境搭建
本篇文章主要介紹了Koa2微信公眾號開發(fā)之本地開發(fā)調(diào)試環(huán)境搭建,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05
使用nodejs?+?koa?+?typescript?集成和自動重啟的問題
這篇文章主要介紹了nodejs?+?koa?+?typescript?集成和自動重啟,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
在Node.js應(yīng)用程序中處理大數(shù)的操作指南
在JavaScript生態(tài)系統(tǒng)中,你可以使用BigInt來處理大整數(shù),但是,你也可以使用具有類似于BigInt功能的第三方庫,本文將是使用BigInt和提供類似功能的流行庫管理大數(shù)的完整指南,我們還將比較第三方庫的用例、優(yōu)勢和劣勢2023-06-06
nodejs中用npm初始化來創(chuàng)建package.json的實例講解
今天小編就為大家分享一篇nodejs中用npm初始化來創(chuàng)建package.json的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10
Nodejs處理Json文件并將處理后的數(shù)據(jù)寫入新文件中
這篇文章主要介紹了Nodejs處理Json文件并將處理后的數(shù)據(jù)寫入新文件中,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Node.js用Socket.IO做聊天軟件的實現(xiàn)示例
本文主要介紹了Node.js用Socket.IO做聊天軟件的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

