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.");
        }
예제 #2
0
        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);
        }
예제 #3
0
        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}");
            }
        }
예제 #4
0
        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})");
            }
        }