While tackling this issue may not be solely related to SignalR, it's more about approaching it in the most efficient way. In C#, creating a singleton of a shared object is achievable by making it static and utilizing a lock to prevent multiple threads from creating the same object. Similarly, when using the JavaScript SignalR client, the goal is to have a single connection instance that can be accessed by different components without conflicts. The current solution I have attempted still leads to a race condition where multiple web components end up with their own connection instances:
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();
}
}
Surprisingly, two web components calling
await MessagingService.GetService()
from their async connectedCallback()
methods end up having their individual instances of MessagingService
along with separate connections. Numerous resources online suggest that locking might not be the appropriate solution here, indicating that there might be flaws in my approach. How can I ensure only one connection is ever created?