public static async Task SetAsync <T>(this IDistributedCache cache, string key, T value, DistributedCacheEntryOptions options, DefaultJsonSerializer jsonSerializer, CancellationToken ct) { var valueData = jsonSerializer.SerializeToUtf8Bytes(value); await cache.SetAsync(key, valueData, options, ct); }
public IActionResult SSOAuthorizeAsync([FromQuery, BindRequired] Guid uuid, [FromServices] NexusModsAPIKeyProvider apiKeyProvider, [FromServices] DefaultJsonSerializer jsonSerializer, CancellationToken ct) { async IAsyncEnumerable <SSEMessage> SSEEvents() { var client = new ClientWebSocket(); using var cts = new CancellationTokenSource(60000); using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts.Token, ct); var timeoutToken = linkedCts.Token; var connectionToken = null as string; yield return(new SSEMessage(Event: "connecting")); var receivedAPIKey = false; async Task ReceiveLoop() { var buffer = new ArraySegment <byte>(new byte[1024]); var sb = new StringBuilder(); while (!timeoutToken.IsCancellationRequested && client.State == WebSocketState.Open) { var received = await client.ReceiveAsync(buffer, timeoutToken); if (received.MessageType == WebSocketMessageType.Close) { break; } sb.Append(Encoding.UTF8.GetString(buffer.AsSpan(0, received.Count))); if (received.EndOfMessage) { var text = sb.ToString(); sb.Clear(); var response = jsonSerializer.Deserialize <SSOResponse?>(text); if (response is not null && response.Success && response.Data is not null) { if (response.Data.ConnectionToken is not null) { connectionToken = response.Data.ConnectionToken; } if (response.Data.ApiKey is not null) { receivedAPIKey = true; apiKeyProvider.Override(response.Data.ApiKey); await client.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye", timeoutToken); } } } } } await client.ConnectAsync(new Uri("wss://sso.nexusmods.com"), timeoutToken); var receiveTask = ReceiveLoop(); var request = jsonSerializer.SerializeToUtf8Bytes(new SSORequest(uuid, connectionToken, 2)); await client.SendAsync(request, WebSocketMessageType.Text, true, timeoutToken); yield return(new SSEMessage(Event: "connected")); await receiveTask; if (!receivedAPIKey) { yield return(new SSEMessage(Event: "api-key-failed-to-get")); } else { yield return(new SSEMessage(Event: "api-key-received")); } yield return(new SSEMessage(Event: "finished")); } return(new SSEActionResult(SSEEvents())); }