I'll admit, this is probably not even a SignalR specific question, but more of a "doing it the right way" question. Typically in C#, we could create a singleton of some shared thing by making it static and then using a lock around it so only one thread could create the shared object. Using the Javascript SignalR client, I would like to do the same thing, not having to worry about whether or not two components want to use a connection. My solution is this, but it still results in a race condition where two web components each get their own connection instance:
export class MessagingService {
private static service: MessagingService;
static async GetService(): Promise<MessagingService> {
if (!this.service) {
let service = new MessagingService();
await service.start();
this.service = service;
}
return this.service;
}
connection;
async start() {
this.connection = new signalR.HubConnectionBuilder().withUrl("/MyHub").withAutomaticReconnect().build();
await this.connection.start();
}
}
Naively, I wouldn't expect two web components on the page, calling await MessagingService.GetService() from their async connectedCallback() methods, to each end up with their own instance of the MessagingService and therefore connection, but that's exactly what happens.
Countless other questions on the Internets suggest that locking isn't what I need here, but rather that I'm doing it wrong. How can I make sure only one of these connections is ever created?