Browse Source

disconnect io after log out

ruiyi.jiang 2 years ago
parent
commit
5d8a421c14

+ 4 - 4
client/src/App.tsx

@@ -8,8 +8,8 @@ import { WebSocketProvider } from './context/WebSocket';
 
 function App() {
   return (
-    <RootProvider>
-      <AuthProvider>
+    <AuthProvider>
+      <RootProvider>
         <WebSocketProvider>
           <NavProvider>
             <MuiPickersUtilsProvider utils={DayjsUtils}>
@@ -17,8 +17,8 @@ function App() {
             </MuiPickersUtilsProvider>
           </NavProvider>
         </WebSocketProvider>
-      </AuthProvider>
-    </RootProvider>
+      </RootProvider>
+    </AuthProvider>
   );
 }
 

+ 1 - 1
client/src/components/layout/Header.tsx

@@ -77,7 +77,7 @@ const Header: FC<HeaderType> = props => {
     await MilvusHttp.closeConnection();
     window.localStorage.removeItem(MILVUS_ADDRESS);
     // make sure we clear state in all pages
-    navigate(0);
+    // navigate(0);
   };
 
   return (

+ 18 - 1
client/src/context/Root.tsx

@@ -1,7 +1,8 @@
-import { useState, useCallback, useEffect } from 'react';
+import { useState, useCallback, useEffect, useContext } from 'react';
 import React from 'react';
 import { ThemeProvider, makeStyles } from '@material-ui/core/styles';
 import { SwipeableDrawer } from '@material-ui/core';
+import { authContext } from '../context/Auth';
 import {
   RootContextType,
   DialogType,
@@ -43,6 +44,8 @@ const { Provider } = rootContext;
 // notice type mean it's a notice dialog you need to set props like title, content, actions
 // custom type could have own state, you could set a complete component in dialog.
 export const RootProvider = (props: { children: React.ReactNode }) => {
+  const { isAuth } = useContext(authContext);
+
   const classes = makeStyles({
     paper: {
       minWidth: '300px',
@@ -117,6 +120,20 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
     fetchVersion();
   }, []);
 
+  useEffect(() => {
+    // if auth is off, hide snack bar
+    if (!isAuth) {
+      setSnackBar({
+        open: false,
+        type: 'success',
+        message: '',
+        vertical: 'top',
+        horizontal: 'right',
+        autoHideDuration: 3000,
+      });
+    }
+  }, [isAuth]);
+
   return (
     <Provider
       value={{

+ 37 - 30
client/src/context/WebSocket.tsx

@@ -1,6 +1,7 @@
-import { createContext, useEffect, useState } from 'react';
-import { io } from 'socket.io-client';
+import { createContext, useContext, useEffect, useState, useRef } from 'react';
+import { io, Socket } from 'socket.io-client';
 import { WS_EVENTS, WS_EVENTS_TYPE } from '../consts/Http';
+import { authContext } from '../context/Auth';
 import { url } from '../http/Axios';
 import { CollectionHttp } from '../http/Collection';
 import { MilvusHttp } from '../http/Milvus';
@@ -17,40 +18,46 @@ const { Provider } = webSokcetContext;
 
 export const WebSocketProvider = (props: { children: React.ReactNode }) => {
   const [collections, setCollections] = useState<CollectionView[]>([]);
+  const { isAuth } = useContext(authContext);
+  const socket = useRef<Socket | null>(null);
 
   useEffect(() => {
-    const socket = io(url);
+    if (isAuth) {
+      socket.current = io(url);
 
-    socket.on('connect', function () {
-      console.log('--- ws connected ---');
-    });
+      socket.current.on('connect', function () {
+        console.log('--- ws connected ---');
+      });
 
-    /**
-     * Because of collections data may be big, so we still use ajax to fetch data.
-     * Only when collection list includes index building or loading collection,
-     * server will keep push collections data from milvus every seconds.
-     * After all collections are not loading or building index, tell server stop pulling data.
-     */
-    socket.on(WS_EVENTS.COLLECTION, (data: any) => {
-      const collections: CollectionHttp[] = data.map(
-        (v: any) => new CollectionHttp(v)
-      );
+      /**
+       * Because of collections data may be big, so we still use ajax to fetch data.
+       * Only when collection list includes index building or loading collection,
+       * server will keep push collections data from milvus every seconds.
+       * After all collections are not loading or building index, tell server stop pulling data.
+       */
+      socket.current.on(WS_EVENTS.COLLECTION, (data: any) => {
+        const collections: CollectionHttp[] = data.map(
+          (v: any) => new CollectionHttp(v)
+        );
 
-      const hasLoadingOrBuildingCollection = collections.some(
-        v => checkLoading(v) || checkIndexBuilding(v)
-      );
+        const hasLoadingOrBuildingCollection = collections.some(
+          v => checkLoading(v) || checkIndexBuilding(v)
+        );
 
-      setCollections(collections);
-      // If no collection is building index or loading collection
-      // stop server cron job
-      if (!hasLoadingOrBuildingCollection) {
-        MilvusHttp.triggerCron({
-          name: WS_EVENTS.COLLECTION,
-          type: WS_EVENTS_TYPE.STOP,
-        });
-      }
-    });
-  }, []);
+        setCollections(collections);
+        // If no collection is building index or loading collection
+        // stop server cron job
+        if (!hasLoadingOrBuildingCollection) {
+          MilvusHttp.triggerCron({
+            name: WS_EVENTS.COLLECTION,
+            type: WS_EVENTS_TYPE.STOP,
+          });
+        }
+      });
+    } else {
+      socket.current?.disconnect();
+    }
+  }, [isAuth]);
 
   return (
     <Provider

+ 0 - 7
client/src/pages/dialogs/insert/Import.tsx

@@ -176,13 +176,6 @@ const InsertImport: FC<InsertImportProps> = ({
           </Typography>
         </div>
 
-        <div className="sampleWrapper">
-          <Typography variant="body2" className="text title">
-            {insertTrans('sample')}
-          </Typography>
-          <pre className="sample">{INSERT_CSV_SAMPLE}</pre>
-        </div>
-
         <Typography variant="body2" className="text title">
           {insertTrans('noteTitle')}
         </Typography>

+ 10 - 4
server/src/app.ts

@@ -108,19 +108,25 @@ server.listen(PORT, () => {
     pubSub.on('ws_pubsub', (msg: any) => {
       socket.emit(msg.event, msg.data);
     });
-    io.on('disconnect', () => {
-      console.info('ws disconnected');
+    socket.on('disconnect', () => {
+      console.info(
+        chalk.green(
+          `ws client disconnected ${socket.client.conn.remoteAddress}`
+        )
+      );
     });
   });
 
-  server.on('disconnect', () => {
+  server.on('disconnect', (socket: Socket) => {
     io.removeAllListeners();
   });
 
   const ips = getIp();
   ips.forEach(ip => {
     console.info(
-      chalk.cyanBright(`Attu server started: http://${ip}:${PORT}/api/v1/swagger/`)
+      chalk.cyanBright(
+        `Attu server started: http://${ip}:${PORT}/api/v1/swagger/`
+      )
     );
   });
 });