Esempio n. 1
0
#pragma warning disable 1998
        private async void ProcessMessageAsync(WebSocketMessageEnvelope envelope, string message)
#pragma warning restore 1998
        {
            if (!string.IsNullOrEmpty(envelope.Cid))
            {
                // Handle message response.
                TaskCompletionSource <WebSocketMessageEnvelope> completer;
                var cid = envelope.Cid;
                _messageReplies.TryRemove(cid, out completer);
                if (completer == null)
                {
                    if (Trace)
                    {
                        Logger.InfoFormat("No task completer for message: '{0}'", cid);
                    }
                    return;
                }

                if (envelope.Error != null)
                {
                    // FIXME use a dedicated exception type.
                    completer.SetException(new WebSocketException(envelope.Error.Message));
                }
                else
                {
                    completer.SetResult(envelope);
                }
            }
            else if (envelope.Error != null)
            {
                OnError?.Invoke(this, new WebSocketException(envelope.Error.Message));
            }
            else if (envelope.ChannelMessage != null)
            {
                OnChannelMessage?.Invoke(this, envelope.ChannelMessage);
            }
            else if (envelope.ChannelPresenceEvent != null)
            {
                OnChannelPresence?.Invoke(this, envelope.ChannelPresenceEvent);
            }
            else if (envelope.MatchmakerMatched != null)
            {
                OnMatchmakerMatched?.Invoke(this, envelope.MatchmakerMatched);
            }
            else if (envelope.MatchPresenceEvent != null)
            {
                OnMatchPresence?.Invoke(this, envelope.MatchPresenceEvent);
            }
            else if (envelope.MatchState != null)
            {
                OnMatchState?.Invoke(this, envelope.MatchState);
            }
            else if (envelope.NotificationList != null)
            {
                foreach (var notification in envelope.NotificationList.Notifications)
                {
                    OnNotification?.Invoke(this, notification);
                }
            }
            else if (envelope.StatusPresenceEvent != null)
            {
                OnStatusPresence?.Invoke(this, envelope.StatusPresenceEvent);
            }
            else if (envelope.StreamPresenceEvent != null)
            {
                OnStreamPresence?.Invoke(this, envelope.StreamPresenceEvent);
            }
            else if (envelope.StreamState != null)
            {
                OnStreamState?.Invoke(this, envelope.StreamState);
            }
            else
            {
                if (Trace)
                {
                    Logger.InfoFormat("Socket received unrecognised message: '{0}'", message);
                }
            }
        }
Esempio n. 2
0
        internal WebSocketWrapper(Uri baseUri, WebSocketOptions options) : base(options)
        {
            _baseUri        = baseUri;
            _messageReplies = new ConcurrentDictionary <string, TaskCompletionSource <WebSocketMessageEnvelope> >();
            options.ValidateOptions();
            _options = options.Clone();

            if (!IsTrace)
            {
                _options.Logger = new NullLogger();
            }

            OnError = (sender, exception) => _options.Logger.Error(exception);

            OnChannelMessage = (sender, message) =>
                               _options.Logger.DebugFormat("Received channel message '{0}'", message);
            OnChannelPresence = (sender, _event) =>
                                _options.Logger.DebugFormat("Received channel presence '{0}'", _event);
            OnConnect           = (sender, args) => _options.Logger.Debug("Socket connected.");
            OnDisconnect        = (sender, args) => _options.Logger.Debug("Socket disconnected.");
            OnMatchmakerMatched = (sender, matched) =>
                                  _options.Logger.DebugFormat("Received matchmaker match '{0}'", matched);
            OnMatchPresence = (sender, _event) =>
                              _options.Logger.DebugFormat("Received match presence '{0}'", _event);
            OnMatchState   = (sender, state) => _options.Logger.DebugFormat("Received match state '{0}'", state);
            OnNotification = (sender, notification) =>
                             _options.Logger.DebugFormat("Received notification '{0}'", notification);
            OnStatusPresence = (sender, _event) =>
                               _options.Logger.DebugFormat("Received status presence '{0}'", _event);
            OnStreamPresence = (sender, _event) =>
                               _options.Logger.DebugFormat("Received stream presence '{0}'", _event);
            OnStreamState = (sender, state) => _options.Logger.DebugFormat("Received stream state '{0}'", state);

            Connected       += (sender, args) => OnConnect.Invoke(this, EventArgs.Empty);
            Disconnected    += (sender, args) => OnDisconnect.Invoke(this, EventArgs.Empty);
            ErrorReceived   += (sender, exception) => OnError?.Invoke(this, exception);
            MessageReceived += (sender, message) =>
            {
                if (IsTrace)
                {
                    _options.Logger.DebugFormat("Socket read message: '{0}'", message);
                }

                var envelope = message.FromJson <WebSocketMessageEnvelope>();
                if (!string.IsNullOrEmpty(envelope.Cid))
                {
                    // Handle message response.
                    TaskCompletionSource <WebSocketMessageEnvelope> completer;
                    var cid = envelope.Cid;
                    _messageReplies.TryRemove(cid, out completer);
                    if (completer == null)
                    {
                        if (IsTrace)
                        {
                            _options.Logger.InfoFormat("No task completer for message: '{0}'", cid);
                        }
                        return;
                    }

                    if (envelope.Error != null)
                    {
                        // FIXME use a dedicated exception type.
                        completer.SetException(new WebSocketException(envelope.Error.Message));
                    }
                    else
                    {
                        completer.SetResult(envelope);
                    }
                }
                else if (envelope.Error != null)
                {
                    OnError?.Invoke(this, new WebSocketException(envelope.Error.Message));
                }
                else if (envelope.ChannelMessage != null)
                {
                    OnChannelMessage?.Invoke(this, envelope.ChannelMessage);
                }
                else if (envelope.ChannelPresenceEvent != null)
                {
                    OnChannelPresence?.Invoke(this, envelope.ChannelPresenceEvent);
                }
                else if (envelope.MatchmakerMatched != null)
                {
                    OnMatchmakerMatched?.Invoke(this, envelope.MatchmakerMatched);
                }
                else if (envelope.MatchPresenceEvent != null)
                {
                    OnMatchPresence?.Invoke(this, envelope.MatchPresenceEvent);
                }
                else if (envelope.MatchState != null)
                {
                    OnMatchState?.Invoke(this, envelope.MatchState);
                }
                else if (envelope.NotificationList != null)
                {
                    foreach (var notification in envelope.NotificationList.Notifications)
                    {
                        OnNotification?.Invoke(this, notification);
                    }
                }
                else if (envelope.StatusPresenceEvent != null)
                {
                    OnStatusPresence?.Invoke(this, envelope.StatusPresenceEvent);
                }
                else if (envelope.StreamPresenceEvent != null)
                {
                    OnStreamPresence?.Invoke(this, envelope.StreamPresenceEvent);
                }
                else if (envelope.StreamState != null)
                {
                    OnStreamState?.Invoke(this, envelope.StreamState);
                }
                else
                {
                    if (IsTrace)
                    {
                        _options.Logger.InfoFormat("Socket received unrecognised message: '{0}'", message);
                    }
                }
            };
        }
        /// <inheritdoc />
        public Task ConnectAsync(ISession session, CancellationToken ct = default(CancellationToken),
                                 bool appearOnline = false, int connectTimeout = 5000)
        {
            if (_webSocket != null)
            {
                _webSocket.Close(CloseStatusCode.Normal);
                _webSocket = null;
            }

            var addr = new UriBuilder(_baseUri)
            {
                Path  = "/ws",
                Query = string.Concat("lang=en&status=", appearOnline, "&token=", session.AuthToken)
            };

            _webSocket = new WebSocket(addr.Uri.ToString())
            {
                EmitOnPing = false,
                WaitTime   = TimeSpan.FromSeconds(connectTimeout)
            };

            _webSocket.OnOpen    += (sender, args) => OnConnect.Invoke(this, EventArgs.Empty);
            _webSocket.OnClose   += (sender, args) => OnDisconnect.Invoke(this, EventArgs.Empty);
            _webSocket.OnMessage += (sender, args) =>
            {
                var message = args.Data;
                if (IsTrace)
                {
                    _options.Logger.DebugFormat("Socket read message: '{0}'", message);
                }
                var envelope = message.FromJson <WebSocketMessageEnvelope>();
                if (!string.IsNullOrEmpty(envelope.Cid))
                {
                    // Handle message response.
                    TaskCompletionSource <WebSocketMessageEnvelope> completer;
                    var cid = envelope.Cid;
                    _messageReplies.TryRemove(cid, out completer);
                    if (completer == null)
                    {
                        if (IsTrace)
                        {
                            _options.Logger.InfoFormat("No task completer for message: '{0}'", cid);
                        }
                        return;
                    }

                    if (envelope.Error != null)
                    {
                        // FIXME use a dedicated exception type.
                        completer.SetException(new System.Net.WebSockets.WebSocketException(envelope.Error.Message));
                    }
                    else
                    {
                        completer.SetResult(envelope);
                    }
                }
                else if (envelope.Error != null)
                {
                    OnError?.Invoke(this, new System.Net.WebSockets.WebSocketException(envelope.Error.Message));
                }
                else if (envelope.ChannelMessage != null)
                {
                    OnChannelMessage?.Invoke(this, envelope.ChannelMessage);
                }
                else if (envelope.ChannelPresenceEvent != null)
                {
                    OnChannelPresence?.Invoke(this, envelope.ChannelPresenceEvent);
                }
                else if (envelope.MatchmakerMatched != null)
                {
                    OnMatchmakerMatched?.Invoke(this, envelope.MatchmakerMatched);
                }
                else if (envelope.MatchPresenceEvent != null)
                {
                    OnMatchPresence?.Invoke(this, envelope.MatchPresenceEvent);
                }
                else if (envelope.MatchState != null)
                {
                    OnMatchState?.Invoke(this, envelope.MatchState);
                }
                else if (envelope.NotificationList != null)
                {
                    foreach (var notification in envelope.NotificationList.Notifications)
                    {
                        OnNotification?.Invoke(this, notification);
                    }
                }
                else if (envelope.StatusPresenceEvent != null)
                {
                    OnStatusPresence?.Invoke(this, envelope.StatusPresenceEvent);
                }
                else if (envelope.StreamPresenceEvent != null)
                {
                    OnStreamPresence?.Invoke(this, envelope.StreamPresenceEvent);
                }
                else if (envelope.StreamState != null)
                {
                    OnStreamState?.Invoke(this, envelope.StreamState);
                }
                else
                {
                    if (IsTrace)
                    {
                        _options.Logger.InfoFormat("Socket received unrecognised message: '{0}'", message);
                    }
                }
            };

            _webSocket.Connect();
            _webSocket.TcpClient.NoDelay = true;
            return(Task.CompletedTask);
        }