/// <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();
            }
        }
        /// <summary>
        /// TokenGenerator is used for generate access token when connecting to lobby.
        /// If token generator is not specified, no token will be used when connecting to lobby.
        /// For entitlement token verification, use EntitlementTokenGenerator class on the parameter.
        /// </summary>
        /// <param name="tokenGenerator"> Token generator for connecting lobby. </param>
        public void SetConnectionTokenGenerator(ITokenGenerator tokenGenerator)
        {
            if (maintainConnectionCoroutine != null)
            {
                AccelByteDebug.LogWarning("Can't set connection token generator! Lobby is already connected.");
                return;
            }

            this.tokenGenerator = tokenGenerator;
            this.tokenGenerator.TokenReceivedEvent += OnTokenReceived;
        }
 /// <summary>
 /// Set the interval of sending telemetry event to the backend.
 /// By default it sends the queued events once a minute.
 /// Should not be less than 5 seconds.
 /// </summary>
 /// <param name="interval">The interval between telemetry event.</param>
 public void SetBatchFrequency(TimeSpan interval)
 {
     if (interval >= MINIMUM_INTERVAL_TELEMETRY)
     {
         telemetryInterval = interval;
     }
     else
     {
         AccelByteDebug.LogWarning($"Telemetry schedule interval is too small! Set to {MINIMUM_INTERVAL_TELEMETRY.TotalSeconds} seconds.");
         telemetryInterval = MINIMUM_INTERVAL_TELEMETRY;
     }
 }
        /// <summary>
        /// Change the delay parameters to maintain connection in the websocket.
        /// </summary>
        /// <param name="totalTimeout">Time limit until stop to re-attempt</param>
        /// <param name="backoffDelay">Initial delay time</param>
        /// <param name="maxDelay">Maximum delay time</param>
        public void SetRetryParameters(int totalTimeout, int backoffDelay, int maxDelay)
        {
            if (maintainConnectionCoroutine != null)
            {
                AccelByteDebug.LogWarning("Can't change retry parameters! Lobby is already connected.");
                return;
            }

            this.totalTimeout = totalTimeout;
            this.backoffDelay = backoffDelay;
            this.maxDelay     = maxDelay;
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #8
0
        /// <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));
        }
Exemple #9
0
        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;
                }
            }
        }