| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- import env from "../config/env.js";
- class WebSocketService {
- constructor() {
- this.socketTask = null;
- this.isConnected = false;
- this.reconnectAttempts = 0;
- this.maxReconnectAttempts = 5;
- this.reconnectInterval = 3000; // 3秒重连
- this.heartbeatInterval = 60000; // 60秒发送一次心跳
- this.heartbeatTimer = null;
- this.reconnectTimer = null;
- }
- async connect() {
- // 先关闭之前的连接
- // await this.disconnect();
- const userId = uni.getStorageSync("userInfo").userId;
- const baseUrl = env.baseUrl.replace("https://", "");
- const wsUrl = `wss://${baseUrl}/ws?userId=${userId}`;
- console.log("Attempting to connect to WebSocket:", wsUrl);
- return new Promise((resolve, reject) => {
- try {
- this.socketTask = uni.connectSocket({
- url: wsUrl,
- complete: () => {
- console.log("WebSocket connection attempt completed");
- },
- });
- if (!this.socketTask) {
- console.error("Failed to create socket task");
- reject(new Error("Failed to create socket task"));
- return;
- }
- // 监听连接打开
- this.socketTask.onOpen(() => {
- console.log("WebSocket connected successfully");
- this.isConnected = true;
- this.reconnectAttempts = 0;
- // 启动心跳
- this.startHeartbeat();
- resolve();
- });
- // 监听消息
- this.socketTask.onMessage((res) => {
- try {
-
- // 先解析 JSON 字符串
- const data = JSON.parse(res.data);
- // 判断是否是心跳响应
- if (data.message === "PONG") {
- return;
- }
- switch (data.type) {
- case "INIT":
- uni.$emit("init", data);
- break;
- case "RUNNING":
- uni.$emit("newMessage", data);
- break;
- case "NEW_RECORD":
- uni.$emit("newRecord", data);
- break;
- default:
- console.log("Unknown message type:", data.type);
- }
- } catch (error) {
- console.error("Failed to parse WebSocket message:", error);
-
- }
- });
- // 监听连接关闭
- this.socketTask.onClose((res) => {
- console.log("WebSocket closed:", res);
- this.isConnected = false;
- this.stopHeartbeat();
- if (
- !res.wasClean &&
- this.reconnectAttempts < this.maxReconnectAttempts
- ) {
- this.reconnectAttempts++;
- console.log(
- `Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
- );
- this.reconnectTimer = setTimeout(
- () => this.connect(),
- this.reconnectInterval
- );
- }
- });
- // 监听错误
- this.socketTask.onError((error) => {
- console.error("WebSocket error:", error);
- this.isConnected = false;
- this.stopHeartbeat();
- reject(error);
- });
- } catch (error) {
- console.error("Failed to create WebSocket connection:", error);
- reject(error);
- }
- });
- }
- // 启动心跳
- startHeartbeat() {
- this.stopHeartbeat(); // 先清除可能存在的定时器
- this.heartbeatTimer = setInterval(() => {
- if (this.isConnected) {
- this.send({ type: "PING" });
- }
- }, this.heartbeatInterval);
- }
- // 停止心跳
- stopHeartbeat() {
- if (this.heartbeatTimer) {
- clearInterval(this.heartbeatTimer);
- this.heartbeatTimer = null;
- }
- }
- async disconnect() {
- this.stopHeartbeat();
- if (this.reconnectTimer) {
- clearTimeout(this.reconnectTimer);
- this.reconnectTimer = null;
- }
- return new Promise((resolve) => {
- if (this.socketTask) {
- this.socketTask.close({
- success: () => {
- console.log("WebSocket disconnected successfully");
- this.socketTask = null;
- this.isConnected = false;
- resolve();
- },
- fail: (error) => {
- console.error("Failed to disconnect WebSocket:", error);
- this.socketTask = null;
- this.isConnected = false;
- resolve();
- },
- });
- } else {
- resolve();
- }
- });
- }
- async send(message) {
- if (!this.isConnected || !this.socketTask) {
- console.error("WebSocket is not connected");
- return false;
- }
- return new Promise((resolve, reject) => {
- this.socketTask.send({
- data: JSON.stringify(message),
- success: () => {
- console.log("Message sent successfully");
- resolve(true);
- },
- fail: (error) => {
- console.error("Failed to send message:", error);
- reject(error);
- },
- });
- });
- }
- }
- // 创建单例
- const websocketService = new WebSocketService();
- export default websocketService;
|