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 List cachedPeerList; private double communicationRate; private Random rand; public void Init(PeerInfo source, string contactServerUrl, double communicationRate) { serverString = contactServerUrl; this.communicationRate = communicationRate; myself = source; cachedPeerList = new List(); rand = new Random(); //Init ChannelFactory and Client var binding = new NetTcpBinding(); var endpoint = new EndpointAddress(serverString); myChannelFactory = new ChannelFactory(binding, endpoint); client = myChannelFactory.CreateChannel(); //Register Peer client.RegisterPeer(myself); //Start heartbeat timer timer = new Timer(1000 * 20); //each 20 seconds timer.Elapsed += RefreshPeerList; timer.Start(); } public List GetPeerList() { return cachedPeerList; } public void SendLogToServer(string msg) { client.MakeLog(myself, msg); } public void Dispose() { timer.Stop(); timer.Dispose(); ((IClientChannel)client).Close(); myChannelFactory.Close(); myChannelFactory = null; } private List ChoosePeersForMessaging(ref List allPeers) { Shuffle(allPeers); int toTake = Convert.ToInt32(allPeers.Count * communicationRate) + 1; if (allPeers.Count > 0 && toTake == 0) { toTake = 1; } return allPeers.Take(toTake).ToList(); ; } private void Shuffle(IList list) { int n = list.Count; while (n > 1) { n--; int k = rand.Next(n + 1); T value = list[k]; list[k] = list[n]; list[n] = value; } } private void RefreshPeerList(object sender, ElapsedEventArgs e) { lock (timerLock) { try { var allPeers = client.GetPeerList(myself); cachedPeerList = ChoosePeersForMessaging(ref allPeers); } catch { } //nothing to do } } } }