diff --git a/src/pages/Report/index.jsx b/src/pages/Report/index.jsx index ce8a0d4..866ecdf 100755 --- a/src/pages/Report/index.jsx +++ b/src/pages/Report/index.jsx @@ -69,12 +69,10 @@ export const Report = memo(({ idWell }) => { } } - const unSubscribeReportHub = Subscribe( - 'hubs/reports', - 'GetReportProgress', - `Report_${taskId}`, - handleReportProgress - ) + const unSubscribeReportHub = Subscribe('hubs/reports', `Report_${taskId}`, { + methodName: 'GetReportProgress', + handler: handleReportProgress, + }) }, setShowLoader, `Не удалось создать отчет по скважине (${idWell}) c diff --git a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx index db5c547..b2fd566 100755 --- a/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx +++ b/src/pages/Telemetry/TelemetryView/ActiveMessagesOnline.jsx @@ -29,7 +29,10 @@ export const ActiveMessagesOnline = memo(({ idWell }) => { `Не удалось загрузить сообщения по скважине "${idWell}"`, 'Получение списка сообщений' ) - return Subscribe('hubs/telemetry','ReceiveMessages', `well_${idWell}`, handleReceiveMessages) + return Subscribe('hubs/telemetry',`well_${idWell}`, { + methodName: 'ReceiveMessages', + handler: handleReceiveMessages, + }) }, [idWell, handleReceiveMessages]) return ( diff --git a/src/pages/Telemetry/TelemetryView/index.jsx b/src/pages/Telemetry/TelemetryView/index.jsx index 87370e6..c11ae6f 100755 --- a/src/pages/Telemetry/TelemetryView/index.jsx +++ b/src/pages/Telemetry/TelemetryView/index.jsx @@ -323,8 +323,11 @@ export default function TelemetryView({ idWell }) { const handleDataSpin = useCallback((data) => data && setDataSpin(data), []) useEffect(() => { - const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) - const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin) + const unsubscribe = Subscribe( + 'hubs/telemetry', `well_${idWell}`, + { methodName: 'ReceiveDataSaub', handler: handleDataSaub }, + { methodName: 'ReceiveDataSpin', handler: handleDataSpin } + ) invokeWebApiWrapperAsync( async () => { const flowChart = await DrillFlowChartService.get(idWell) @@ -338,10 +341,7 @@ export default function TelemetryView({ idWell }) { `Не удалось получить данные по скважине "${idWell}"`, 'Получение данных по скважине' ) - return () => { - unsubscribeSaub() - unsubscribeSpin() - } + return unsubscribe }, [idWell, chartInterval, handleDataSpin, handleDataSaub]) useEffect(() => invokeWebApiWrapperAsync( diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts index a87a5e3..b55982a 100755 --- a/src/services/signalr/index.ts +++ b/src/services/signalr/index.ts @@ -1,25 +1,22 @@ -import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr'; +import { getUserToken } from '@asb/utils/storage' +import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr' // SignalR js api: //https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest const ConnectionOptions = { - accessTokenFactory: () => localStorage['token'], - transport:1, + accessTokenFactory: () => getUserToken() ?? '', + transport: 1, } -type ConnectionsDict = { - [route: string]: HubConnection; -}; +type ConnectionsDict = Record //var baseUrl = `http://192.168.1.70:5000` -var baseUrl = process.env.NODE_ENV === 'development' - ? require('../../../package.json').proxy - :'' +const baseUrl = process.env.NODE_ENV === 'development' ? require('../../../package.json').proxy : '' const Connections: ConnectionsDict = { 'hubs/telemetry': new HubConnectionBuilder() - .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)// + .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions) .withAutomaticReconnect() .build(), @@ -31,57 +28,67 @@ const Connections: ConnectionsDict = { let connectionPromise: Promise -const GetConnectionAsync = async (hubUrl: string) => { +export const GetConnectionAsync = async (hubUrl: string): Promise => { + const Connection: HubConnection = Connections[hubUrl] - let Connection: HubConnection = Connections[hubUrl]; + if (Connection.state === HubConnectionState.Disconnected) + connectionPromise = Connection.start() - if (Connection.state === HubConnectionState.Disconnected) - connectionPromise = Connection.start() - - if (Connection.state !== HubConnectionState.Connected) - await connectionPromise - - return Connection - } + if (Connection.state !== HubConnectionState.Connected) + await connectionPromise -type handlerFunction = (...args: any[]) => void; + return Connection +} -type cleanFunction = (...args: any[]) => void; +type handlerFunction = (...args: any[]) => void +type cleanFunction = (...args: any[]) => void + +export type SubscribeGroup = { + methodName: string, + handler: handlerFunction, +} const MakeUnsubscribeFunction = ( connection: HubConnection, - methodName: string, - groupName: (string|null)):cleanFunction => { - return async() => { - if(connection.state === HubConnectionState.Connected) - { - if(groupName) - await connection.send('RemoveFromGroup', groupName) - connection.off(methodName) + groupName: string[] | string | null, + ...groups: SubscribeGroup[] +): cleanFunction => async() => { + if(connection.state === HubConnectionState.Connected) { + if (groupName) { + if (Array.isArray(groupName)) { + for (const g of groupName) + await connection.send('RemoveFromGroup', g) + } else await connection.send('RemoveFromGroup', groupName) } - connection.stop() + for (const g of groups) + connection.off(g.methodName) } + connection.stop() } /** Subscribe on some SignalR method (topic). - * @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]); - * @param {string} methodName name of the method - * @param {string} groupName name of the group - * @param {handlerFunction} handler fires when got new data by subscription + * @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]); + * @param {string[] | string} groupName name of the group(-s) + * @param {SubscribeGroup} groups groups obtains method name and handler which fires when got new data by subscription * @return {cleanFunction} unsubscribe function for useEffect cleanup. */ -const Subscribe = ( +export const Subscribe = ( hubUrl: string, - methodName: string, - groupName: string = '', - handler: handlerFunction ):cleanFunction=>{ + groupName: string[] | string = '', + ...groups: SubscribeGroup[] +): cleanFunction => { GetConnectionAsync(hubUrl).then(async connection => { - if(groupName) - await connection.send('AddToGroup', groupName) - connection.on(methodName, handler) + if (groupName) { + if (Array.isArray(groupName)) { + for (const g of groupName) + await connection.send('AddToGroup', g) + } else await connection.send('AddToGroup', groupName) + } + for (const g of groups) + connection.on(g.methodName, g.handler) }) - return MakeUnsubscribeFunction(Connections[hubUrl],methodName,groupName) + return MakeUnsubscribeFunction(Connections[hubUrl], groupName, ...groups) } /** Invokes some SignalR method. @@ -89,13 +96,9 @@ const Subscribe = ( * @param {any[]} args methods arguments * @return {Promise} Promise */ -const InvokeAsync = async (methodName:string, hubUrl: string, ...args:any[]) => { +export const InvokeAsync = async (methodName: string, hubUrl: string, ...args: any[]) => { await GetConnectionAsync(hubUrl) await Connections[hubUrl].send(methodName, ...args) } -export { - Subscribe, - InvokeAsync, - GetConnectionAsync, -} \ No newline at end of file +export default Subscribe