Websocket
1 建構函式
-
new WebSocket(url[, protocols])
-
引數
url
:要連線到的 URLprotocols
:單個協議字串或協議字串陣列
2 例項屬性
-
binaryType
:接收的二進位制資料的型別blob
arraybuffer
-
readyState
:websocket 連線的當前狀態
readyState 值 | mean | 解釋 |
---|---|---|
0 | connecting | 已建立 socket,連線尚未開啟 |
1 | open | 連線開啟且已做好通訊準備 |
2 | closing | 連線正在關閉 |
3 | closed | 連線已關閉 |
3 例項方法
-
close()
:關閉連線-
close(code, reason)
-
引數
code
:指示關閉原因- 1000:正常關閉
- 1001-1015:指示實際原因
-
-
send(data)
:傳送資料
4 事件
-
close
:websocket 連線關閉時觸發 close 事件-
addEventListener("close", (event) => {});
-
onclose = (event) => {};
-
屬性
code
:伺服器傳送的關閉程式碼reason
:伺服器關閉連線的原因wasClean
:是否已完全關閉
-
-
error
:與 websocket 連線由於錯誤而關閉時觸發 error 事件addEventListener("error", (event) => {});
onerror = (event) => {};
-
message
:websocket 接收到資料時觸發 message 事件-
addEventListener("message", (event) => {});
-
onmessage = (event) => {};
-
屬性
data
origin
:訊息來源
-
-
open
:與 websocket 建立連線時觸發 open 事件addEventListener("open", (event) => {});
onopen = (event) => {};
import { useState, useRef, useEffect } from 'react';
interface WebSocketOptions {
url: string;
onOpen?: () => void;
onMessage?: (message: any) => void;
onClose?: (event: Event) => void;
onError?: (event: Event) => void;
reconnectInterval?: number;
reconnectAttrmpts?: number;
}
const defaultOptions: Required<WebSocketOptions> = {
url: '', // 連線的長連線
onOpen: () => {}, // 開啟連線
onMessage: () => {}, // 訊息
onClose: () => {}, // 關閉連線
onError: () => {}, // 異常
reconnectInterval: 1000, // 重連時長設定
reconnectAttrmpts: Number.MAX_VALUE // 最大連線範圍數
};
const useWebsocket = (options: WebSocketOptions): [WebSocket | undefined, (message: any) => void, string, boolean] => {
const { url, onOpen, onClose, onMessage, onError, reconnectInterval, reconnectAttrmpts } = {
...defaultOptions,
...options
};
const [isConnected, setIsConnected] = useState(false); // 是否連線
const [reconnectCount, setReconnectCount] = useState(0); // 是否重連
const [newMessage, setNewMessage] = useState(''); // 最新訊息
const wsRef = useRef<WebSocket>();
const reconnectTimerRef = useRef<NodeJS.Timer>();
const connect = () => {
setIsConnected(false);
const ws = new WebSocket(url);
// 與 websocket 建立連線時觸發
ws.onopen = () => {
console.log('----------websocket is connected---------');
setIsConnected(true);
setReconnectCount(0);
onOpen();
};
// websocket 接收到資料時觸發
ws.onmessage = event => {
const message: any = JSON.parse(event.data);
console.log(`----------websocket reveived message: ${message}--------------`);
setNewMessage(event.data);
onMessage(message);
};
// websocket 連線關閉時觸發
ws.onclose = event => {
console.error(`-----------wesocket closed with code ${event.code}-----------`);
setIsConnected(false);
onClose(event);
// 是否重新連線
// if (reconnectCount < reconnectAttrmpts) {
// reconnectTimerRef.current = setTimeout(() => {
// setReconnectCount(prevCount => prevCount + 1);
// connect();
// }, reconnectInterval);
// }
};
// 與 websocket 連線由於錯誤而關閉時觸發
ws.onerror = event => {
console.error(`websocket error:`, event);
onClose(event);
};
wsRef.current = ws;
};
useEffect(() => {
connect();
return () => {
// 關閉連線
wsRef.current?.close();
clearTimeout(reconnectTimerRef.current);
};
}, []);
const sendMessage = (message: any): void => {
if (isConnected && wsRef.current) {
console.log(`-------websocket sending message: ${JSON.stringify(message)}--------`);
// 傳送資料
wsRef.current.send(JSON.stringify(message));
} else {
console.error('cannot send message - websocket is not connected');
}
};
return [wsRef.current, sendMessage, newMessage, isConnected];
};
export default useWebsocket;