feat: 增加socket上下文并增加模拟重连机制的调试

release/desktop
moonrailgun 3 years ago
parent ee0a0972b5
commit 04b92b9f17

@ -2,7 +2,7 @@ import { io, Socket } from 'socket.io-client';
import _isNil from 'lodash/isNil';
import { getServiceUrl } from '../manager/service';
import { isDevelopment } from '../utils/environment';
import { showErrorToasts, showGlobalLoading } from '../manager/ui';
import { showErrorToasts, showGlobalLoading, showToasts } from '../manager/ui';
import { t } from '../i18n';
import { sharedEvent } from '../event';
@ -67,8 +67,21 @@ export class AppSocket {
this.listener.push([`notify:${eventName}`, callback as any]);
}
close() {
this.socket.close();
/**
*
* NOTICE:
*/
mockReconnect() {
this.socket.disconnect();
showToasts('reconnect after 5s');
setTimeout(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.socket.io.skipReconnect = false;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.socket.io.reconnect();
}, 5 * 1000);
}
/**

@ -63,7 +63,7 @@ export const SettingsAccount: React.FC = React.memo(() => {
// 登出
const handleLogout = useCallback(async () => {
await setUserJWT(null);
getGlobalSocket()?.close();
getGlobalSocket()?.disconnect();
history.push('/');
}, []);

@ -0,0 +1,30 @@
import { Button } from 'antd';
import React, { useEffect, useState } from 'react';
import { useSocketContext } from '@/context/SocketContext';
export const SettingsDebug: React.FC = React.memo(() => {
const socket = useSocketContext();
const [socketConnected, setSocketConnected] = useState(true);
useEffect(() => {
const id = setInterval(() => {
setSocketConnected(socket.connected);
}, 1000);
return () => {
clearInterval(id);
};
}, []);
return (
<div>
<p>Socket: {JSON.stringify(socketConnected)}</p>
<div className="space-x-1">
<Button type="primary" onClick={() => socket.mockReconnect()}>
Socket
</Button>
</div>
</div>
);
});
SettingsDebug.displayName = 'SettingsDebug';

@ -6,9 +6,10 @@ import {
} from '@/components/SidebarView';
import { pluginCustomPanel } from '@/plugin/common';
import React, { useCallback, useMemo } from 'react';
import { t } from 'tailchat-shared';
import { isDevelopment, t } from 'tailchat-shared';
import { SettingsAbout } from './About';
import { SettingsAccount } from './Account';
import { SettingsDebug } from './Debug';
import { SettingsPerformance } from './Performance';
import { SettingsStatus } from './Status';
import { SettingsSystem } from './System';
@ -58,6 +59,15 @@ export const SettingsView: React.FC<SettingsViewProps> = React.memo((props) => {
},
],
};
if (isDevelopment) {
// 仅用于开发环境
common.children.push({
type: 'item',
title: t('调试'),
content: <SettingsDebug />,
});
}
const more: SidebarViewMenuItem[] = pluginCustomPanel
.filter((p) => p.position === 'setting')
.map((p) => ({

@ -0,0 +1,21 @@
import React, { useContext } from 'react';
import type { AppSocket } from 'tailchat-shared';
const SocketContext = React.createContext<AppSocket>({} as AppSocket);
SocketContext.displayName = 'SocketContext';
export const SocketContextProvider: React.FC<{ socket: AppSocket }> =
React.memo((props) => {
return (
<SocketContext.Provider value={props.socket}>
{props.children}
</SocketContext.Provider>
);
});
SocketContextProvider.displayName = 'SocketContextProvider';
export function useSocketContext(): AppSocket {
const context = useContext(SocketContext);
return context;
}

@ -17,6 +17,8 @@ import { useHistory } from 'react-router';
import { SidebarContextProvider } from './SidebarContext';
import { PortalHost } from '@/components/Portal';
import { setGlobalSocket, setGlobalStore } from '@/utils/global-state-helper';
import { SocketContextProvider } from '@/context/SocketContext';
import { Problem } from '@/components/Problem';
/**
* hooks
@ -74,7 +76,7 @@ function useAppState() {
*
*/
export const MainProvider: React.FC = React.memo((props) => {
const { loading, store, error } = useAppState();
const { loading, store, error, socket } = useAppState();
if (loading) {
return (
@ -90,14 +92,20 @@ export const MainProvider: React.FC = React.memo((props) => {
}
if (_isNil(store)) {
return <div>{t('出现异常, Store 创建失败')}</div>;
return <Problem text={t('出现异常, Store 创建失败')} />;
}
if (_isNil(socket)) {
return <Problem text={t('出现异常, Socket 创建失败')} />;
}
return (
<ReduxProvider store={store}>
<SidebarContextProvider>
<PortalHost>{props.children}</PortalHost>
</SidebarContextProvider>
<SocketContextProvider socket={socket}>
<SidebarContextProvider>
<PortalHost>{props.children}</PortalHost>
</SidebarContextProvider>
</SocketContextProvider>
</ReduxProvider>
);
});

Loading…
Cancel
Save