xieyonghong 3 лет назад
Родитель
Сommit
b2f1f1a04b

+ 13 - 2
src/hooks/websocket/useSendWebsocketMessage.ts

@@ -16,6 +16,7 @@ enum MsgType {
 }
 
 const subscribeList: Record<string, { next: any; complete: any }[]> = {};
+const messageCache: Record<string, string> = {};
 
 export const useSendWebsocketMessage = () => {
   const messageHistory = useRef<any>([]);
@@ -41,12 +42,20 @@ export const useSendWebsocketMessage = () => {
       }
     }
   };
+
   const { sendMessage, latestMessage } = useWebSocket(url, {
-    reconnectInterval: 1000,
-    reconnectLimit: 1,
+    // reconnectInterval: 1000,
+    // reconnectLimit: 1,
     onClose: () => console.error('websocket 链接关闭'),
     onOpen: (event) => console.log('打开链接', event),
     onError: (event) => console.log('报错了', event),
+    onReconnect: () => {
+      if (Object.keys(messageCache).length && sendMessage) {
+        Object.values(messageCache).forEach((item) => {
+          sendMessage(item);
+        });
+      }
+    },
     onMessage: dispenseMessage,
   });
 
@@ -69,6 +78,7 @@ export const useSendWebsocketMessage = () => {
         complete: () => subscriber.complete(),
       });
       const message = JSON.stringify({ id, topic, parameter, type: MsgType.sub });
+      messageCache[id] = message;
       if (sendMessage) {
         sendMessage(message);
       } else {
@@ -77,6 +87,7 @@ export const useSendWebsocketMessage = () => {
       return () => {
         const unsub = JSON.stringify({ id, type: MsgType.unsub });
         delete subscribeList[id];
+        delete messageCache[id];
         sendMessage?.(unsub);
       };
     });

+ 46 - 20
src/hooks/websocket/useWebSocket.ts

@@ -11,13 +11,14 @@ export enum ReadyState {
 }
 
 export interface Options {
-  reconnectLimit?: number;
-  reconnectInterval?: number;
+  // reconnectLimit?: number;
+  // reconnectInterval?: number;
   manual?: boolean;
   onOpen?: (event: WebSocketEventMap['open']) => void;
   onClose?: (event: WebSocketEventMap['close']) => void;
   onMessage?: (message: WebSocketEventMap['message']) => void;
   onError?: (event: WebSocketEventMap['error']) => void;
+  onReconnect?: () => void;
 }
 
 export interface Result {
@@ -31,18 +32,21 @@ export interface Result {
 
 export default function useWebSocket(socketUrl: string, options: Options = {}): Result {
   const {
-    reconnectLimit = 3,
-    reconnectInterval = 3 * 1000,
+    // reconnectLimit = 3,
+    // reconnectInterval = 3 * 1000,
     manual = false,
     onOpen,
     onClose,
     onMessage,
+    onReconnect,
     onError,
   } = options;
 
-  const reconnectTimesRef = useRef(0);
-  const reconnectTimerRef = useRef<NodeJS.Timeout>();
+  const reconnectTimesRef = useRef(0); // 重连次数
+  const reconnectTimerRef = useRef<NodeJS.Timeout>(); // 计时器
   const websocketRef = useRef<WebSocket>();
+  const lockReconnect = useRef(false); // 避免重复连接
+  const isReconnect = useRef(false);
 
   const [latestMessage, setLatestMessage] = useState<WebSocketEventMap['message']>();
   const [readyState, setReadyState] = useState<ReadyState>(ReadyState.Closed);
@@ -52,7 +56,7 @@ export default function useWebSocket(socketUrl: string, options: Options = {}):
     if (ws) {
       setReadyState(ws?.readyState);
     } else {
-      if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);
+      // if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);
 
       // if (websocketRef.current) {
       //   // 此处应考虑状态。
@@ -60,16 +64,21 @@ export default function useWebSocket(socketUrl: string, options: Options = {}):
       // }
 
       try {
-        console.log(websocketRef.current, 'current');
+        // console.log(websocketRef.current, 'current');
         websocketRef.current = new WebSocket(socketUrl);
 
         websocketRef.current.onerror = (event) => {
+          isReconnect.current = true; // 开启重连
           // eslint-disable-next-line @typescript-eslint/no-use-before-define
           reconnect();
           onError?.(event);
           setReadyState(websocketRef.current?.readyState || ReadyState.Closed);
         };
         websocketRef.current.onopen = (event) => {
+          if (isReconnect.current && onReconnect) {
+            // 是否为重连
+            onReconnect();
+          }
           onOpen?.(event);
           reconnectTimesRef.current = 0;
           setReadyState(websocketRef.current?.readyState || ReadyState.Closed);
@@ -79,10 +88,12 @@ export default function useWebSocket(socketUrl: string, options: Options = {}):
           setLatestMessage(message);
         };
         websocketRef.current.onclose = (event) => {
+          isReconnect.current = true; // 开启重连
           // eslint-disable-next-line @typescript-eslint/no-use-before-define
           reconnect();
           onClose?.(event);
           setReadyState(websocketRef.current?.readyState || ReadyState.Closed);
+          Store.set(SystemConst.GLOBAL_WEBSOCKET, null);
         };
         Store.set(SystemConst.GLOBAL_WEBSOCKET, websocketRef.current);
       } catch (error) {
@@ -91,22 +102,37 @@ export default function useWebSocket(socketUrl: string, options: Options = {}):
     }
   });
 
+  const getTime = (time: number): number => {
+    const m = 60 * 1000;
+    if (time <= 5) {
+      return 3000;
+    } else if (time > 5 && time <= 10) {
+      return 10000;
+    } else if (time > 10 && time <= 20) {
+      return m;
+    }
+    return 5 * m;
+  };
+
   /**
    * 重连
    */
   const reconnect = usePersistFn(() => {
-    if (
-      reconnectTimesRef.current < reconnectLimit &&
-      websocketRef.current?.readyState !== ReadyState.Open
-    ) {
-      if (reconnectTimerRef.current) {
-        clearTimeout(reconnectTimerRef.current);
-      }
-      reconnectTimerRef.current = setTimeout(() => {
-        connectWs();
-        reconnectTimesRef.current += 1;
-      }, reconnectInterval);
+    if (lockReconnect.current) {
+      return;
     }
+
+    if (reconnectTimerRef.current) {
+      clearTimeout(reconnectTimerRef.current);
+    }
+
+    lockReconnect.current = true;
+    const _time = getTime(reconnectTimesRef.current);
+    reconnectTimerRef.current = setTimeout(() => {
+      lockReconnect.current = false;
+      reconnectTimesRef.current += 1;
+      connectWs();
+    }, _time);
   });
 
   /**
@@ -142,7 +168,7 @@ export default function useWebSocket(socketUrl: string, options: Options = {}):
   const disconnect = usePersistFn(() => {
     if (reconnectTimerRef.current) clearTimeout(reconnectTimerRef.current);
 
-    reconnectTimesRef.current = reconnectLimit;
+    reconnectTimesRef.current = 0;
     websocketRef.current?.close();
   });
 

+ 31 - 5
src/pages/device/Instance/index.tsx

@@ -519,12 +519,38 @@ const Instance = () => {
         onSearch={(data) => {
           actionRef.current?.reset?.();
           setSearchParams(data);
+          const terms1 = data.terms[0]?.terms?.map((e) => {
+            if (e.column === 'classifiedId') {
+              return {
+                column: 'productId$product-info',
+                value: [e],
+              };
+            } else {
+              return e;
+            }
+          });
+          if (data.terms && data.terms.length === 2) {
+            const terms2 = data.terms[1]?.terms?.map((e) => {
+              if (e.column === 'classifiedId') {
+                return {
+                  column: 'productId$product-info',
+                  value: [e],
+                };
+              } else {
+                return e;
+              }
+            });
+            setSearchParams({
+              ...searchParams,
+              terms: [{ terms: terms1 }, { terms: terms2, type: data.terms[1].type }],
+            });
+          } else {
+            setSearchParams({
+              ...searchParams,
+              terms: [{ terms: terms1 }],
+            });
+          }
         }}
-        // onReset={() => {
-        //   // 重置分页及搜索参数
-        //   actionRef.current?.reset?.();
-        //   setSearchParams({});
-        // }}
       />
       <ProTableCard<DeviceInstance>
         columns={columns}