網上找的websocket的前期參考代碼,存一份,侵刪
import {Injectable} from '@angular/core'; import {interval, Subject} from 'rxjs'; /** * websocket服務 * @author LiQun * @date 2019/1/25 */ @Injectable({ providedIn: 'root' }) export class WebsocketService { messageSubject; // subject對象,用於發送事件 private url; // 默認請求的url private webSocket: WebSocket; // websocket對象 connectSuccess = false; // websocket 連接成功 period = 60 * 1000 * 10; // 10分鍾檢查一次 serverTimeoutSubscription = null; // 定時檢測連接對象 reconnectFlag = false; // 重連 reconnectPeriod = 5 * 1000; // 重連失敗,則5秒鍾重連一次 reconnectSubscription = null; // 重連訂閱對象 runTimeSubscription; // 記錄運行連接subscription runTimePeriod = 60 * 10000; // 記錄運行連接時間 constructor() { this.messageSubject = new Subject(); console.log('開始心跳檢測'); // 進入程序就進行心跳檢測,避免出現開始就連接中斷,后續不重連 this.heartCheckStart(); this.calcRunTime(); } /** * 發送消息 * @author LiQun * @date 2019/1/22 * @param message 發送消息 */ sendMessage(message) { this.webSocket.send(message); } /** * 創建新連接 * @author LiQun * @date 2019/1/22 * @param url 要連接的url */ connect(url) { if (!!url) { this.url = url; } // 創建websocket對象 this.createWebSocket(); } /** * 創建連接 * @author LiQun * @date 2019/1/22 */ createWebSocket() { // 如果沒有建立過連接,才建立連接並且添加時間監聽 this.webSocket = new WebSocket(this.url); // 建立連接成功 this.webSocket.onopen = (e) => this.onOpen(e); // 接收到消息 this.webSocket.onmessage = (e) => this.onMessage(e); // 連接關閉 this.webSocket.onclose = (e) => this.onClose(e); // 異常 this.webSocket.onerror = (e) => this.onError(e); } /** * 連接打開 * @author LiQun * @date 2019/1/22 * @param e 打開事件 */ onOpen(e) { console.log('websocket 已連接'); // 設置連接成功 this.connectSuccess = true; // 如果是重連中 if (this.reconnectFlag) { // 1.停止重連 this.stopReconnect(); // 2.重新開啟心跳 this.heartCheckStart(); // 3.重新開始計算運行時間 this.calcRunTime(); } } /** * 接受到消息 * @author LiQun * @date 2019/1/22 * @param event 接受消息事件 */ onMessage(event) { console.log('接收到的消息', event.data); // 將接受到的消息發布出去 const message = JSON.parse(event.data); console.log('接收到消息時間', new Date().getTime()); this.messageSubject.next(message); } /** * 連接關閉 * @author LiQun * @date 2019/1/22 */ private onClose(e) { console.log('連接關閉', e); this.connectSuccess = false; this.webSocket.close(); // 關閉時開始重連 this.reconnect(); this.stopRunTime(); // throw new Error('webSocket connection closed:)'); } /** * 連接異常 * @author LiQun * @date 2019/1/22 */ private onError(e) { // 出現異常時一定會進onClose,所以只在onClose做一次重連動作 console.log('連接異常', e); this.connectSuccess = false; // throw new Error('webSocket connection error:)'); } /** * 開始重新連接 * @author LiQun * @date 2019/1/22 */ reconnect() { // 如果已重連,則直接return,避免重復連接 if (this.connectSuccess) { this.stopReconnect(); console.log('已經連接成功,停止重連'); return; } // 如果正在連接中,則直接return,避免產生多個輪訓事件 if (this.reconnectFlag) { console.log('正在重連,直接返回'); return; } // 開始重連 this.reconnectFlag = true; // 如果沒能成功連接,則定時重連 this.reconnectSubscription = interval(this.reconnectPeriod).subscribe(async (val) => { console.log(`重連:${val}次`); const url = this.url; // 重新連接 this.connect(url); }); } /** * 停止重連 * @author LiQun * @date 2019/1/22 */ stopReconnect() { // 連接標識置為false this.reconnectFlag = false; // 取消訂閱 if (typeof this.reconnectSubscription !== 'undefined' && this.reconnectSubscription != null) { this.reconnectSubscription.unsubscribe(); } } /** * 開始心跳檢測 * @author LiQun * @date 2019/1/22 */ heartCheckStart() { this.serverTimeoutSubscription = interval(this.period).subscribe((val) => { // 保持連接狀態,重置下 if (this.webSocket != null && this.webSocket.readyState === 1) { console.log(val, '連接狀態,發送消息保持連接'); } else { // 停止心跳 this.heartCheckStop(); // 開始重連 this.reconnect(); console.log('連接已斷開,重新連接'); } }); } /** * 停止心跳檢測 * @author LiQun * @date 2019/1/22 */ heartCheckStop() { // 取消訂閱停止心跳 if (typeof this.serverTimeoutSubscription !== 'undefined' && this.serverTimeoutSubscription != null) { this.serverTimeoutSubscription.unsubscribe(); } } /** * 開始計算運行時間 * @author LiQun * @date 2019/1/25 */ calcRunTime() { this.runTimeSubscription = interval(this.runTimePeriod).subscribe(period => { console.log('運行時間', `${period}分鍾`); }); } /** * 停止計算運行時間 * @author LiQun * @date 2019/1/25 */ stopRunTime() { if (typeof this.runTimeSubscription !== 'undefined' && this.runTimeSubscription !== null) { this.runTimeSubscription.unsubscribe(); } } }