import IO from 'socket.io-client'; import config from '@fiora/config/client'; import platform from 'platform'; import notification from './utils/notification'; import playSound from './utils/playSound'; import store from './state/store'; import { ActionTypes } from './state/action'; import { Message } from './state/reducer'; const { dispatch } = store; // 会话ID,用于服务端访问静态资源时做身份识别 const serverSessionID = String( Math.trunc(Math.random() * 10000) + Math.random(), ); let windowStatus = 'focus'; window.onfocus = () => { windowStatus = 'focus'; }; window.onblur = () => { windowStatus = 'blur'; }; // 只能通过path参数指定socket url,即使uri参数包含路径也会被忽略 const socket = IO(config.server, { autoConnect: false, path: config.socketPath, }); socket.on('connect', async () => { dispatch({ type: ActionTypes.Connect, payload: '' }); }); socket.on('disconnect', () => { // @ts-ignore dispatch({ type: ActionTypes.Disconnect, payload: null }); }); socket.on('message', async (message: Message) => { dispatch({ type: ActionTypes.AddMessage, payload: message, }); const state = store.getState(); const peerID = message.isSentBySelf ? message.toID : message.fromID; const contact = state.allContacts.get(peerID); if (!state.focusContactID) { dispatch({ type: ActionTypes.MoveFocusToNextActiveContact, payload: null, }); } if (!message.isSentBySelf && state.status.soundSwitch) { const soundType = state.status.sound; playSound(soundType); } if ( !message.isSentBySelf && windowStatus === 'blur' && state.status.notificationSwitch ) { notification( message.fromName, contact?.avatar || '', (message.isGroupMessage ? message.speakingGroupMemberName + ': ' : '') + message.content, Math.random().toString(), ); } }); // 初始化web socket连接 function initSocket(passphrase: string) { return new Promise((resolve, reject) => { if (socket.connected) { resolve(true); return; } socket.auth = { appName: config.app_name, appCode: config.app_code, passphrase, sessionID: serverSessionID, platform: platform.name || '', }; socket.connect(); socket.on('connect', () => resolve(true)); socket.on('connect_error', reject); }); } function reconnect() { return new Promise((resolve, reject) => { if (socket.connected) { return resolve(true); } if (!socket.active) { socket.connect(); } socket.on('connect', () => resolve(true)); socket.on('connect_error', reject); }); } export { socket, initSocket, reconnect, serverSessionID as sessionID };