/// <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(); } } }
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(); } } }
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); } } }