/// <summary> /// Runs server thread. /// Perform server polling for new requests. /// </summary> private void Run() { Debug.WriteLine("Starting Server Thread with ID: " + serverIndex + " at " + DateTime.Now.ToString()); Http http = new Http(serverIndex); while (settings.Servers[serverIndex].Cookie == null) { Thread.Sleep(1000); } while (true) { bool receiveNow = false; lock (thisLock) { receiveNow = (queues.Values.Count > 0); } // nothing to do - wait if (!receiveNow) { Thread.Sleep(http.fetchMessageTimeoutRetryDelay); continue; } else { // TODO: Handle situation when network is down Debug.WriteLine("Entering FetchMessage at " + DateTime.Now.ToString()); ServerResponse sr = http.FetchMessage(settings.Servers[serverIndex].InstanceId, settings.Servers[serverIndex].Cookie, settings.Servers[serverIndex].LastMessageId); // check if message is valid if (sr.token == null) { Debug.WriteLine("Skipped message with empty token"); continue; } OutgoingMessage om = new OutgoingMessage { Action = "Received", Id = sr.id, Token = sr.token, Data = JsonConvert.SerializeObject(sr.data) }; Debug.WriteLine("Entering send message at " + DateTime.Now.ToString()); int currentReaders = 0; string path; string args; lock (thisLock) { try { AppInfo ai = settings.Servers[serverIndex].Queues.First(queue => queue.Token.Equals(om.Token)); if (queues.ContainsKey(ai.GetKey())) { P2PMessageQueue q = queues[ai.GetKey()]; currentReaders = q.CurrentReaders; path = ai.Path; args = ai.Args; } else { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); continue; } } catch (InvalidOperationException) { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); continue; } } // if no readers - start the app and make sure that Ai is still valid bool messageSkipped = false; if (currentReaders == 0) { Process.Start(path, args); while (currentReaders == 0) { Thread.Sleep(10000); lock (thisLock) { try { AppInfo ai = settings.Servers[serverIndex].Queues.First(queue => queue.Token.Equals(om.Token)); if (queues.ContainsKey(ai.GetKey())) { P2PMessageQueue q = queues[ai.GetKey()]; currentReaders = q.CurrentReaders; } else { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); messageSkipped = true; break; } } catch (InvalidOperationException) { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); messageSkipped = true; break; } } } if (messageSkipped) { continue; } // give a chance for the client app to fully initialize Thread.Sleep(10000); } // send the message lock (thisLock) { try { AppInfo ai = settings.Servers[serverIndex].Queues.First(queue => queue.Token.Equals(om.Token)); if (queues.ContainsKey(ai.GetKey())) { P2PMessageQueue q = queues[ai.GetKey()]; string data = JsonConvert.SerializeObject(om); Message message = new Message(Encoding.UTF8.GetBytes(data), false); Debug.WriteLine("About to send message at " + DateTime.Now.ToString()); ReadWriteResult result = q.Send(message, 0); // If message delivered save its id // TODO: Verify client responce to ensure message is readed if (result == ReadWriteResult.OK) { settings.Servers[serverIndex].LastMessageId = sr.id; Settings.Save(settings); } else { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token + ", result of Send is : " + result.ToString()); } Debug.WriteLine("Delivered: " + ai.GetKey() + ", " + data + " at " + DateTime.Now.ToString()); } else { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); } } catch (InvalidOperationException) { Debug.WriteLine("Skipped: " + om.Id + ", " + om.Token); } } } } }