Работа методов 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 { getUserToken, isDev } from '@utils'
import { makeTaskQueue } from '@utils/queue'
const queue = makeTaskQueue<void>()
// SignalR js api:
//https://docs.microsoft.com/ru-ru/javascript/api/@aspnet/signalr/?view=signalr-js-latest
@ -53,7 +56,7 @@ const MakeUnsubscribeFunction = (
connection: HubConnection,
groupName: string[] | string | null,
...groups: SubscribeGroup[]
): cleanFunction => async() => {
): cleanFunction => () => queue.push(async() => {
if(connection.state === HubConnectionState.Connected) {
if (groupName) {
if (Array.isArray(groupName)) {
@ -64,8 +67,8 @@ const MakeUnsubscribeFunction = (
for (const g of groups)
connection.off(g.methodName)
}
connection.stop()
}
await connection.stop()
})
/** Subscribe on some SignalR method (topic).
* @example useEffect(() => SubscribeMultiple('/url/', `${id}`, { methodName: 'methodName', handler: handleNewData }), [id]);
@ -78,15 +81,17 @@ export const Subscribe = (
groupName: string[] | string = '',
...groups: SubscribeGroup[]
): cleanFunction => {
GetConnectionAsync(hubUrl).then(async connection => {
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)
queue.push(async () => {
await GetConnectionAsync(hubUrl).then(async connection => {
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], 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