/// <summary>Runs the application. Retrives a token from the authentication server, then retrieves the list of services, and /// then opens the WebSocket(s) at the address(es) specified by service discovery using the token.</summary> public void Run() { /* Get local hostname. */ IPAddress hostEntry = Array.Find(Dns.GetHostEntry(Dns.GetHostName()).AddressList, ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); if (string.IsNullOrEmpty(_position)) { _position = (hostEntry == null) ? "127.0.0.1/net" : hostEntry.ToString(); } if (!GetAuthenticationInfo() || !DiscoverServices()) { Environment.Exit(1); } _tokenTS = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds; if (_hostName != null) { _hosts.Add(new Tuple <string, string>(_hostName, _port)); if (_hostName2 != null) { _hosts.Add(new Tuple <string, string>(_hostName2, _port2)); } } Console.CancelKeyPress += Console_CancelKeyPress; WebSocketSession session1 = null; WebSocketSession session2 = null; double curTS = 0.0; double deltaTime = 0.0; try { /* Open websocket(s) */ foreach (var host in _hosts) { var webSocketSession = new WebSocketSession("Session" + (_webSocketSessions.Count + 1), host.Item1, host.Item2); _webSocketSessions.Add(webSocketSession.Name, webSocketSession); webSocketSession.Connect(); Task.Factory.StartNew(() => { webSocketSession.Run(); }); // if hotstandby is not supported, stop after connecting to the first host in hosts. Otherwise, // connect to the first two hosts if (_webSocketSessions.Count == 2 || !_hotstandby) { break; } } // after 95% of the time allowed before the token expires, retrive a new set of tokens and send a login to each open websocket while (true) { Thread.Sleep((int)(3000)); // in ms session1 = _webSocketSessions["Session1"]; if (_webSocketSessions.ContainsKey("Session2")) { session2 = _webSocketSessions["Session2"]; } if ((session1 != null && !session1.WebSocketConnected) || (session2 != null && !session2.WebSocketConnected)) { if ((session1 != null && !session1.Reconnecting) || (session2 != null && !session2.Reconnecting)) { curTS = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds; if ((_expiration_in_ms / 1000) < 600) { deltaTime = _expiration_in_ms * 0.95; } else { deltaTime = 300 * 1000; } if (Convert.ToInt64(curTS - deltaTime) >= Convert.ToInt64(_tokenTS)) { if (!GetAuthenticationInfo()) { Console_CancelKeyPress(null, null); } _tokenTS = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds; if (_expiration_in_ms != _original_expiration_in_ms) { System.Console.WriteLine("expire time changed from " + _original_expiration_in_ms / 1000 + " sec to " + _expiration_in_ms / 1000 + " sec; retry login"); if (!GetAuthenticationInfo()) { Console_CancelKeyPress(null, null); } } } } else { if (!GetAuthenticationInfo()) { Console_CancelKeyPress(null, null); } _tokenTS = TimeSpan.FromTicks(DateTime.Now.Ticks).TotalMilliseconds; } if (!session1.Canceling) { if (session1.WebSocket.State != WebSocketState.Open) { session1.Reconnect(); Task.Factory.StartNew(() => { session1.Run(); }); } } if (session2 != null && !session2.Canceling) { if (session2.WebSocket.State != WebSocketState.Open) { session2.Reconnect(); Task.Factory.StartNew(() => { session2.Run(); }); } } } } } catch (Exception ex) { System.Console.WriteLine(ex); Console.ReadKey(); } finally { Console_CancelKeyPress(this, null); Console.ReadKey(); } }