internal void Init(FalconPeer falconPeer, bool listenForReply, float durationSeconds, int numOfSignalsToEmit, int maxNumOfPeersToDiscover, IEnumerable <IPEndPoint> endPointsToSendTo, Guid?token, DiscoveryCallback callback) { // NOTE: This class is re-used from a pool so this method needs to fully reset // the class. if (listenForReply) { Debug.Assert(callback != null, "callback required if listening for a reply"); } else { Debug.Assert(callback == null, "callback must be null if not listening for a reply"); } Debug.Assert(maxNumOfPeersToDiscover > 0, "max no. of peers to receive a reply must be greater than 0"); this.TaskEnded = false; this.falconPeer = falconPeer; this.emitCount = 0; this.listenForReply = listenForReply; this.callback = callback; this.secondsBetweenEmits = (durationSeconds / numOfSignalsToEmit); this.totalEmits = numOfSignalsToEmit; this.maxNumberPeersToDiscover = maxNumOfPeersToDiscover; this.token = token; this.ellapsedSecondsSinceLastEmit = 0.0f; if (token.HasValue) { Buffer.BlockCopy(Const.DISCOVER_PACKET_WITH_TOKEN_HEADER, 0, signal, 0, Const.DISCOVER_PACKET_WITH_TOKEN_HEADER.Length); Buffer.BlockCopy(token.Value.ToByteArray(), 0, signal, Const.DISCOVER_PACKET.Length, Const.DISCOVERY_TOKEN_SIZE); } else { Buffer.BlockCopy(Const.DISCOVER_PACKET, 0, signal, 0, Const.DISCOVER_PACKET.Length); } this.endPointsToSendTo.Clear(); this.endPointsToSendTo.AddRange(endPointsToSendTo); this.endPointsReceivedReplyFrom.Clear(); }
void IDiscovery.OnDiscoveryRequest(string contractName, string contractNamespace, Uri[] scopesToMatch) { if (m_Addresses.Count == 0) { return; } //Callback to the client wanting to discover IDiscoveryCallback clientCallback = OperationContext.Current.GetCallbackChannel <IDiscoveryCallback>(); DiscoveryCallback serviceCallback = new DiscoveryCallback(clientCallback); Action <string> discover = (address) => { IDiscovery serviceProxy = DuplexChannelFactory <IDiscovery, IDiscoveryCallback> .CreateChannel(serviceCallback, DiscoveryFactory.Binding, new EndpointAddress(address as string)); CancellationTokenSource cancellationSource = new CancellationTokenSource(); EventHandler cleanup = delegate { //Will still be Opening if service was not found and the discovery period expires. ICommunicationObject proxy = serviceProxy as ICommunicationObject; if (proxy.State != CommunicationState.Faulted) { try { proxy.Close(); } catch {} } cancellationSource.Cancel(); }; (clientCallback as ICommunicationObject).Closed += cleanup; (clientCallback as ICommunicationObject).Faulted += cleanup; Task.Delay(DiscoveryFactory.Binding.SendTimeout).ContinueWith(_ => cleanup(null, EventArgs.Empty), cancellationSource.Token); try { serviceProxy.OnDiscoveryRequest(contractName, contractNamespace, scopesToMatch); } catch { Trace.Write("Some problem occurred publishing to a service."); } }; m_Addresses.ForEachAsync(discover); }
internal void AddDiscoveryReply(IPEndPoint endPointReceivedFrom) { // check we haven't already discovered this peer if (endPointsReceivedReplyFrom.Exists(ep => ep.FastEquals(endPointReceivedFrom))) { return; } // raise PeerDiscovered event falconPeer.RaisePeerDiscovered(endPointReceivedFrom); // add to list of end points received reply from endPointsReceivedReplyFrom.Add(endPointReceivedFrom); if (endPointsReceivedReplyFrom.Count == maxNumberPeersToDiscover) { callback(endPointsReceivedReplyFrom.ToArray()); callback = null; // prevent possible subsequent Tick() calling the callback again TaskEnded = true; } }
public void Discover(DiscoveryCallback callback) { coordinator.StartListen(); ATCommandRequestFrame discoverNodes = FrameBuilder.ATCommandRequest .setATCommandName("ND") .Build() as ATCommandRequestFrame; coordinator.EnqueueFrame(discoverNodes, delegate(Frame frame) { if (!(frame is ATCommandResponseFrame)) { return false; } bool endOfDiscovery = HandleNetworkDiscoveryResponse(new NetworkDiscoveryResponseFrame(frame as ATCommandResponseFrame)); if (endOfDiscovery && callback != null) { callback(knownDevices); } return endOfDiscovery; }); }