Методы signalr переписаны для использования с множеством обработчиками и группами

This commit is contained in:
goodmice 2022-04-14 11:06:07 +05:00
parent dd781e41d3
commit 0e519ea03f
4 changed files with 66 additions and 62 deletions

View File

@ -69,12 +69,10 @@ export const Report = memo(({ idWell }) => {
} }
} }
const unSubscribeReportHub = Subscribe( const unSubscribeReportHub = Subscribe('hubs/reports', `Report_${taskId}`, {
'hubs/reports', methodName: 'GetReportProgress',
'GetReportProgress', handler: handleReportProgress,
`Report_${taskId}`, })
handleReportProgress
)
}, },
setShowLoader, setShowLoader,
`Не удалось создать отчет по скважине (${idWell}) c `Не удалось создать отчет по скважине (${idWell}) c

View File

@ -29,7 +29,10 @@ export const ActiveMessagesOnline = memo(({ idWell }) => {
`Не удалось загрузить сообщения по скважине "${idWell}"`, `Не удалось загрузить сообщения по скважине "${idWell}"`,
'Получение списка сообщений' 'Получение списка сообщений'
) )
return Subscribe('hubs/telemetry','ReceiveMessages', `well_${idWell}`, handleReceiveMessages) return Subscribe('hubs/telemetry',`well_${idWell}`, {
methodName: 'ReceiveMessages',
handler: handleReceiveMessages,
})
}, [idWell, handleReceiveMessages]) }, [idWell, handleReceiveMessages])
return ( return (

View File

@ -323,8 +323,11 @@ export default function TelemetryView({ idWell }) {
const handleDataSpin = useCallback((data) => data && setDataSpin(data), []) const handleDataSpin = useCallback((data) => data && setDataSpin(data), [])
useEffect(() => { useEffect(() => {
const unsubscribeSaub = Subscribe('hubs/telemetry', 'ReceiveDataSaub', `well_${idWell}`, handleDataSaub) const unsubscribe = Subscribe(
const unsubscribeSpin = Subscribe('hubs/telemetry', 'ReceiveDataSpin', `well_${idWell}`, handleDataSpin) 'hubs/telemetry', `well_${idWell}`,
{ methodName: 'ReceiveDataSaub', handler: handleDataSaub },
{ methodName: 'ReceiveDataSpin', handler: handleDataSpin }
)
invokeWebApiWrapperAsync( invokeWebApiWrapperAsync(
async () => { async () => {
const flowChart = await DrillFlowChartService.get(idWell) const flowChart = await DrillFlowChartService.get(idWell)
@ -338,10 +341,7 @@ export default function TelemetryView({ idWell }) {
`Не удалось получить данные по скважине "${idWell}"`, `Не удалось получить данные по скважине "${idWell}"`,
'Получение данных по скважине' 'Получение данных по скважине'
) )
return () => { return unsubscribe
unsubscribeSaub()
unsubscribeSpin()
}
}, [idWell, chartInterval, handleDataSpin, handleDataSaub]) }, [idWell, chartInterval, handleDataSpin, handleDataSaub])
useEffect(() => invokeWebApiWrapperAsync( useEffect(() => invokeWebApiWrapperAsync(

View File

@ -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: // SignalR js api:
//https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest //https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest
const ConnectionOptions = { const ConnectionOptions = {
accessTokenFactory: () => localStorage['token'], accessTokenFactory: () => getUserToken() ?? '',
transport:1, transport: 1,
} }
type ConnectionsDict = { type ConnectionsDict = Record<string, HubConnection>
[route: string]: HubConnection;
};
//var baseUrl = `http://192.168.1.70:5000` //var baseUrl = `http://192.168.1.70:5000`
var baseUrl = process.env.NODE_ENV === 'development' const baseUrl = process.env.NODE_ENV === 'development' ? require('../../../package.json').proxy : ''
? require('../../../package.json').proxy
:''
const Connections: ConnectionsDict = { const Connections: ConnectionsDict = {
'hubs/telemetry': new HubConnectionBuilder() 'hubs/telemetry': new HubConnectionBuilder()
.withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)// .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)
.withAutomaticReconnect() .withAutomaticReconnect()
.build(), .build(),
@ -31,57 +28,67 @@ const Connections: ConnectionsDict = {
let connectionPromise: Promise<void> let connectionPromise: Promise<void>
const GetConnectionAsync = async (hubUrl: string) => { export const GetConnectionAsync = async (hubUrl: string): Promise<HubConnection> => {
const Connection: HubConnection = Connections[hubUrl]
let Connection: HubConnection = Connections[hubUrl]; if (Connection.state === HubConnectionState.Disconnected)
connectionPromise = Connection.start()
if (Connection.state === HubConnectionState.Disconnected) if (Connection.state !== HubConnectionState.Connected)
connectionPromise = Connection.start() await connectionPromise
if (Connection.state !== HubConnectionState.Connected) return Connection
await connectionPromise }
return Connection type handlerFunction = (...args: any[]) => void
} type cleanFunction = (...args: any[]) => void
type handlerFunction = (...args: any[]) => void; export type SubscribeGroup = {
methodName: string,
type cleanFunction = (...args: any[]) => void; handler: handlerFunction,
}
const MakeUnsubscribeFunction = ( const MakeUnsubscribeFunction = (
connection: HubConnection, connection: HubConnection,
methodName: string, groupName: string[] | string | null,
groupName: (string|null)):cleanFunction => { ...groups: SubscribeGroup[]
return async() => { ): cleanFunction => async() => {
if(connection.state === HubConnectionState.Connected) if(connection.state === HubConnectionState.Connected) {
{ if (groupName) {
if(groupName) if (Array.isArray(groupName)) {
await connection.send('RemoveFromGroup', groupName) for (const g of groupName)
connection.off(methodName) 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). /** Subscribe on some SignalR method (topic).
* @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]); * @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]);
* @param {string} methodName name of the method * @param {string[] | string} groupName name of the group(-s)
* @param {string} groupName name of the group * @param {SubscribeGroup} groups groups obtains method name and handler which fires when got new data by subscription
* @param {handlerFunction} handler fires when got new data by subscription
* @return {cleanFunction} unsubscribe function for useEffect cleanup. * @return {cleanFunction} unsubscribe function for useEffect cleanup.
*/ */
const Subscribe = ( export const Subscribe = (
hubUrl: string, hubUrl: string,
methodName: string, groupName: string[] | string = '',
groupName: string = '', ...groups: SubscribeGroup[]
handler: handlerFunction ):cleanFunction=>{ ): cleanFunction => {
GetConnectionAsync(hubUrl).then(async connection => { GetConnectionAsync(hubUrl).then(async connection => {
if(groupName) if (groupName) {
await connection.send('AddToGroup', groupName) if (Array.isArray(groupName)) {
connection.on(methodName, handler) 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. /** Invokes some SignalR method.
@ -89,13 +96,9 @@ const Subscribe = (
* @param {any[]} args methods arguments * @param {any[]} args methods arguments
* @return {Promise<void>} Promise * @return {Promise<void>} Promise
*/ */
const InvokeAsync = async (methodName:string, hubUrl: string, ...args:any[]) => { export const InvokeAsync = async (methodName: string, hubUrl: string, ...args: any[]) => {
await GetConnectionAsync(hubUrl) await GetConnectionAsync(hubUrl)
await Connections[hubUrl].send(methodName, ...args) await Connections[hubUrl].send(methodName, ...args)
} }
export { export default Subscribe
Subscribe,
InvokeAsync,
GetConnectionAsync,
}