Методы 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(
'hubs/reports',
'GetReportProgress',
`Report_${taskId}`,
handleReportProgress
)
const unSubscribeReportHub = Subscribe('hubs/reports', `Report_${taskId}`, {
methodName: 'GetReportProgress',
handler: handleReportProgress,
})
},
setShowLoader,
`Не удалось создать отчет по скважине (${idWell}) c

View File

@ -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 (

View File

@ -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(

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:
//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<string, HubConnection>
//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<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)
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<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 Connections[hubUrl].send(methodName, ...args)
}
export {
Subscribe,
InvokeAsync,
GetConnectionAsync,
}
export default Subscribe