ReceiveNew() public static method

Return a new ZreMsg based received from the input socket. Message is ignored if input is a RouterSocket and the message header doesn't meet the http://rfc.zeromq.org/spec:36 spec. Message is ignored if the message signature doesn't start with %xAA %xA1.
public static ReceiveNew ( NetMQ.Sockets.RouterSocket input, System.Guid &uuid ) : ZreMsg
input NetMQ.Sockets.RouterSocket the socket
uuid System.Guid The identity Guid received into the RoutingId, or Guid.Empty
return ZreMsg
Exemplo n.º 1
0
        /// <summary>
        /// Here we handle messages coming from other peers
        /// </summary>
        private void ReceivePeer()
        {
            Guid uuid;
            var  msg = ZreMsg.ReceiveNew(_inbox, out uuid);

            if (msg == null)
            {
                // Ignore a bad message (header or message signature doesn't meet http://rfc.zeromq.org/spec:36)
                _loggerDelegate?.Invoke("Ignoring a bad message (header or message signature doesn't meet http://rfc.zeromq.org/spec:36).");
                return;
            }
            if (uuid == _uuid)
            {
                var text = $"({_name}) Our own message should not be coming back to us! {_uuid}";
                _loggerDelegate?.Invoke(text);
                throw new InvalidOperationException(text);
            }
            _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(ReceivePeer)}() received message={msg}");
            Debug.Assert(uuid != _uuid, $"({_name}) Our own message should not be coming back to us! uuid={_uuid}");
            ZyrePeer peer;

            if (!_peers.TryGetValue(uuid, out peer))
            {
                _loggerDelegate?.Invoke($"Peer {uuid.ToShortString6()} is unknown.");
            }
            if (msg.Id == ZreMsg.MessageId.Hello)
            {
                // On HELLO we may create the peer if it's unknown
                // On other commands the peer must already exist
                if (peer != null)
                {
                    // Remove fake peers
                    if (peer.Ready)
                    {
                        _loggerDelegate?.Invoke("Removing fake peer={peer} because we received another HELLO from the same uuid.");
                        RemovePeer(peer);
                        Debug.Assert(!_peers.ContainsKey(uuid));
                    }
                    else if (peer.Endpoint == _endpoint)
                    {
                        // We ignore HELLO, if peer has same endpoint as current node
                        _loggerDelegate?.Invoke("Ignoring HELLO for peer that has same endpoint as current node.");
                        return;
                    }
                }
                peer = RequirePeer(uuid, msg.Hello.Endpoint);
                //_loggerDelegate?.Invoke($"TMP Did {nameof(RequirePeer)}");
                peer.Ready = true;
            }
            if (peer == null)
            {
                _loggerDelegate?.Invoke("Ignoring null peer");
                return;
            }
            if (!peer.Ready)
            {
                // Ignore command if peer isn't ready
                _loggerDelegate?.Invoke($"Ignoring peer that isn't ready: {peer}");
                return;
            }
            if (peer.MessagesLost(msg))
            {
                _loggerDelegate?.Invoke($"MessagesLost! {nameof(ZyreNode)}.{nameof(ReceivePeer)}() ignoring message={msg} and removing peer={peer} ");
                RemovePeer(peer);
                return;
            }

            // Now process each command
            _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(ReceivePeer)}() is now ready to process this {msg.Id} command.");
            switch (msg.Id)
            {
            case ZreMsg.MessageId.Hello:
                // Store properties from HELLO command into peer
                var helloMessage = msg.Hello;
                peer.Name    = helloMessage.Name;
                peer.Headers = helloMessage.Headers;

                // Tell the caller about the peer
                var headersBuffer = Serialization.BinarySerialize(peer.Headers);
                _outbox.SendMoreFrame("ENTER").SendMoreFrame(peer.Uuid.ToByteArray()).SendMoreFrame(peer.Name).SendMoreFrame(headersBuffer).SendFrame(helloMessage.Endpoint);
                _loggerDelegate?.Invoke($"ENTER name={peer.Name} endpoint={peer.Endpoint}");

                // Join peer to listed groups
                foreach (var groupName in helloMessage.Groups)
                {
                    JoinPeerGroup(peer, groupName);
                }

                // Now take peer's status from HELLO, after joining groups
                peer.Status = helloMessage.Status;
                _loggerDelegate?.Invoke($"Hello message has been processed for peer: {peer}");
                break;

            case ZreMsg.MessageId.Whisper:
                // Pass up to caller API as WHISPER event
                _outbox.SendMoreFrame("WHISPER").SendMoreFrame(uuid.ToByteArray()).SendMoreFrame(peer.Name).SendMultipartMessage(msg.Whisper.Content);
                break;

            case ZreMsg.MessageId.Shout:
                // Pass up to caller API as SHOUT event
                _outbox.SendMoreFrame("SHOUT").SendMoreFrame(uuid.ToByteArray()).SendMoreFrame(peer.Name).SendMoreFrame(msg.Shout.Group).SendMultipartMessage(msg.Shout.Content);
                break;

            case ZreMsg.MessageId.Join:
                JoinPeerGroup(peer, msg.Join.Group);
                Debug.Assert(msg.Join.Status == peer.Status);
                break;

            case ZreMsg.MessageId.Leave:
                LeavePeerGroup(peer, msg.Leave.Group);
                Debug.Assert(msg.Leave.Status == peer.Status);
                break;

            case ZreMsg.MessageId.Ping:
                break;

            case ZreMsg.MessageId.PingOk:
                Debug.Fail("Unexpected");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Activity from peer resets peer timers
            peer.Refresh();
            //_loggerDelegate?.Invoke($"TMP Leaving {nameof(ReceivePeer)}");
        }