1、webSocket長連接
應用場景:站內信,會員到期提醒等。webSocket只能傳輸字符串,使用node向前端發送數據的時候,使用JSON.stringify()轉換一下數據格式。在node服務端使用ws模塊來搭建webSocket服務,webSocket服務可以和express服務共存,可以寫在同一個server服務文件裏,前提是佔用不同的接口。
2、實現socket的方法:
- net
- websocket 在html5新增的,使用簡單,低版本瀏覽器不兼容。
- socket.io 兼容性最好,比較麻煩
3、實現步驟:
-
前後端連接
-
1、後端搭載socket服務器 new WebSocket.server({port: 8080}, ()=>{})
ws.on(‘connection’)
-
2、前端進行連接 new WebSocket(‘ws:localhost:8080’)
ws.onOpen()
-
-
數據交互
-
1、前端主動發送數據 ws.onmessage=()=>{}監聽
ws.send()發送數據
-
2、後端主動發送數據 ws.on(‘message’, ()=>{})監聽
-
-
斷開連接
- 1、後端斷開ws.on(‘close’)
- 2、前端斷開ws.onClose()
4、具體代碼實現步驟:
// 前端
import React, {useEffect} from 'react';
export default function WebSockets(){
const ws=new WebSocket('ws://localhost:8080');
useEffect(()=>{
ws.onopen=()=>{
console.log('webSocket服務已連接')
}
ws.onmessage=(msg)=>{
console.log('來自後端的數據'+msg.data)
}
ws.onclose=()=>{
console.log('後端主動關閉')
}
})
const handleClickSend=()=>{
ws.send('hellos');
}
return (
<div>
<h2>WebSocket頁面</h2>
<button onClick={handleClickSend}>點擊向websocket發送數據</button>
</div>
)
}
// 後端
const WebSocket=require('ws');
const ws=new WebSocket.Server({port: 8080}, ()=>{
console.log('webSocket 運行在8080端口')
})
ws.on('connection', (client)=>{
client.send('歡迎光臨'); // 只能傳輸字符串
client.on('message', (msg)=>{
console.log('收到前端傳遞的數據'+msg);
});
client.on('close', (msg)=>{
console.log('前端主動斷開連接');
});
})
如果想做某種聊天工具,需要收到前端數據後發送給所有用戶,可以使用廣播來完成。
具體後端實現:
const WebSocket=require('ws');
const ws=new WebSocket.Server({port: 8080}, ()=>{
console.log('webSocket 運行在8080端口')
})
const clients=[];
ws.on('connection', (client)=>{
clients.push(client)
client.send('歡迎光臨'); // 只能傳輸字符串
client.on('message', (msg)=>{
console.log('收到前端傳遞的數據'+msg);
sendAll(msg);
});
client.on('close', (msg)=>{
console.log('前端主動斷開連接');
});
})
// 廣播
function sendAll(msg){
for(let i=0; i<clients.length;i++){
clients[i].send(msg);
}
}
5、注意:webSocket是不存在跨域的,所以,除了正規的解決跨域方式之外,websocket長連接是解決跨域的一種方法。
6、使用socket.io進行長連接
socket.io主要思想就是傳參數,需要先自定義事件,假如想要在服務端傳遞數據給瀏覽器,需要先使用emit自定義事件auto(該自定義事件名稱隨便起,前提是前後端要對應上),在瀏覽器中觸發該事件auto,來獲得數據。同理瀏覽器想要傳遞數據給服務器,需要先使用emit自定義事件getData,在node服務觸發該自定義事件getData。
- 在服務端主要使用socket.io模塊,安裝該模塊,服務端代碼如下:
const express=require('express');
const app=express();
const server=require('http').createServer(app);
const ws=require('socket.io')(server);
ws.on('connection', (client)=>{
client.emit('auto','我是參數');
client.on('getData', (meg)=>{
console.log(meg+'從瀏覽器發過來的數據')
})
})
server.listen(8081, '0.0.0.0');
- 在前端主要使用socket.io-client插件來接收,前端代碼如下:
import React, {useEffect} from 'react';
import io from 'socket.io-client';
export default function SocketIo(){
const socket=io.connect('http://localhost:8081');
useEffect(()=>{
socket.on('auto', (msg)=>{
console.log('socket'+msg)
});
})
const handleClickSend=()=>{
socket.emit('getData', '瀏覽器數據666');
}
return (
<div>
<h2>socket.io頁面</h2>
<button onClick={handleClickSend}>點擊向websocket發送數據</button>
</div>
)
}