Esempio n. 1
0
        /// <summary>
        /// Starts the server.
        /// </summary>
        public void Start()
        {
            using (ILock lockObject = new SocketLock(this.profile.Port - 1))
            {
                lockObject.LockObject(this.process.Timeout);
                try
                {
                    int portToUse = DetermineNextFreePort(this.host, this.profile.Port);
                    this.profile.Port = portToUse;
                    this.profile.WriteToDisk();
                    this.process.Clean(this.profile);
                    this.process.StartProfile(this.profile, new string[] { "-foreground" });

                    this.SetAddress(portToUse);

                    // TODO (JimEvans): Get a better url algorithm.
                    this.extensionUri = new Uri(string.Format(CultureInfo.InvariantCulture, "http://{0}:{1}/hub/", this.host, portToUse));
                    this.ConnectToBrowser(this.process.Timeout);
                }
                finally
                {
                    lockObject.UnlockObject();
                }
            }
        }
Esempio n. 2
0
 public void Start()
 {
     using (ILock @lock = new SocketLock(this.profile.Port - 1))
     {
         @lock.LockObject(this.process.Timeout);
         try
         {
             int num = FirefoxDriverServer.DetermineNextFreePort(this.host, this.profile.Port);
             this.profile.Port = num;
             this.profile.WriteToDisk();
             this.process.StartProfile(this.profile, new string[]
             {
                 "-foreground"
             });
             this.SetAddress(num);
             this.extensionUri = new Uri(string.Format(CultureInfo.InvariantCulture, "http://{0}:{1}/hub/", new object[]
             {
                 this.host,
                 num
             }));
             this.ConnectToBrowser(this.process.Timeout);
         }
         finally
         {
             @lock.UnlockObject();
         }
     }
 }
Esempio n. 3
0
        internal async Task InternalConnectAsync()
        {
            SocketLock socketLock = null;

            try
            {
                if (this.GatewayInfo == null)
                {
                    await this.InternalUpdateGatewayAsync().ConfigureAwait(false);
                }
                await this.InitializeAsync().ConfigureAwait(false);

                socketLock = this.GetSocketLock();
                await socketLock.LockAsync().ConfigureAwait(false);
            }
            catch
            {
                socketLock?.UnlockAfter(TimeSpan.Zero);
                throw;
            }

            if (!this.Presences.ContainsKey(this.CurrentUser.Id))
            {
                this._presences[this.CurrentUser.Id] = new DiscordPresence
                {
                    Discord      = this,
                    RawActivity  = new TransportActivity(),
                    Activity     = new DiscordActivity(),
                    Status       = UserStatus.Online,
                    InternalUser = new TransportUser
                    {
                        Id            = this.CurrentUser.Id,
                        Username      = this.CurrentUser.Username,
                        Discriminator = this.CurrentUser.Discriminator,
                        AvatarHash    = this.CurrentUser.AvatarHash
                    }
                };
            }
            else
            {
                var pr = this._presences[this.CurrentUser.Id];
                pr.RawActivity = new TransportActivity();
                pr.Activity    = new DiscordActivity();
                pr.Status      = UserStatus.Online;
            }

            Volatile.Write(ref this._skippedHeartbeats, 0);

            this._webSocketClient     = this.Configuration.WebSocketClientFactory(this.Configuration.Proxy);
            this._payloadDecompressor = this.Configuration.GatewayCompressionLevel != GatewayCompressionLevel.None
                ? new PayloadDecompressor(this.Configuration.GatewayCompressionLevel)
                : null;

            this._cancelTokenSource = new CancellationTokenSource();
            this._cancelToken       = this._cancelTokenSource.Token;

            this._webSocketClient.Connected       += SocketOnConnect;
            this._webSocketClient.Disconnected    += SocketOnDisconnect;
            this._webSocketClient.MessageReceived += SocketOnMessage;
            this._webSocketClient.ExceptionThrown += SocketOnException;

            var gwuri = new QueryUriBuilder(this.GatewayUri)
                        .AddParameter("v", "6")
                        .AddParameter("encoding", "json");

            if (this.Configuration.GatewayCompressionLevel == GatewayCompressionLevel.Stream)
            {
                gwuri.AddParameter("compress", "zlib-stream");
            }

            await this._webSocketClient.ConnectAsync(gwuri.Build()).ConfigureAwait(false);

            Task SocketOnConnect(IWebSocketClient sender, SocketEventArgs e)
            => this._socketOpened.InvokeAsync(this, e);

            async Task SocketOnMessage(IWebSocketClient sender, SocketMessageEventArgs e)
            {
                MemoryStream msg = default;

                if (e is SocketTextMessageEventArgs etext)
                {
                    msg = etext.Message;
                }
                else if (e is SocketBinaryMessageEventArgs ebin) // :DDDD
                {
                    msg = new MemoryStream();
                    if (!this._payloadDecompressor.TryDecompress(new ArraySegment <byte>(ebin.Message), msg))
                    {
                        this.Logger.LogError(LoggerEvents.WebSocketReceiveFailure, "Payload decompression failed");
                        return;
                    }

                    msg.Seek(0, SeekOrigin.Begin);

                    if (this.Configuration.MinimumLogLevel == LogLevel.Trace)
                    {
                        var cs = new MemoryStream();
                        await msg.CopyToAsync(cs).ConfigureAwait(false);

                        msg.Seek(0, SeekOrigin.Begin);
                        cs.Seek(0, SeekOrigin.Begin);

                        using (var sr = new StreamReader(cs, Utilities.UTF8))
                        {
                            this.Logger.LogTrace(LoggerEvents.GatewayWsRx, await sr.ReadToEndAsync().ConfigureAwait(false));
                        }
                    }
                }

                try
                {
                    await this.HandleSocketMessageAsync(msg).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(LoggerEvents.WebSocketReceiveFailure, ex, "Socket handler suppressed an exception");
                }
            }

            Task SocketOnException(IWebSocketClient sender, SocketErrorEventArgs e)
            => this._socketErrored.InvokeAsync(this, e);

            async Task SocketOnDisconnect(IWebSocketClient sender, SocketCloseEventArgs e)
            {
                // release session and connection
                this.ConnectionLock.Set();
                this.SessionLock.Set();

                if (!this._disposed)
                {
                    this._cancelTokenSource.Cancel();
                }

                this.Logger.LogDebug(LoggerEvents.ConnectionClose, "Connection closed ({0}, '{1}')", e.CloseCode, e.CloseMessage);
                await this._socketClosed.InvokeAsync(this, e).ConfigureAwait(false);



                if (this.Configuration.AutoReconnect && (e.CloseCode < 4001 || e.CloseCode >= 5000))
                {
                    this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({0}, '{1}'), reconnecting", e.CloseCode, e.CloseMessage);

                    if (this._status == null)
                    {
                        await this.ConnectAsync().ConfigureAwait(false);
                    }
                    else
                    if (this._status.IdleSince.HasValue)
                    {
                        await this.ConnectAsync(this._status._activity, this._status.Status, Utilities.GetDateTimeOffsetFromMilliseconds(this._status.IdleSince.Value)).ConfigureAwait(false);
                    }
                    else
                    {
                        await this.ConnectAsync(this._status._activity, this._status.Status).ConfigureAwait(false);
                    }
                }
                else
                {
                    this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({0}, '{1}')", e.CloseCode, e.CloseMessage);
                }
            }
        }