using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using DistributedGA.Core.Domain; using DistributedGA.Core.Interface; using System.Timers; namespace DistributedGA.Core.Implementation { public class WcfPeerListManager : IPeerListManager { private string serverString = null; private PeerInfo myself = null; private Timer timer = null; //sends heartbeat to contact-server private Object timerLock = new Object(); private ChannelFactory myChannelFactory; private IContactService client; private IContactService heartbeatClient; private int communicationRate; //how many peers are contacted by this peer in percent public void Init(PeerInfo source, string contactServerUrl, int communicationRate) { serverString = contactServerUrl; this.communicationRate = communicationRate; myself = source; //Init ChannelFactory and Clients var binding = new NetTcpBinding(); var endpoint = new EndpointAddress(serverString); myChannelFactory = new ChannelFactory(binding, endpoint); client = myChannelFactory.CreateChannel(); heartbeatClient = myChannelFactory.CreateChannel(); //Register Peer client.RegisterPeer(source); //Start heartbeat timer timer = new Timer(1000); //each 5 minutes timer.Elapsed += SendHeartbeatToServer; timer.Start(); } public List GetPeerList() { try { var allPeers = client.GetPeerList(myself); //maybe timout exception... var peersForMessaging = ChoosePeersForMessaging(allPeers); //return peersForMessaging; return allPeers; //TODO: Enable 10% list communication } catch { } //if maybe sending failed (because of connection lost, etc.): just ignore return new List(); } public void SendLogToServer(string msg) { client.MakeLog(myself, msg); } public void Dispose() { timer.Stop(); timer.Dispose(); ((IClientChannel)client).Close(); ((IClientChannel)heartbeatClient).Close(); myChannelFactory.Close(); client = null; myChannelFactory = null; } private List ChoosePeersForMessaging(List allPeers) { //communicate with 10% of the network int noOfPeers = allPeers.Count / (100 / communicationRate); List indexList = GetRandomItemIndexes(noOfPeers, 0, allPeers.Count - 1); List res = new List(); foreach (int index in indexList) { res.Add(allPeers.ElementAt(index)); } return allPeers; } private List GetRandomItemIndexes(int noOfItems, int minValue, int maxValue) { List res = new List(); Random rnd = new Random(); int tmp = -1; while (res.Count < noOfItems) { tmp = rnd.Next(minValue, maxValue + 1); if (!res.Contains(tmp)) { res.Add(tmp); } } return res; } private void SendHeartbeatToServer(object sender, ElapsedEventArgs e) { lock (timerLock) { try { heartbeatClient.UpdateHeartbeat(myself); } catch { } //nothing to do } } } }