I have an abstract class WebsocketHandler which is inherited by WsUserRequestHandler which implements an interface which in turn is injected as a singleton service to be used in other classes.
WebsocketHandler (simplified):
public abstract class WebSocketHandler
{
private event EventHandler<OnRequestReceivedEventArgs> OnRequestReceived;
private ClientWebSocket _client { get; set; } = new ClientWebSocket();
protected async Task<bool> Connect(WsConnectionInfo connectionInfo)
{
this._client.ConnectAsync(...)
while (true)
{
await this.Receive(this._client);
if (this._cts.IsCancellationRequested)
break;
}
}
private async Task Receive(ClientWebSocket client)
{
while (true)
{
var result = await client.ReceiveAsync(...);
if (result.MessageType == WebSocketMessageType.Text)
{
var jsonInput = Encoding.UTF8.GetString(...);
var request = JsonConvert.DeserializeObject<IWebSocketRequest>(jsonInput, ...);
if (request is null)
continue;
// Always true
Console.WriteLine("received request event is null: " + (this.OnRequestReceived == null));
// Always null, so not being invoked
this.OnRequestReceived?.Invoke(this, new OnRequestReceivedEventArgs(request));
}
}
}
// this method runs as expected when called and ReceivedRequest gets
// successfully attached to event handler (at least in the scope of the method)
protected async Task<TRequest> RequestReceived<TRequest>(CancellationToken token)
where TRequest : IWebSocketRequest
{
var request = default(dynamic);
void ReceivedRequest(object sender, OnRequestReceivedEventArgs args)
{
if (args.Request.GetType() == typeof(TRequest))
request = args.Request;
}
this.OnRequestReceived += ReceivedRequest;
Console.WriteLine(this.OnRequestReceived == null); // returns false
while (request == null)
await Task.Delay(25, token);
this.OnRequestReceived -= ReceivedRequest;
return request;
}
The class WsUserRequestHandler is injected into another class which then calls the base method RequestReceived and awaits it. If I then, after making sure that the method is called and awaited, send a message to the websocket, the Receive method is called and OnRequestReceived turns out null. I have also made sure that the cancellation token that gets passed on to RequestReceived isn't cancelled, and also that it doesn't unsubscribe from the event.