private bool HandshakeServer(SymServer symServer) { try { if (symServer == null) { return(false); } symServer.IsInUse = true; //var client = _symConnectionList[symServer.Id]; var client = _symConnectionList.Find(symConn => symConn.Id == symServer.Id).TcpClient; // open if not already open if (!client.Connected) { client.Connect(symServer.Host, symServer.Port); } // send/rcv buffers var req = Encoding.ASCII.GetBytes("HANDSHAKE\n"); var resp = new byte[_maxbuffersize]; // send handshake var socket = client.Client; socket.Send(req); // get & validate response socket.Receive(resp); var handshakeResponse = Encoding.ASCII.GetString(resp).Replace("\0", "").Replace("\n", "").Trim(); //trim nulls and control chars; if (handshakeResponse.StartsWith("RSHANDSHAKE")) { // good response symServer.IsInUse = false; return(true); } // bad response; leave host out of pool return(false); } catch (SocketException s) { if (s.ErrorCode == 10061) // refused; connection not open or in use { // take server out of rotation symServer.IsFaulted = true; return(false); } // take server out of rotation symServer.IsFaulted = true; return(false); } }
/// <summary> /// Asyncronously fetch our next symServer from the list /// </summary> /// <returns></returns> private async Task <SymServer> AcquireNextHost() { int attempts = 0; //set a task completion source and a timer, attempt to re-acquire our socket every TaskCompletionSource <SymServer> tcs = null; SymServer acquiredServer = null; //set timer for retry interval on send var t = new System.Timers.Timer() { AutoReset = true, Enabled = true, Interval = _retryInterval }; //create task completion source loop tcs = new TaskCompletionSource <SymServer>(t); t.Elapsed += (sender, e) => { var senderTimer = sender as System.Timers.Timer; lock (_acquireSocketLock) { acquiredServer = GetNextHost(); } attempts++; if (acquiredServer != null || attempts > _maxRetries) { senderTimer.Close(); if (!tcs.TrySetResult(acquiredServer)) { System.Diagnostics.Debug.WriteLine("Failed to set result for host acquisition"); } } }; //activate our timer t.Start(); //await our task result return(await tcs.Task); }
private void UnlockHost(SymServer host) { // unlock server host.IsInUse = false; }