Example #1
0
        /// <summary>Reads client messages.</summary>
        /// <param name="webSocket">  The web socket.</param>
        /// <param name="clientGuid"> Unique identifier for the client.</param>
        /// <param name="cancelToken">A token that allows processing to be cancelled.</param>
        /// <returns>An asynchronous result.</returns>
        private async Task ReadClientMessages(
            WebSocket webSocket,
            Guid clientGuid,
            CancellationToken cancelToken)
        {
            // get the client object
            if (!WebsocketManager.TryGetClient(clientGuid, out WebsocketClientInformation client))
            {
                // nothing to do here (will cancel on exit)
                return;
            }

            // create our receive buffer
            byte[] buffer = new byte[_messageBufferSize];
            int    count;
            int    messageLength = 0;

            WebSocketReceiveResult result;

            // loop until cancelled
            while (!cancelToken.IsCancellationRequested)
            {
                // reset buffer offset
                messageLength = 0;

                // do not bubble errors here
                try
                {
                    // read a message
                    do
                    {
                        count  = _messageBufferSize - messageLength;
                        result = await webSocket.ReceiveAsync(
                            new ArraySegment <byte>(
                                buffer,
                                messageLength,
                                count),
                            cancelToken).ConfigureAwait(false);

                        messageLength += result.Count;
                    }while (!result.EndOfMessage);

                    // process this message
                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        break;
                    }

                    // check for a bind request
                    string message = Encoding.UTF8.GetString(buffer).Substring(0, messageLength);

                    if (message.StartsWith("bind ", StringComparison.Ordinal))
                    {
                        // grab the rest of the content
                        message = message.Replace("bind ", string.Empty, StringComparison.Ordinal);

                        string[] ids = message.Split(',');

                        // traverse the requested ids
                        foreach (string id in ids)
                        {
                            string subscriptionId = id.StartsWith("Subscription/", StringComparison.Ordinal)
                                ? id.Replace("Subscription/", string.Empty, StringComparison.Ordinal)
                                : id;

                            // make sure this subscription exists
                            if ((!SubscriptionManagerR4.Exists(subscriptionId)) &&
                                (!SubscriptionManagerR5.Exists(subscriptionId)))
                            {
                                continue;
                            }

                            // register this subscription to this client
                            WebsocketManager.AddSubscriptionToClient(subscriptionId, clientGuid);
                        }
                    }

                    if (message.StartsWith("bind-with-token ", StringComparison.Ordinal))
                    {
                        // grab the rest of the content
                        message = message.Replace("bind-with-token ", string.Empty, StringComparison.Ordinal);

                        if (!Guid.TryParse(message, out Guid tokenGuid))
                        {
                            continue;
                        }

                        // register this token to this client
                        WebsocketManager.BindClientWithToken(tokenGuid, clientGuid);
                    }

                    if (message.StartsWith("unbind ", StringComparison.Ordinal))
                    {
                        // grab the rest of the content
                        message = message.Replace("unbind ", string.Empty, StringComparison.Ordinal);

                        string[] ids = message.Split(',');

                        // traverse the requested ids
                        foreach (string id in ids)
                        {
                            string subscriptionId = id.StartsWith("Subscription/", StringComparison.Ordinal)
                                ? id.Replace("Subscription/", string.Empty, StringComparison.Ordinal)
                                : id;

                            // remove this subscription from this client
                            WebsocketManager.RemoveSubscriptionFromClient(subscriptionId, clientGuid);
                        }
                    }
                }

                // keep looping
                catch (Exception ex)
                {
                    Console.WriteLine($"SubscriptionWebsocketHandler.ReadClientMessages" +
                                      $" <<< client: {clientGuid} caught exception: {ex.Message}");

                    // this socket is borked, exit
                    break;
                }
            }
        }