/// <summary> /// Establish websocket connection /// </summary> /// <param name="url">url of the websocket server</param> /// <param name="authorizationToken">user authorization token</param> /// <param name="sessionId">session id header</param> public void Connect(string url, string authorizationToken, string sessionId = "") { if (State == WsState.Connecting || State == WsState.Open) { AccelByteDebug.Log("[AccelByteWebSocket] is connecting or already connected"); return; } if (this.tokenGenerator != null) { if (!this.tokenGenerator.IsValid()) { this.tokenGenerator.RequestToken(); return; } } webSocketUrl = url; this.authorizationToken = authorizationToken; webSocket.Connect(url, this.authorizationToken, sessionId, this.tokenGenerator?.Token); // check status after connect, only maintain connection when close code is reconnectable if (this.closeCodeCurrent == WsCloseCode.NotSet || isReconnectable(this.closeCodeCurrent)) { StartMaintainConnection(); } }
internal DedicatedServerManager(DedicatedServerManagerApi api, IServerSession serverSession, CoroutineRunner coroutineRunner) { Assert.IsNotNull(api, "api parameter can not be null."); Assert.IsNotNull(serverSession, "session parameter can not be null"); Assert.IsNotNull(coroutineRunner, "coroutineRunner parameter can not be null. Construction failed"); this.coroutineRunner = coroutineRunner; this.serverSession = serverSession; this.api = api; AccelByteDebug.Log("Server init sessionAdapter: " + this.serverSession.AuthorizationToken); AccelByteDebug.Log("Server init podName: " + this.name); }
public static ServerSetupData ParseCommandLine(string[] args) { bool isProviderFound = false; bool isGameVersionFound = false; bool isRegionFound = false; string region = ""; string provider = ""; string game_version = ""; ServerSetupData serverSetupData = new ServerSetupData(); foreach (string arg in args) { AccelByteDebug.Log("arg: " + arg); if (arg.Contains("provider")) { string[] split = arg.Split('='); provider = split[1]; isProviderFound = true; } if (arg.Contains("game_version")) { string[] split = arg.Split('='); game_version = split[1]; isGameVersionFound = true; } if (arg.Contains("region")) { string[] split = arg.Split('='); region = split[1]; isRegionFound = true; } if (isProviderFound && isGameVersionFound && isRegionFound) { serverSetupData = new ServerSetupData() { region = region, provider = provider, gameVersion = game_version }; break; } } return(serverSetupData); }
private IEnumerator GetServerLatenciesAsync(ResultCallback <Dictionary <string, int> > callback) { Result <QosServerList> getQosServersResult = null; yield return(this.qosManager.GetQosServers(result => getQosServersResult = result)); if (getQosServersResult.IsError) { callback.TryError(getQosServersResult.Error.Code); yield break; } var stopwatch = new Stopwatch(); var latencies = new Dictionary <string, int>(); foreach (QosServer server in getQosServersResult.Value.servers) { using (var udpClient = new UdpClient(server.port)) { udpClient.Connect(new IPEndPoint(IPAddress.Parse(server.ip), server.port)); byte[] sendBytes = Encoding.ASCII.GetBytes("PING"); stopwatch.Restart(); IAsyncResult asyncResult = udpClient.BeginSend(sendBytes, sendBytes.Length, null, null); yield return(WaitUntil(() => asyncResult.IsCompleted, 15 * 1000)); udpClient.EndSend(asyncResult); var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); asyncResult = udpClient.BeginReceive(null, null); yield return(WaitUntil(() => asyncResult.IsCompleted, 15 * 1000)); if (!asyncResult.IsCompleted) { AccelByteDebug.Log($"[QOS] timeout to PING {server.ip}"); } udpClient.EndReceive(asyncResult, ref remoteIpEndPoint); latencies[server.region] = stopwatch.Elapsed.Milliseconds; } } callback.TryOk(latencies); }
/// <summary> /// Register server to DSM and mark this machine as ready /// </summary> /// <param name="port">Exposed port number to connect to</param> /// <param name="callback">Returns a Result via callback when completed</param> public void RegisterServer(int portNumber, ResultCallback callback) { Report.GetFunctionLog(this.GetType().Name); if (!this.serverSession.IsValid()) { AccelByteDebug.Log("Server RegisterServer session is not valid"); callback.TryError(ErrorCode.IsNotLoggedIn); return; } this.name = Environment.GetEnvironmentVariable("POD_NAME"); var request = new RegisterServerRequest { pod_name = this.name, port = portNumber }; this.coroutineRunner.Run(this.api.RegisterServer(request, this.serverSession.AuthorizationToken, callback)); }
internal DedicatedServerManagerApi(string baseUrl, string namespace_, IHttpClient httpClient) { AccelByteDebug.Log("ServerApi init serverapi start"); Assert.IsNotNull(baseUrl, "Creating " + GetType().Name + " failed. Parameter baseUrl is null"); Assert.IsFalse( string.IsNullOrEmpty(namespace_), "Creating " + GetType().Name + " failed. Parameter namespace is null."); Assert.IsNotNull(httpClient, "Creating " + GetType().Name + " failed. Parameter httpWorker is null"); this.baseUrl = baseUrl; this.namespace_ = namespace_; this.httpClient = httpClient; this.serverSetup = new RegisterServerRequest() { game_version = "", ip = "", pod_name = "", provider = "" }; ParseArgsAndServerSetup(); }
/// <summary> /// Retrying connection with exponential backoff if disconnected, ping if connected /// </summary> /// <param name="backoffDelay">Initial delay time</param> /// <param name="maxDelay">Maximum delay time</param> /// <param name="totalTimeout">Time limit until stop to re-attempt</param> /// <returns></returns> private IEnumerator MaintainConnection(int backoffDelay, int maxDelay, int totalTimeout) { while (true) { switch (this.webSocket.ReadyState) { case WsState.Open: this.webSocket.Ping(); yield return(new WaitForSeconds(this.pingDelay / 1000f)); break; case WsState.Connecting: while (this.webSocket.ReadyState == WsState.Connecting) { yield return(new WaitForSeconds(1f)); } break; case WsState.Closing: while (this.webSocket.ReadyState == WsState.Closing) { yield return(new WaitForSeconds(1f)); } break; case WsState.Closed: System.Random rand = new System.Random(); int nextDelay = backoffDelay; var firstClosedTime = DateTime.Now; var timeout = TimeSpan.FromSeconds(totalTimeout / 1000f); while (this.reconnectOnClose && this.webSocket.ReadyState == WsState.Closed && DateTime.Now - firstClosedTime < timeout) { // debug ws connection #if DEBUG AccelByteDebug.Log("[WS] Re-Connecting"); #endif if (this.tokenGenerator == null) { this.webSocket.Connect(this.webSocketUrl, this.authorizationToken, this.sessionId); } else { this.tokenGenerator.RequestToken(); } float randomizedDelay = (float)(nextDelay + ((rand.NextDouble() * 0.5) - 0.5)); #if DEBUG AccelByteDebug.Log("[WS] Next reconnection in: " + randomizedDelay); #endif yield return(new WaitForSeconds(randomizedDelay / 1000f)); nextDelay *= 2; if (nextDelay > maxDelay) { nextDelay = maxDelay; } } if (this.webSocket.ReadyState == WsState.Closed) { this.OnRetryAttemptFailed?.Invoke(this, EventArgs.Empty); yield break; } break; } } }