websocket是啥我就簡單的說一下,這個你們知道的應該挺多的。那麼首先它是一個協議,相似於咱們的HTTP協議,可是不一樣的是HTTP協議是客戶端向服務器端請求,而後服務器端響應而且只能響應一次,可是沒法作到服務器端主動向瀏覽器端推送數據。那麼websocket主要就是解決服務器端沒法向客戶端主動推送數據的。當咱們須要保持一種長連接時,咱們就須要用到websocket 使用場景以下:瀏覽器發起請求,這個請求會經歷大量的計算,而且返回給瀏覽器當前計算到了哪一步,這個時候瀏覽器就能夠展現一個彈窗告訴用戶當前已經到了哪一步,適當的更能夠展現一個進度條,避免用戶由於請求時間太長看久了loading也會膩不是。 它的主要特色就是,服務器能夠主動向客戶端推送信息,客戶端也能夠主動向服務器發送信息,是真正的雙向平等對話 特色包括: (1)創建在 TCP 協議之上,服務器端的實現比較容易。 (2)與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器。 (3)數據格式比較輕量,性能開銷小,通訊高效。 (4)能夠發送文本,也能夠發送二進制數據。 (5)沒有同源限制,客戶端能夠與任意服務器通訊。 (6)協議標識符是ws(若是加密,則爲wss),服務器網址就是 URL。前端
這邊是用node.js 的express框架進行操做,使用express-ws
插件node
cnpm i -S express-ws
複製代碼
使用express-ws插件對app進行操做,對於不是ts環境下的經過web
import express from 'express';
import expressWs from 'express-ws';
const app = express();
app = expressWs(app);
複製代碼
對於 ts 環境下的操做express
import * as express from 'express';
import * as expressWs from 'express-ws';
const appBase = express();
// 引入 websocket
let wsInstance = expressWs(appBase);
let { app } = wsInstance;
複製代碼
獲取到實例以後,能夠經過app.ws進行操做了npm
// 設置websocket
app.ws('/autoSchedule', (ws, req) => {
ws.send('已鏈接');
});
複製代碼
以前看到有說能夠經過router進行使用ws,由於router至關於一個mini 的app實例,可是我在ts環境下試了不少次都沒有成功,好比說一下代碼瀏覽器
import expres from 'express';
import expressWs from 'express-ws';
const router = expressWs(express().Router());
router.ws('/autoSchedule', (ws, req) => {
})
複製代碼
這種方式也是須要app作expressWS(app)
操做的。可是在ts下我沒有試成功過,一直包的是router沒有ws方法,或者是expressWs(express().Router())
操做時說router不是一個app實例。總之很神奇。那麼我採用的方法是,將個人業務代碼封裝成一個大的函數而後經過模塊導出,在app.ts文件下引用使用,這個操做的關鍵在於須要將app.ws('/autoSchedule',(ws: any, req: any))
回調函數中的ws傳遞給該函數,已達到模塊劃分的目的.bash
// app.ts
// 引入封裝好的函數模塊
import scheduleWs from './src/util/autoSchedule';
// 設置websocket
app.ws('/autoSchedule', (ws: any, req: any) => {
// 將 ws 傳遞給函數
scheduleWs(ws);
});
複製代碼
util/autoSchedule.ts
export default (ws: any) => {
ws.send('開始調用');
// 業務代碼
}
複製代碼
websocket在執行send
方法,發送信息的時候,send
函數的參數只支持字符串、二進制數據。因此我通常會將所須要的數據轉成 JSON字符串,而後在前端在解析,例如服務器
// 服務器端
ws.send(JSON.stringify({
code: 0,
msg: '開始調度'
}));
複製代碼
// 客戶端
ws.onmessage = (e: any) => {
let res: any = JSON.parse(e.data);
}
複製代碼
執行徹底部任務時,記得關閉socket鏈接websocket
ws.close();
複製代碼
websocket協議的接口地址是以 ws 開頭app
let ws = new WebSocket('ws://localhost:3000/autoSchedule');
複製代碼
switch (ws.readyState) {
case WebSocket.CONNECTING:
// do something
break;
case WebSocket.OPEN:
// do something
break;
case WebSocket.CLOSING:
// do something
break;
case WebSocket.CLOSED:
// do something
break;
default:
// this never happens
break;
}
複製代碼
監聽鏈接開啓
ws.onopen = () => {
console.log('已鏈接');
}
複製代碼
監聽鏈接關閉
ws.onclose = () => {
console.log('已關閉');
}
複製代碼
監聽鏈接發生錯誤
ws.onerror = (error: any) => {
console.log(error);
}
複製代碼
監聽服務器端發來的消息
ws.onmessage = (e) => {
let res = e.data;
}
複製代碼
向服務器端發送消息
ws.send('hello world');
複製代碼