protected abstract void OnClosedPrematurely(); // Unsuccessful close /// <param name="cancellationToken">Token that when cancelled will abort the entire socket.</param> /// <exception cref="ArgumentException">Thrown if <paramref name="uri"/> does not start with ws:// or wss://.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="uri"/> is null.</exception> /// <exception cref="InvalidOperationException"> /// Thrown if the socket attempts to start after a first time. A WebSocket instance /// can only be used for one connection attempt. /// </exception> /// <exception cref="OperationCanceledException"></exception> /// <exception cref="ObjectDisposedException">Thrown if this socket has already been disposed.</exception> /// <exception cref="WebSocketException">Thrown if the socket fails to connect.</exception> public virtual async Task ConnectAsync(Uri uri, CancellationToken cancellationToken) { if (uri == null) { throw new ArgumentNullException(nameof(uri)); } // Attempt to connect log.LogVerbose($"Connecting to {uri}..."); await socket.ConnectAsync(uri, cancellationToken).ConfigureAwait(false); // Shouldn't ever happen, but just in case if (socket.State != WebSocketState.Open) { log.LogWarning($"Socket.ConnectAsync succeeded but the state is {socket.State}!"); throw new WebSocketException(WebSocketError.Faulted, "Failed to connect. No other information is available."); } // Connection successful (exception would be thrown otherwise) abortCancellationSource = new CancellationTokenSource(); sendLock = new AsyncLock(); // Start receive task receiveTask = ReceiveLoop(); log.LogVerbose("Successfully connected."); }
protected override Task OnPayloadReceived(DiscordApiData payload) { VoiceOPCode op = (VoiceOPCode)payload.GetInteger("op").Value; DiscordApiData d = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { callback(payload, d); } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } return(Task.CompletedTask); }
private async void Socket_OnDispatch(object sender, DispatchEventArgs e) { if (isDisposed) { return; } string eventName = e.EventName; if (eventName == null) { log.LogError($"[Socket_OnDispatch] eventName was null!"); return; } DispatchCallback callback; if (dispatchHandlers.TryGetValue(eventName, out callback)) { try { if (callback.Synchronous != null) { callback.Synchronous(e.Data); } else { await callback.Asynchronous(e.Data).ConfigureAwait(false); } } catch (ShardCacheException cex) { log.LogWarning($"[{eventName}] Did not complete because: {cex.Message}."); } catch (Exception ex) { log.LogError($"[{eventName}] Unhandled exception: {ex}"); } } else { log.LogWarning($"Missing handler for dispatch event: {eventName}"); } }
protected override async Task OnPayloadReceived(DiscordApiData payload) { GatewayOPCode op = (GatewayOPCode)payload.GetInteger("op"); DiscordApiData data = payload.Get("d"); PayloadCallback callback; if (payloadHandlers.TryGetValue(op, out callback)) { if (callback.Synchronous != null) { callback.Synchronous(payload, data); } else { await callback.Asynchronous(payload, data).ConfigureAwait(false); } } else { log.LogWarning($"Missing handler for payload: {op} ({(int)op})"); } }