網上找的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();
}
}
}
