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 { t } from '../i18n' ; class SocketEventError extends Error { name = 'SocketEventError' ; } type SocketEventRespones < T = unknown > = { result : true ; data : T ; } | { result : false ; message : string ; } ; /**
 * 封装后的 Socket
 */ export class AppSocket { private listener : [ string , ( data : unknown ) => void ] [ ] = [ ] ; constructor ( private socket ) { socket . onAny ( ( eventName , data ) => { const matched = this . listener . filter ( ( [ ev ] ) => ev === eventName ) ; if ( matched . length === 0 ) { console . warn ( `[Socket IO] Unhandler event: ${ eventName }` , data ) ; return ; } matched . forEach ( ( [ , cb ] ) => { cb ( data ) ; } ) ; } ) ; } get connected ( ) : boolean { return this . socket . connected ; } async request < T = unknown > ( eventName , eventData = { } ) { return new Promise ( ( resolve , reject ) => { this . socket . emit ( eventName , eventData , ( resp ) => { if ( resp . result === true ) { resolve ( resp . data ) ; } else if ( resp . result === false ) { reject ( new SocketEventError ( resp . message ) ) ; } } ) ; } ) ; } /**
     * 监听远程通知
     */ listen < T > ( eventName , callback ) { this . listener . push ( [ `notify:${ eventName }` , callback as any ] ) ; } close ( ) { this . socket . close ( ) ; } /**
     * 断线重连后触发
     */ onReconnect ( cb ) { this . socket . on ( 'reconnect' , cb ) ; } /**
     * 初始Socket状态管理提示
     */ private closeFn : unknown = null ; setupSocketStatusTip ( ) { const socket = this . socket ; const showConnecting = ( ) => { if ( this . closeFn ) { return ; } this . closeFn = showGlobalLoading ( t ( '正在重新链接' ) ) ; } ; const closeConnecting = ( ) => { if ( this . closeFn && typeof this . closeFn === 'function' ) { this . closeFn ( ) ; } } ; socket . on ( 'connect' , ( ) => { console . log ( '连接成功' ) ; closeConnecting ( ) ; } ) ; socket . on ( 'connecting' , ( data ) => { console . log ( '正在连接' ) ; showConnecting ( ) ; } ) ; socket . on ( 'reconnect' , ( data ) => { console . log ( '重连成功' ) ; closeConnecting ( ) ; } ) ; socket . on ( 'reconnecting' , ( data ) => { console . log ( '重连中...' ) ; showConnecting ( ) ; } ) ; socket . on ( 'disconnect' , ( data ) => { console . log ( '与服务器的链接已断开' ) ; showErrorToasts ( t ( '与服务器的链接已断开' ) ) ; closeConnecting ( ) ; } ) ; socket . on ( 'connect_failed' , ( data ) => { console . log ( '连接失败' ) ; showErrorToasts ( t ( '连接失败' ) ) ; closeConnecting ( ) ; } ) ; socket . on ( 'error' , ( data ) => { console . log ( '网络出现异常' , data ) ; showErrorToasts ( t ( '网络出现异常' ) ) ; closeConnecting ( ) ; } ) ; } } let _socket ; param token export function createSocket ( token ) { if ( ! _isNil ( _socket ) ) { _socket . close ( ) ; } return new Promise ( ( resolve , reject ) => { _socket = io ( getServiceUrl ( ) , { transports : [ 'websocket' ] , auth : { token } , forceNew : true } ) ; _socket . once ( 'connect' , ( ) => { const appSocket = new AppSocket ( _socket ) ; appSocket . setupSocketStatusTip ( ) ; resolve ( appSocket ) ; } ) ; _socket . once ( 'error' , ( ) => { reject ( ) ; } ) ; if ( isDevelopment ) { _socket . onAny ( ( ... args ) => { console . debug ( 'Receive Notify:' , args ) ; } ) ; } } ) ; }