private void initICCC() { // The message to request the current listeners: var messageListeners = new ICCCGetListeners(); var messageListenersData = ICCCProcessor.INSTANCE.convertMessage2Data(messageListeners); // The messagw to request the current hosts: var messageHosts = new ICCCGetHosts(); var messageHostsData = ICCCProcessor.INSTANCE.convertMessage2Data(messageHosts); this.initialOceanServersLock.EnterReadLock(); try { // An endless loop until we got the initial connection done: while(true) { var chosenServer = "127.0.0.1:60000"; if(this.initialOceanServers.Count == 1) { // In case of only one, take that: chosenServer = this.initialOceanServers[0]; } if(this.initialOceanServers.Count > 1) { // Select a random server: chosenServer = this.initialOceanServers[BetterRND.INSTANCE.nextInt(0, this.initialOceanServers.Count)]; } // // Build an listener regarding this server for the first message: // var tmpListener = new ICCCListener(); tmpListener.Channel = messageListeners.getChannel(); tmpListener.Command = messageListeners.getCommand(); tmpListener.IPAddressPort = chosenServer; tmpListener.IsActive = true; tmpListener.Kind = ICCCKind.KindOcean; // Send the message: var answerData = this.sendMessage(messageListenersData, tmpListener); // Decode the answer: var messageListenerAnswer = ICCCProcessor.INSTANCE.convertData2Message(answerData, messageListeners.getAnswerObject()) as ICCCGetListenersAnswer; // Was the request successful? if(messageListenerAnswer == null) { // No: Re-try! Thread.Sleep(TimeSpan.FromSeconds(30)); continue; } // Store the listeners: this.cacheLock.EnterWriteLock(); try { this.icccListenerCache.Clear(); var countEntries = messageListenerAnswer.Channels.Length; for(var n = 0; n < countEntries; n++) { this.icccListenerCache.Add(new ICCCListener(messageListenerAnswer.Channels[n], messageListenerAnswer.Commands[n], messageListenerAnswer.IPAddressesPorts[n], true, messageListenerAnswer.Kinds[n])); } } finally { this.cacheLock.ExitWriteLock(); } // // Build an listener regarding this server for the second message: // tmpListener = new ICCCListener(); tmpListener.Channel = messageHosts.getChannel(); tmpListener.Command = messageHosts.getCommand(); tmpListener.IPAddressPort = chosenServer; tmpListener.IsActive = true; tmpListener.Kind = ICCCKind.KindOcean; // Send the message: answerData = this.sendMessage(messageHostsData, tmpListener); // Decode the answer: var messageHostsAnswer = ICCCProcessor.INSTANCE.convertData2Message(answerData, messageHosts.getAnswerObject()) as ICCCGetHostsAnswer; // Was the request successful? if(messageHostsAnswer == null) { // No: Re-try! Thread.Sleep(TimeSpan.FromSeconds(30)); continue; } // Store the hosts: this.cacheLock.EnterWriteLock(); try { this.icccHostsCache.Clear(); var countEntries = messageHostsAnswer.Hostnames.Length; for(var n = 0; n < countEntries; n++) { this.icccHostsCache.Add(new ICCCHost(messageHostsAnswer.Hostnames[n], messageHostsAnswer.IPAddressesPorts[n], messageHostsAnswer.Kinds[n])); } } finally { this.cacheLock.ExitWriteLock(); } break; } } finally { this.initialOceanServersLock.ExitReadLock(); } }
/// <summary> /// Sends the message to the wire. This method is thread-safe! /// </summary> /// <param name="data">The sending message's data.</param> /// <param name="listener">The receiving listener.</param> /// <returns>The answer's data.</returns> internal NameValueCollection sendMessage(NameValueCollection data, ICCCListener listener) { if(data == null || listener == null || data.Count < 2) // channel + command = 2 { return new NameValueCollection(); } try { // First of all, sign the message: data = ICCCProcessor.INSTANCE.signMessage(data); // Get a web client: using(var web = new WebClient()) { // Send the request / message to the wire and wait & read the answer: var responseBytes = web.UploadValues(string.Format("http://{0}/ICCC", listener.IPAddressPort), data); // Converts the answer's bytes to text: var answerBody = ASCIIEncoding.UTF8.GetString(responseBytes); // No answer? if(answerBody == null || answerBody == string.Empty) { return new NameValueCollection(); } // Convert the text to values: return HttpUtility.ParseQueryString(answerBody); } } catch { return new NameValueCollection(); } }