/// <summary> /// Find or create peer via its UUID /// </summary> /// <param name="uuid">the identity of peer</param> /// <param name="endpoint">the endpoint to which we will connect the new peer</param> /// <returns>A peer (existing, or new one connected to endpoint)</returns> private ZyrePeer RequirePeer(Guid uuid, string endpoint) { Debug.Assert(!string.IsNullOrEmpty(endpoint)); ZyrePeer peer; if (_peers.TryGetValue(uuid, out peer)) { if (!_reportedKnownPeersTmp.Contains(peer)) { var callingMethod1 = MethodNameLevelAbove(); _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() called by {callingMethod1} returning already-known peer={peer}"); _reportedKnownPeersTmp.Add(peer); } return peer; } // Purge any previous peer on same endpoint foreach (var existingPeer in _peers.Values) { PurgePeer(existingPeer, endpoint); } var callingMethod2 = MethodNameLevelAbove(); _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() called by {callingMethod2} creating new peer with uuidShort={uuid.ToShortString6()}"); peer = ZyrePeer.NewPeer(_peers, uuid, _loggerDelegate); peer.Origin = _name; peer.Connect(_uuid, endpoint); // Handshake discovery by sending HELLO as first message var helloMessage = new ZreMsg { Id = ZreMsg.MessageId.Hello, Hello = { Endpoint = _endpoint, Groups = _ownGroups.Keys.ToList(), Status = _status, Name = _name, Headers = _headers } }; _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() called by {callingMethod2} created new peer={peer}. Sending Hello message..."); peer.Send(helloMessage); return peer; }
private ZyreNode(PairSocket outbox, Action<string> loggerDelegate = null) { _outbox = outbox; _loggerDelegate = loggerDelegate; _beaconPort = ZreDiscoveryPort; _interval = TimeSpan.Zero; // Use default _uuid = Guid.NewGuid(); _peers = new Dictionary<Guid, ZyrePeer>(); _peerGroups = new Dictionary<string, ZyreGroup>(); _ownGroups = new Dictionary<string, ZyreGroup>(); _headers = new Dictionary<string, string>(); // Default name for node is first 6 characters of UUID: // the shorter string is more readable in logs _name = _uuid.ToShortString6(); // Use ZMQ_ROUTER_HANDOVER so that when a peer disconnects and // then reconnects, the new client connection is treated as the // canonical one, and any old trailing commands are discarded. // This RouterHandover option is currently not supported in NetMQ Feb 16 2016 _actor = NetMQActor.Create(RunActor); }