Работа методов SignalR завязана на очередь

This commit is contained in:
goodmice 2022-07-19 15:13:09 +05:00
parent c9f28a45af
commit 5f0d4f98dc
2 changed files with 46 additions and 13 deletions

View File

@ -1,6 +1,9 @@
import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr' import { HubConnection, HubConnectionBuilder, HubConnectionState } from '@microsoft/signalr'
import { getUserToken, isDev } from '@utils' import { getUserToken, isDev } from '@utils'
import { makeTaskQueue } from '@utils/queue'
const queue = makeTaskQueue<void>()
// 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
@ -53,7 +56,7 @@ const MakeUnsubscribeFunction = (
connection: HubConnection, connection: HubConnection,
groupName: string[] | string | null, groupName: string[] | string | null,
...groups: SubscribeGroup[] ...groups: SubscribeGroup[]
): cleanFunction => async() => { ): cleanFunction => () => queue.push(async() => {
if(connection.state === HubConnectionState.Connected) { if(connection.state === HubConnectionState.Connected) {
if (groupName) { if (groupName) {
if (Array.isArray(groupName)) { if (Array.isArray(groupName)) {
@ -64,8 +67,8 @@ const MakeUnsubscribeFunction = (
for (const g of groups) for (const g of groups)
connection.off(g.methodName) connection.off(g.methodName)
} }
connection.stop() await connection.stop()
} })
/** Subscribe on some SignalR method (topic). /** Subscribe on some SignalR method (topic).
* @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]); * @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]);
@ -78,17 +81,19 @@ export const Subscribe = (
groupName: string[] | string = '', groupName: string[] | string = '',
...groups: SubscribeGroup[] ...groups: SubscribeGroup[]
): cleanFunction => { ): cleanFunction => {
GetConnectionAsync(hubUrl).then(async connection => { queue.push(async () => {
if (groupName) { await GetConnectionAsync(hubUrl).then(async connection => {
if (Array.isArray(groupName)) { if (groupName) {
for (const g of groupName) if (Array.isArray(groupName)) {
await connection.send('AddToGroup', g) for (const g of groupName)
} else await connection.send('AddToGroup', groupName) await connection.send('AddToGroup', g)
} } else await connection.send('AddToGroup', groupName)
for (const g of groups) }
connection.on(g.methodName, g.handler) for (const g of groups)
connection.on(g.methodName, g.handler)
})
}) })
return MakeUnsubscribeFunction(Connections[hubUrl], groupName, ...groups) return MakeUnsubscribeFunction(Connections[hubUrl], groupName, ...groups)
} }

28
src/utils/queue.ts Normal file
View File

@ -0,0 +1,28 @@
export type TaskHandler<T> = () => T | PromiseLike<T>
export type Queue<T> = {
push: (task: TaskHandler<T>) => Promise<T>
readonly length: number
}
export const makeTaskQueue = <T,>(): Queue<T> => {
let pending: Promise<T | void> = Promise.resolve()
let count: number = 0
const run = async (task?: TaskHandler<T>) => {
count++
try {
await pending;
} finally {
count--
return Promise.resolve().then(task);
}
}
return {
push: (task: TaskHandler<T>) => pending = run(task),
length: count,
}
}
export default makeTaskQueue