work with ZRE messages
Example #1
0
        /// <summary>
        /// We do this once a second:
        /// - if peer has gone quiet, send TCP ping and emit EVASIVE event
        /// - if peer has disappeared, expire it
        /// </summary>
        /// <param name="peer">the peer to ping</param>
        /// <returns>true if this peer should be removed</returns>
        private bool PingPeer(ZyrePeer peer)
        {
            if (!_isRunning)
            {
                // We have been stopped. We know longer can communicate to peers.
                return(true);
            }
            if (DateTime.Now >= peer.ExpiredAt)
            {
                return(true);
            }
            if (DateTime.Now >= peer.EvasiveAt)
            {
                // If peer is being evasive, force a TCP ping.
                // ZeroMQTODO: do this only once for a peer in this state;
                // it would be nicer to use a proper state machine
                // for peer management.
                _loggerDelegate?.Invoke($"Peer seems dead/slow: name={peer.Name} endpoint={peer.Endpoint}");
                ZreMsg.SendPing(_outbox, 0);

                // Inform the calling application this peer is being evasive
                _outbox.SendMoreFrame("EVASIVE");
                _outbox.SendMoreFrame(peer.Uuid.ToByteArray());
                _outbox.SendFrame(peer.Name);
            }
            return(false);
        }
Example #2
0
            internal void Read(ZreMsg m)
            {
                int listSize;
                int hashSize;
                int chunkSize;

                byte[] guidBytes;
                byte   version;

                // Version
                version = m.GetNumber1();
                if (version != 2)
                {
                    throw new MessageException("Version is invalid");
                }

                // Sequence
                Sequence = m.GetNumber2();

                // Group
                Group = m.GetString();

                // Status
                Status = m.GetNumber1();
            }
Example #3
0
 /// <summary>
 /// Send message to all peers in group
 /// </summary>
 /// <param name="msg">the message</param>
 internal void Send(ZreMsg msg)
 {
     foreach (var peer in _peers.Values)
     {
         peer.Send(msg);
     }
 }
Example #4
0
 /// <summary>
 /// Send message to all peers in group
 /// </summary>
 /// <param name="msg"></param>
 public void Send(ZreMsg msg)
 {
     foreach (var peer in m_peers.Values)
     {
         peer.Send(msg);
     }
 }
Example #5
0
 /// <summary>
 /// Send message to all peers in group
 /// </summary>
 /// <param name="msg"></param>
 public void Send(ZreMsg msg)
 {
     foreach (var peer in m_peers.Values)
     {
         peer.Send(msg);
     }
 }
Example #6
0
 /// <summary>
 /// Send message to all peers in group
 /// </summary>
 /// <param name="msg">the message</param>
 internal void Send(ZreMsg msg)
 {
     foreach (var peer in _peers.Values)
     {
         peer.Send(msg);
     }
 }
Example #7
0
            internal void Write(ZreMsg m)
            {
                // Version
                m.PutNumber1(2); // Version

                // Sequence
                m.PutNumber2(Sequence);
            }
Example #8
0
 /// <summary>
 /// Send message to peer
 /// </summary>
 /// <param name="msg">the message</param>
 /// <returns>always true</returns>
 public bool Send(ZreMsg msg)
 {
     if (m_connected)
     {
         msg.Sequence = m_sentSequence++;
         msg.Send(m_mailbox);
     }
     return(true);
 }
Example #9
0
            internal void Write(ZreMsg m)
            {
                // Version
                m.PutNumber1(2); // Version

                // Sequence
                m.PutNumber2(Sequence);

                // Group
                m.PutString(Group);

                // Content
            }
Example #10
0
        /// <summary>
        /// Send a PingOk message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        public static void SendPingOk(IOutgoingSocket socket, ushort sequence)
        {
            var msg = new ZreMsg
            {
                Id     = MessageId.PingOk,
                PingOk =
                {
                    Version  =        2,
                    Sequence = sequence,
                }
            };

            msg.Send(socket);
        }
Example #11
0
        /// <summary>
        /// Send a Ping message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <returns>true if message was successfully sent</returns>
        public static bool SendPing(IOutgoingSocket socket, ushort sequence)
        {
            var msg = new ZreMsg
            {
                Id   = MessageId.Ping,
                Ping =
                {
                    Version  =        2,
                    Sequence = sequence,
                }
            };

            return(msg.Send(socket));
        }
Example #12
0
 /// <summary>
 /// Check if messages were lost from peer, returns true if they were
 /// </summary>
 /// <param name="msg"></param>
 /// <returns>true if we have lost one or more message</returns>
 public bool MessagesLost(ZreMsg msg)
 {
     Debug.Assert(msg != null);
     if (msg.Id == ZreMsg.MessageId.Hello)
     {
         //  HELLO always MUST have sequence = 1
         m_wantSequence = 1;
     }
     else
     {
         m_wantSequence = m_wantSequence == UshortMax ? (ushort)0 : m_wantSequence++;
     }
     return(m_wantSequence != msg.Sequence);
 }
Example #13
0
 /// <summary>
 /// Send message to peer
 /// </summary>
 /// <param name="msg">the message</param>
 /// <returns>always true</returns>
 internal bool Send(ZreMsg msg)
 {
     if (Connected)
     {
         msg.Sequence = ++_sentSequence;
         _loggerDelegate?.Invoke($"{nameof(ZyrePeer)}.{nameof(Send)}() sending message={msg} to Endpoint={Endpoint}");
         var success = msg.Send(_mailbox);
         if (!success)
         {
             _loggerDelegate?.Invoke($"{nameof(ZyrePeer)}.{nameof(Send)}() UNABLE to send message={msg} to Endpoint={Endpoint}");
         }
     }
     return(true);
 }
Example #14
0
        /// <summary>
        /// Send a Whisper message to the socket
        /// Warning re WHISPER and SHOUT: The 0MQ spec http://rfc.zeromq.org/spec:36
        ///     says "message content defined as one 0MQ frame. ZRE does not support multi-frame message contents."
        ///     ...on the other hand, it appears that zeromq/zyre also supports multi-frame contents, as per the top of zyre.c
        ///     This C# implementation allows multi-frame contents.
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <param name="content">See warning above</param>
        /// <returns>true if message was successfully sent</returns>
        public static bool SendWhisper(IOutgoingSocket socket, ushort sequence, NetMQMessage content)
        {
            var msg = new ZreMsg
            {
                Id      = MessageId.Whisper,
                Whisper =
                {
                    Version  =        2,
                    Sequence = sequence,
                    Content  = content
                }
            };

            return(msg.Send(socket));
        }
Example #15
0
        /// <summary>
        /// Send a Shout message to the socket
        /// Warning re WHISPER and SHOUT: The 0MQ spec http://rfc.zeromq.org/spec:36
        ///     says "message content defined as one 0MQ frame. ZRE does not support multi-frame message contents."
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <param name="content">See warning above</param>
        public static void SendShout(IOutgoingSocket socket, ushort sequence, NetMQMessage content)
        {
            var msg = new ZreMsg
            {
                Id    = MessageId.Shout,
                Shout =
                {
                    Version  =        2,
                    Sequence = sequence,
                    Content  = content
                }
            };

            msg.Send(socket);
        }
Example #16
0
        /// <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}");
                    _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() 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()}");
            _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() 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...");
            _loggerDelegate?.Invoke($"{nameof(ZyreNode)}.{nameof(RequirePeer)}() created new peer={peer}. Sending Hello message...");
            peer.Send(helloMessage);
            return(peer);
        }
Example #17
0
        /// <summary>
        /// Send a Join message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <param name="group"></param>
        /// <param name="status"></param>
        /// <returns>true if message was successfully sent</returns>
        public static bool SendJoin(IOutgoingSocket socket, ushort sequence, string group, byte status)
        {
            var msg = new ZreMsg
            {
                Id   = MessageId.Join,
                Join =
                {
                    Version  =        2,
                    Sequence = sequence,
                    Group    = group,
                    Status   = status,
                }
            };

            return(msg.Send(socket));
        }
Example #18
0
        /// <summary>
        /// Send a Leave message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <param name="group"></param>
        /// <param name="status"></param>
        public static void SendLeave(IOutgoingSocket socket, ushort sequence, string group, byte status)
        {
            var msg = new ZreMsg
            {
                Id    = MessageId.Leave,
                Leave =
                {
                    Version  =        2,
                    Sequence = sequence,
                    Group    = group,
                    Status   = status,
                }
            };

            msg.Send(socket);
        }
Example #19
0
            internal void Read(ZreMsg m)
            {
                int listSize;
                int hashSize;
                int chunkSize;

                byte[] guidBytes;
                byte   version;

                // Version
                version = m.GetNumber1();
                if (version != 2)
                {
                    throw new MessageException("Version is invalid");
                }

                // Sequence
                Sequence = m.GetNumber2();

                // Endpoint
                Endpoint = m.GetString();

                // Groups
                listSize = (int)m.GetNumber4();
                Groups   = new List <string>(listSize);
                while (listSize-- > 0)
                {
                    string s = m.GetLongString();
                    Groups.Add(s);
                }

                // Status
                Status = m.GetNumber1();

                // Name
                Name = m.GetString();

                // Headers
                hashSize = (int)m.GetNumber4();
                Headers  = new Dictionary <string, string>();
                while (hashSize-- > 0)
                {
                    string key   = m.GetString();
                    string value = m.GetLongString();
                    Headers.Add(key, value);
                }
            }
Example #20
0
            internal void Write(ZreMsg m)
            {
                // Version
                m.PutNumber1(2); // Version

                // Sequence
                m.PutNumber2(Sequence);

                // Endpoint
                m.PutString(Endpoint);

                // Groups
                if (Groups != null)
                {
                    m.PutNumber4((UInt32)Groups.Count);

                    foreach (string s in Groups)
                    {
                        m.PutLongString(s);
                    }
                }
                else
                {
                    m.PutNumber4(0); //  Empty string array
                }
                // Status
                m.PutNumber1(Status);

                // Name
                m.PutString(Name);

                // Headers
                if (Headers != null)
                {
                    m.PutNumber4((UInt32)Headers.Count);

                    foreach (var pair in Headers)
                    {
                        m.PutString(pair.Key);
                        m.PutLongString(pair.Value);
                    }
                }
                else
                {
                    m.PutNumber4(0); //  Empty dictionary
                }
            }
Example #21
0
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="input">the socket</param>
        /// <param name="uuid">The identity Guid received into the RoutingId, or Guid.Empty</param>
        /// <returns>null if not a valid message (message to be ignored)</returns>
        public static ZreMsg ReceiveNew(RouterSocket input, out Guid uuid)
        {
            var msg = new ZreMsg();

            if (msg.Receive(input))
            {
                if (msg.RoutingId.Length != 17 || msg.RoutingId[0] != 0x1)
                {
                    uuid = Guid.Empty;
                    return(null);
                }
                uuid = GetUuid(msg.RoutingId, 1);
                return(msg);
            }
            uuid = Guid.Empty;
            return(null);
        }
Example #22
0
        /// <summary>
        /// Send a Hello message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="endpoint"></param>
        /// <param name="groups"></param>
        /// <param name="status"></param>
        /// <param name="name"></param>
        /// <param name="headers"></param>
        /// <returns>true if message was successfully sent</returns>
        public static bool SendHello(IOutgoingSocket socket, string endpoint, List <string> groups, byte status, string name, Dictionary <string, string> headers)
        {
            var msg = new ZreMsg
            {
                Id    = MessageId.Hello,
                Hello =
                {
                    Endpoint = endpoint,
                    Groups   = groups,
                    Status   = status,
                    Name     = name,
                    Headers  = headers
                }
            };

            return(msg.Send(socket));
        }
Example #23
0
        /// <summary>
        /// Send a Hello message to the socket
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="sequence"></param>
        /// <param name="endpoint"></param>
        /// <param name="groups"></param>
        /// <param name="status"></param>
        /// <param name="name"></param>
        /// <param name="headers"></param>
        public static void SendHello(IOutgoingSocket socket, ushort sequence, string endpoint, List <string> groups, byte status, string name, Dictionary <string, string> headers)
        {
            var msg = new ZreMsg
            {
                Id    = MessageId.Hello,
                Hello =
                {
                    Version  =        2,
                    Sequence = sequence,
                    Endpoint = endpoint,
                    Groups   = groups,
                    Status   = status,
                    Name     = name,
                    Headers  = headers
                }
            };

            msg.Send(socket);
        }
Example #24
0
        /// <summary>
        /// Check if messages were lost from peer, returns true if they were
        /// </summary>
        /// <param name="msg"></param>
        /// <returns>true if we have lost one or more message</returns>
        internal bool MessagesLost(ZreMsg msg)
        {
            Debug.Assert(msg != null);

            //  The sequence number set by the peer and our own calculated sequence number should be the same.
            if (msg.Id == ZreMsg.MessageId.Hello)
            {
                //  HELLO always MUST have sequence = 1
                _wantSequence = 1;
            }
            else
            {
                _wantSequence = _wantSequence == UshortMax ? (ushort)0 : ++_wantSequence;
            }
            if (_wantSequence != msg.Sequence)
            {
                _loggerDelegate?.Invoke($"Sequence error for peer={Name} expected={_wantSequence}, got={msg.Sequence}");
                return(true);
            }
            return(false);
        }
Example #25
0
		public void WhisperTest()
		{
			Action<ZreMsg> setMessage = m => 
			{
				m.Id = ZreMsg.MessageId.Whisper;

				m.Whisper.Sequence = 123;
			};

			Action<ZreMsg> checkMessage = m=> 
			{
				Assert.That(m.Id, Is.EqualTo(ZreMsg.MessageId.Whisper));
				Assert.That(m.Whisper.Sequence, Is.EqualTo(123));               
				Assert.That(m.Whisper.Content.FrameCount, Is.EqualTo(1));                
			};

			using (NetMQContext context = NetMQContext.Create())
			using (var client = context.CreateDealerSocket())
			using (var server = context.CreateRouterSocket())
			{
				server.Bind("inproc://zprototest");
				client.Connect("inproc://zprototest");

				ZreMsg clientMessage = new ZreMsg();
				ZreMsg serverMessage = new ZreMsg();

				for (int i=0; i < 2; i++)
				{
					// client send message to server
					setMessage(clientMessage);				
					clientMessage.Send(client);				
												
					// server receive the message
					serverMessage.Receive(server);
				
					// check that message received ok
					Assert.That(serverMessage.RoutingId, Is.Not.Null);					
					checkMessage(serverMessage);

					// reply to client, no need to set the message, using client data
					serverMessage.Send(server);

					// client receive the message
					clientMessage.Receive(client);
				
					// check that message received ok
					Assert.That(clientMessage.RoutingId, Is.Null);					
					checkMessage(clientMessage);
				}				
			}			
		}	
Example #26
0
 /// <summary>
 /// Send message to peer
 /// </summary>
 /// <param name="msg">the message</param>
 /// <returns>always true</returns>
 public bool Send(ZreMsg msg)
 {
     if (_connected)
     {
         msg.Sequence = _sentSequence++;
         msg.Send(_mailbox);
     }
     return true;
 }
Example #27
0
        /// <summary>
        /// Here we handle the different control messages from the front-end
        /// </summary>
        private void ReceiveApi()
        {
            // Get the whole message off the pipe in one go
            var request = _pipe.ReceiveMultipartMessage();
            var command = request.Pop().ConvertToString();

            switch (command)
            {
            case "UUID":
                _pipe.SendFrame(_uuid.ToByteArray());
                break;

            case "NAME":
                _pipe.SendFrame(_name);
                break;

            case "ENDPOINT":
                _pipe.SendFrame(_endpoint ?? "");
                break;

            case "SET NAME":
                _name = request.Pop().ConvertToString();
                Debug.Assert(!String.IsNullOrEmpty(_name));
                break;

            case "SET HEADER":
                var key   = request.Pop().ConvertToString();
                var value = request.Pop().ConvertToString();
                _headers[key] = value;
                break;

            case "SET PORT":
                var str = request.Pop().ConvertToString();
                Int32.TryParse(str, out _beaconPort);
                break;

            case "SET INTERVAL":
                var intervalStr = request.Pop().ConvertToString();
                TimeSpan.TryParse(intervalStr, out _interval);
                break;

            case "START":
                var interfaceName = request.Pop().ConvertToString();
                Start(interfaceName);
                break;

            case "STOP":
                Stop();
                break;

            case "WHISPER":
                // Get peer to send message to
                var      uuid = PopGuid(request);
                ZyrePeer peer;
                if (_peers.TryGetValue(uuid, out peer))
                {
                    //  Send frame on out to peer's mailbox, drop message
                    //  if peer doesn't exist (may have been destroyed)
                    var msg = new ZreMsg
                    {
                        Id      = ZreMsg.MessageId.Whisper,
                        Whisper = { Content = request }
                    };
                    peer.Send(msg);
                }
                break;

            case "SHOUT":
                // Get group to send message to
                var       groupNameShout = request.Pop().ConvertToString();
                ZyreGroup group;
                if (_peerGroups.TryGetValue(groupNameShout, out group))
                {
                    var msg = new ZreMsg
                    {
                        Id    = ZreMsg.MessageId.Shout,
                        Shout = { Group = groupNameShout, Content = request }
                    };
                    group.Send(msg);
                }
                break;

            case "JOIN":
                var       groupNameJoin = request.Pop().ConvertToString();
                ZyreGroup groupJoin;
                if (!_ownGroups.TryGetValue(groupNameJoin, out groupJoin))
                {
                    // Only send if we're not already in group
                    ZyreGroup.NewGroup(groupNameJoin, _ownGroups);

                    // Update status before sending command
                    _status = _status == UbyteMax ? (byte)0 : ++_status;
                    var msg = new ZreMsg
                    {
                        Id   = ZreMsg.MessageId.Join,
                        Join =
                        {
                            Group  = groupNameJoin,
                            Status = _status
                        }
                    };
                    foreach (var peerJoin in _peers.Values)
                    {
                        peerJoin.Send(msg);
                    }
                }
                break;

            case "LEAVE":
                var       groupNameLeave = request.Pop().ConvertToString();
                ZyreGroup groupLeave;
                if (_ownGroups.TryGetValue(groupNameLeave, out groupLeave))
                {
                    // Only send if we are actually in group
                    // Update status before sending command
                    _status = _status == UbyteMax ? (byte)0 : ++_status;
                    var msg = new ZreMsg
                    {
                        Id    = ZreMsg.MessageId.Leave,
                        Leave =
                        {
                            Group  = groupNameLeave,
                            Status = _status
                        }
                    };
                    foreach (var peerLeave in _peers.Values)
                    {
                        peerLeave.Send(msg);
                    }
                    _ownGroups.Remove(groupNameLeave);
                }
                break;

            case "PEERS":
                // Send the list of the _peers keys
                var peersKeyBuffer = Serialization.BinarySerialize(_peers.Keys.ToList());
                _pipe.SendFrame(peersKeyBuffer);
                break;

            case "PEER ENDPOINT":
                var uuidForEndpoint = PopGuid(request);
                var peerForEndpoint = _peers[uuidForEndpoint];     // throw exception if not found
                _pipe.SendFrame(peerForEndpoint.Endpoint);
                break;

            case "PEER NAME":
                var uuidForName = PopGuid(request);
                var peerForName = _peers[uuidForName];     // throw exception if not found
                _pipe.SendFrame(peerForName.Name);
                break;

            case "PEER HEADER":
                var      uuidForHeader = PopGuid(request);
                var      keyForHeader  = request.Pop().ConvertToString();
                ZyrePeer peerForHeader;
                if (_peers.TryGetValue(uuidForHeader, out peerForHeader))
                {
                    string header;
                    if (peerForHeader.Headers.TryGetValue(keyForHeader, out header))
                    {
                        _pipe.SendFrame(header);
                    }
                    else
                    {
                        _loggerDelegate?.Invoke($"No header with key {keyForHeader} in peer uuidShort={uuidForHeader.ToShortString6()}");
                        _pipe.SendFrame("");
                    }
                }
                else
                {
                    _loggerDelegate?.Invoke($"PEER HEADER requested for peer uuidShort={uuidForHeader.ToShortString6()} that is not a peer");
                    _pipe.SendFrame("");
                }
                break;

            case "PEER GROUPS":
                // Send a list of the _peerGroups keys, comma-delimited
                var peerGroupsKeyBuffer = Serialization.BinarySerialize(_peerGroups.Keys.ToList());
                _pipe.SendFrame(peerGroupsKeyBuffer);
                break;

            case "OWN GROUPS":
                // Send a list of the _ownGroups keys, comma-delimited
                var ownGroupsKeyBuffer = Serialization.BinarySerialize(_ownGroups.Keys.ToList());
                _pipe.SendFrame(ownGroupsKeyBuffer);
                break;

            case "DUMP":
                Dump();
                break;

            case NetMQActor.EndShimMessage:
                // API shut us down
                _poller?.Stop();
                break;

            default:
                throw new ArgumentException(command);
            }
        }
Example #28
0
 /// <summary>
 /// Here we handle the different control messages from the front-end
 /// </summary>
 public void ReceiveApi()
 {
     // Get the whole message off the pipe in one go
     var request = _pipe.ReceiveMultipartMessage();
     var command = request.Pop().ConvertToString();
     switch (command)
     {
         case "UUID":
             _pipe.SendFrame(_uuid.ToString());
             break;
         case "NAME":
             _pipe.SendFrame(_name);
             break;
         case "SET NAME":
             _name = request.Pop().ConvertToString();
             Debug.Assert(!string.IsNullOrEmpty(_name));
             break;
         case "SET HEADER":
             var name = request.Pop().ConvertToString();
             var value = request.Pop().ConvertToString();
             _headers[name] = value;
             break;
         case "SET PORT":
             var str = request.Pop().ConvertToString();
             int.TryParse(str, out _port);
             break;
         case "SET INTERVAL":
             var intervalStr = request.Pop().ConvertToString();
             TimeSpan.TryParse(intervalStr, out _interval);
             break;
         case "START":
             Start();
             break;
         case "STOP":
             Stop();
             break;
         case "WHISPER":
             // Get peer to send message to
             var uuid = PopGuid(request);
             ZrePeer peer;
             if (_peers.TryGetValue(uuid, out peer))
             {
                 //  Send frame on out to peer's mailbox, drop message
                 //  if peer doesn't exist (may have been destroyed)
                 var msg = new ZreMsg
                 {
                     Id = ZreMsg.MessageId.Whisper,
                     Whisper = {Content = request}
                 };
                 peer.Send(msg);
             }
             break;
         case "SHOUT":
             // Get group to send message to
             var groupName = request.Pop().ConvertToString();
             ZreGroup group;
             if (_ownGroups.TryGetValue(groupName, out group))
             {
                 var msg = new ZreMsg
                 {
                     Id = ZreMsg.MessageId.Shout,
                     Shout = {Content = request}
                 };
                 group.Send(msg);
             }
             break;
         case "JOIN":
             var groupNameJoin = request.Pop().ConvertToString();
             ZreGroup groupJoin;
             if (!_ownGroups.TryGetValue(groupNameJoin, out groupJoin))
             {
                 // Only send if we're not already in group
                 var msg = new ZreMsg
                 {
                     Id = ZreMsg.MessageId.Join,
                     Join = {Group = groupNameJoin}
                 };
                 // Update status before sending command
                 IncrementStatus();
                 foreach (var peerJoin in _peers.Values)
                 {
                     peerJoin.Send(msg);
                 }
             }
             break;
         case "LEAVE":
             var groupNameLeave = request.Pop().ConvertToString();
             ZreGroup groupLeave;
             if (_ownGroups.TryGetValue(groupNameLeave, out groupLeave))
             {
                 // Only send if we are actually in group
                 var msg = new ZreMsg
                 {
                     Id = ZreMsg.MessageId.Leave,
                     Join = {Group = groupNameLeave}
                 };
                 // Update status before sending command
                 IncrementStatus();
                 foreach (var peerLeave in _peers.Values)
                 {
                     peerLeave.Send(msg);
                 }
                 _ownGroups.Remove(groupNameLeave);
             }
             break;
         case "PEERS":
             // Send the list of the _peers keys
             var peersKeyBuffer = Serialization.BinarySerialize(_peers.Keys.ToList());
             _pipe.SendFrame(peersKeyBuffer);
             break;
         case "PEER ENDPOINT":
             var uuidForEndpoint = PopGuid(request);
             var peerForEndpoint = _peers[uuidForEndpoint]; // throw exception if not found
             _pipe.SendFrame(peerForEndpoint.Endpoint);
             break;
         case "PEER NAME":
             var uuidForName = PopGuid(request);
             var peerForName = _peers[uuidForName]; // throw exception if not found
             _pipe.SendFrame(peerForName.Name);
             break;
         case "PEER HEADER":
             var uuidForHeader = PopGuid(request);
             var keyForHeader = request.Pop().ConvertToString();
             ZrePeer peerForHeader;
             if (_peers.TryGetValue(uuidForHeader, out peerForHeader))
             {
                 string header;
                 _headers.TryGetValue(keyForHeader, out header);
                 _pipe.SendFrame(header ?? "");
             }
             else
             {
                 _pipe.SendFrame("");
             }
             break;
         case "PEER GROUPS":
             // Send a list of the _peerGroups keys, comma-delimited
             var peerGroupsKeyBuffer = Serialization.BinarySerialize(_peerGroups.Keys.ToList());
             _pipe.SendFrame(peerGroupsKeyBuffer);
             break;
         case "OWN GROUPS":
             // Send a list of the _ownGroups keys, comma-delimited
             var ownGroupsKeyBuffer = Serialization.BinarySerialize(_ownGroups.Keys.ToList());
             _pipe.SendFrame(ownGroupsKeyBuffer);
             break;
         case NetMQActor.EndShimMessage:
             _terminated = true;
             if (_poller != null)
             {
                 _poller.Stop();
             }
             break;
         default:
             throw new ArgumentException(command);
     }
 }
Example #29
0
			internal void Read(ZreMsg m)
			{
				int listSize;
				int hashSize;
				int chunkSize;
				byte[] guidBytes;
				byte version;

				// Version
				version = m.GetNumber1();                          
				if (version != 2) 
				{
					throw new MessageException("Version is invalid");						
				}													

				// Sequence
				Sequence = m.GetNumber2();

			}
Example #30
0
        /// <summary>
        /// Here we handle the different control messages from the front-end
        /// </summary>
        private void ReceiveApi()
        {
            // Get the whole message off the pipe in one go
            var request = _pipe.ReceiveMultipartMessage();
            var command = request.Pop().ConvertToString();
            switch (command)
            {
                case "UUID":
                    _pipe.SendFrame(_uuid.ToByteArray());
                    break;
                case "NAME":
                    _pipe.SendFrame(_name);
                    break;
                case "ENDPOINT":
                    _pipe.SendFrame(_endpoint ?? "");
                    break;
                case "SET NAME":
                    _name = request.Pop().ConvertToString();
                    Debug.Assert(!String.IsNullOrEmpty(_name));
                    break;
                case "SET HEADER":
                    var key = request.Pop().ConvertToString();
                    var value = request.Pop().ConvertToString();
                    _headers[key] = value;
                    break;
                case "SET PORT":
                    var str = request.Pop().ConvertToString();
                    Int32.TryParse(str, out _beaconPort);
                    break;
                case "SET INTERVAL":
                    var intervalStr = request.Pop().ConvertToString();
                    TimeSpan.TryParse(intervalStr, out _interval);
                    break;
                case "START":
                    var interfaceName = request.Pop().ConvertToString();
                    Start(interfaceName);
                    break;
                case "STOP":
                    Stop();
                    break;
                case "WHISPER":
                    // Get peer to send message to
                    var uuid = PopGuid(request);
                    ZyrePeer peer;
                    if (_peers.TryGetValue(uuid, out peer))
                    {
                        //  Send frame on out to peer's mailbox, drop message
                        //  if peer doesn't exist (may have been destroyed)
                        var msg = new ZreMsg
                        {
                            Id = ZreMsg.MessageId.Whisper,
                            Whisper = {Content = request}
                        };
                        peer.Send(msg);
                    }
                    break;
                case "SHOUT":
                    // Get group to send message to
                    var groupNameShout = request.Pop().ConvertToString();
                    ZyreGroup group;
                    if (_peerGroups.TryGetValue(groupNameShout, out group))
                    {
                        var msg = new ZreMsg
                        {
                            Id = ZreMsg.MessageId.Shout,
                            Shout = {Group = groupNameShout, Content = request}
                        };
                        group.Send(msg);
                    }
                    break;
                case "JOIN":
                    var groupNameJoin = request.Pop().ConvertToString();
                    ZyreGroup groupJoin;
                    if (!_ownGroups.TryGetValue(groupNameJoin, out groupJoin))
                    {
                        // Only send if we're not already in group
                        ZyreGroup.NewGroup(groupNameJoin, _ownGroups);

                        // Update status before sending command
                        _status = _status == UbyteMax ? (byte)0 : ++_status;
                        var msg = new ZreMsg
                        {
                            Id = ZreMsg.MessageId.Join,
                            Join =
                            {
                                Group = groupNameJoin,
                                Status = _status
                            }
                        };
                        foreach (var peerJoin in _peers.Values)
                        {
                            peerJoin.Send(msg);
                        }
                    }
                    break;
                case "LEAVE":
                    var groupNameLeave = request.Pop().ConvertToString();
                    ZyreGroup groupLeave;
                    if (_ownGroups.TryGetValue(groupNameLeave, out groupLeave))
                    {
                        // Only send if we are actually in group
                        // Update status before sending command
                        _status = _status == UbyteMax ? (byte)0 : ++_status;
                        var msg = new ZreMsg
                        {
                            Id = ZreMsg.MessageId.Leave,
                            Leave =
                            {
                                Group = groupNameLeave,
                                Status = _status
                            }
                        };
                        foreach (var peerLeave in _peers.Values)
                        {
                            peerLeave.Send(msg);
                        }
                        _ownGroups.Remove(groupNameLeave);
                    }
                    break;
                case "PEERS":
                    // Send the list of the _peers keys
                    var peersKeyBuffer = Serialization.BinarySerialize(_peers.Keys.ToList());
                    _pipe.SendFrame(peersKeyBuffer);
                    break;
                case "PEER ENDPOINT":
                    var uuidForEndpoint = PopGuid(request);
                    var peerForEndpoint = _peers[uuidForEndpoint]; // throw exception if not found
                    _pipe.SendFrame(peerForEndpoint.Endpoint);
                    break;
                case "PEER NAME":
                    var uuidForName = PopGuid(request);
                    var peerForName = _peers[uuidForName]; // throw exception if not found
                    _pipe.SendFrame(peerForName.Name);
                    break;
                case "PEER HEADER":
                    var uuidForHeader = PopGuid(request);
                    var keyForHeader = request.Pop().ConvertToString();
                    ZyrePeer peerForHeader;
                    if (_peers.TryGetValue(uuidForHeader, out peerForHeader))
                    {
                        string header;
                        if (peerForHeader.Headers.TryGetValue(keyForHeader, out header))
                        {
                            _pipe.SendFrame(header);
                        }
                        else
                        {
                            _loggerDelegate?.Invoke($"No header with key {keyForHeader} in peer uuidShort={uuidForHeader.ToShortString6()}");
                            _pipe.SendFrame("");
                        }
                    }
                    else
                    {
                        _loggerDelegate?.Invoke($"PEER HEADER requested for peer uuidShort={uuidForHeader.ToShortString6()} that is not a peer");
                        _pipe.SendFrame("");
                    }
                    break;
                case "PEER GROUPS":
                    // Send a list of the _peerGroups keys, comma-delimited
                    var peerGroupsKeyBuffer = Serialization.BinarySerialize(_peerGroups.Keys.ToList());
                    _pipe.SendFrame(peerGroupsKeyBuffer);
                    break;
                case "OWN GROUPS":
                    // Send a list of the _ownGroups keys, comma-delimited
                    var ownGroupsKeyBuffer = Serialization.BinarySerialize(_ownGroups.Keys.ToList());
                    _pipe.SendFrame(ownGroupsKeyBuffer);
                    break;
                case "DUMP":
                    Dump();
                    break;
                case NetMQActor.EndShimMessage:
                    // API shut us down
                    _poller?.Stop();
                    break;
                default:
                    throw new ArgumentException(command);
            }
        }
Example #31
0
		public void HelloTest()
		{
			Action<ZreMsg> setMessage = m => 
			{
				m.Id = ZreMsg.MessageId.Hello;

				m.Hello.Sequence = 123;
    			m.Hello.Endpoint = "Life is short but Now lasts for ever";
				m.Hello.Groups = new List<string>();
				m.Hello.Groups.Add("Name: Brutus");
				m.Hello.Groups.Add("Age: 43");               
				m.Hello.Status = 123;
    			m.Hello.Name = "Life is short but Now lasts for ever";
				m.Hello.Headers = new Dictionary<string,string>();
				m.Hello.Headers.Add("Name", "Brutus");
				m.Hello.Headers.Add("Age", "43");              
			};

			Action<ZreMsg> checkMessage = m=> 
			{
				Assert.That(m.Id, Is.EqualTo(ZreMsg.MessageId.Hello));
				Assert.That(m.Hello.Sequence, Is.EqualTo(123));                 
				Assert.That(m.Hello.Endpoint, Is.EqualTo("Life is short but Now lasts for ever"));                         
				Assert.That(m.Hello.Groups.Count, Is.EqualTo(2));
				Assert.That(m.Hello.Groups[0], Is.EqualTo("Name: Brutus"));                           
				Assert.That(m.Hello.Groups[1], Is.EqualTo("Age: 43"));                                           
				Assert.That(m.Hello.Status, Is.EqualTo(123));                   
				Assert.That(m.Hello.Name, Is.EqualTo("Life is short but Now lasts for ever"));                             
				Assert.That(m.Hello.Headers.Count, Is.EqualTo(2));
				Assert.That(m.Hello.Headers["Name"], Is.EqualTo("Brutus"));                          
				Assert.That(m.Hello.Headers["Age"], Is.EqualTo("43"));                                          
			};

			using (NetMQContext context = NetMQContext.Create())
			using (var client = context.CreateDealerSocket())
			using (var server = context.CreateRouterSocket())
			{
				server.Bind("inproc://zprototest");
				client.Connect("inproc://zprototest");

				ZreMsg clientMessage = new ZreMsg();
				ZreMsg serverMessage = new ZreMsg();

				for (int i=0; i < 2; i++)
				{
					// client send message to server
					setMessage(clientMessage);				
					clientMessage.Send(client);				
												
					// server receive the message
					serverMessage.Receive(server);
				
					// check that message received ok
					Assert.That(serverMessage.RoutingId, Is.Not.Null);					
					checkMessage(serverMessage);

					// reply to client, no need to set the message, using client data
					serverMessage.Send(server);

					// client receive the message
					clientMessage.Receive(client);
				
					// check that message received ok
					Assert.That(clientMessage.RoutingId, Is.Null);					
					checkMessage(clientMessage);
				}				
			}			
		}	
Example #32
0
 /// <summary>
 /// Check if messages were lost from peer, returns true if they were
 /// </summary>
 /// <param name="msg"></param>
 /// <returns>true if we have lost one or more message</returns>
 public bool MessagesLost(ZreMsg msg)
 {
     Debug.Assert(msg != null);
     if (msg.Id == ZreMsg.MessageId.Hello)
     {
         //  HELLO always MUST have sequence = 1
         _wantSequence = 1;
     }
     else
     {
         _wantSequence = _wantSequence == UshortMax ? (ushort)0 : _wantSequence++;
     }
     return _wantSequence != msg.Sequence;
 }
Example #33
0
			internal void Write(ZreMsg m)
			{
				// Version
				m.PutNumber1(2); // Version

				// Sequence
				m.PutNumber2(Sequence);

				// Endpoint
				m.PutString(Endpoint);

				// Groups
				if (Groups != null) 
				{
					m.PutNumber4((UInt32)Groups.Count);

					foreach (string s in Groups)
					{
						m.PutLongString(s);
					}                
				}
				else
					m.PutNumber4(0);    //  Empty string array

				// Status
				m.PutNumber1(Status);

				// Name
				m.PutString(Name);

				// Headers
				if (Headers != null) 
				{
					m.PutNumber4((UInt32)Headers.Count);
               
					foreach(var pair in Headers)
					{
						m.PutString(pair.Key);
						m.PutLongString(pair.Value);
					}				
				}
				else
					m.PutNumber4(0);    //  Empty dictionary

			}
Example #34
0
 /// <summary>
 /// Send a PingOk message to the socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 public static void SendPingOk(IOutgoingSocket socket, ushort sequence)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.PingOk,
         PingOk =
         {
             Version = 2,
             Sequence = sequence,
         }
     };
     msg.Send(socket);
 }
Example #35
0
 /// <summary>
 /// 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.
 /// </summary>
 /// <param name="input">the socket</param>
 /// <param name="uuid">The identity Guid received into the RoutingId, or Guid.Empty</param>
 /// <returns>null if not a valid message (message to be ignored)</returns>
 public static ZreMsg ReceiveNew(RouterSocket input, out Guid uuid)
 {
     var msg = new ZreMsg();
     if (msg.Receive(input))
     {
         if (msg.RoutingId.Length != 17 || msg.RoutingId[0] != 0x1)
         {
             uuid = Guid.Empty;
             return null;
         }
         uuid = GetUuid(msg.RoutingId, 1);
         return msg;
     }
     uuid = Guid.Empty;
     return null;
 }
Example #36
0
 /// <summary>
 /// Send a Leave message to the socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 /// <param name="group"></param>
 /// <param name="status"></param>
 public static void SendLeave(IOutgoingSocket socket, ushort sequence, string group, byte status)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Leave,
         Leave =
         {
             Version = 2,
             Sequence = sequence,
             Group = group,
             Status = status,
         }
     };
     msg.Send(socket);
 }
Example #37
0
 /// <summary>
 /// Send a Shout message to the socket
 /// Warning re WHISPER and SHOUT: The 0MQ spec http://rfc.zeromq.org/spec:36 
 ///     says "message content defined as one 0MQ frame. ZRE does not support multi-frame message contents."
 ///     But this C# implementation allows multi-frame contents.
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 /// <param name="content">See warning above</param>
 public static void SendShout(IOutgoingSocket socket, ushort sequence, NetMQMessage content)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Shout,
         Shout =
         {
             Version = 2,
             Sequence = sequence,
             Content = content
         }
     };
     msg.Send(socket);
 }
Example #38
0
 /// <summary>
 /// Send message to peer
 /// </summary>
 /// <param name="msg">the message</param>
 /// <returns>always true</returns>
 internal bool Send(ZreMsg msg)
 {
     if (Connected)
     {
         msg.Sequence = ++_sentSequence;
         _loggerDelegate?.Invoke($"{nameof(ZyrePeer)}.{nameof(Send)}() sending message={msg} to Endpoint={Endpoint}");
         var success = msg.Send(_mailbox);
         if (!success)
         {
             _loggerDelegate?.Invoke($"{nameof(ZyrePeer)}.{nameof(Send)}() UNABLE to send message={msg} to Endpoint={Endpoint}");
         }
     }
     return true;
 }
Example #39
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)}");
        }
Example #40
0
			internal void Read(ZreMsg m)
			{
				int listSize;
				int hashSize;
				int chunkSize;
				byte[] guidBytes;
				byte version;

				// Version
				version = m.GetNumber1();                          
				if (version != 2) 
				{
					throw new MessageException("Version is invalid");						
				}													

				// Sequence
				Sequence = m.GetNumber2();

				// Endpoint
				Endpoint = m.GetString();

				// Groups
				listSize = (int)m.GetNumber4();                
				Groups = new List<string>(listSize);                 
				while (listSize-- > 0) 
				{
					string s = m.GetLongString();
					Groups.Add(s);                    
				}												

				// Status
				Status = m.GetNumber1();

				// Name
				Name = m.GetString();

				// Headers
				hashSize = (int)m.GetNumber4();                
				Headers = new Dictionary<string, string>();                
				while (hashSize-- > 0)  
				{
					string key = m.GetString();
					string value = m.GetLongString();
					Headers.Add(key, value);
				}						

			}
Example #41
0
		public void LeaveTest()
		{
			Action<ZreMsg> setMessage = m => 
			{
				m.Id = ZreMsg.MessageId.Leave;

				m.Leave.Sequence = 123;
    			m.Leave.Group = "Life is short but Now lasts for ever";
				m.Leave.Status = 123;
			};

			Action<ZreMsg> checkMessage = m=> 
			{
				Assert.That(m.Id, Is.EqualTo(ZreMsg.MessageId.Leave));
				Assert.That(m.Leave.Sequence, Is.EqualTo(123));                 
				Assert.That(m.Leave.Group, Is.EqualTo("Life is short but Now lasts for ever"));                            
				Assert.That(m.Leave.Status, Is.EqualTo(123));                   
			};

			using (NetMQContext context = NetMQContext.Create())
			using (var client = context.CreateDealerSocket())
			using (var server = context.CreateRouterSocket())
			{
				server.Bind("inproc://zprototest");
				client.Connect("inproc://zprototest");

				ZreMsg clientMessage = new ZreMsg();
				ZreMsg serverMessage = new ZreMsg();

				for (int i=0; i < 2; i++)
				{
					// client send message to server
					setMessage(clientMessage);				
					clientMessage.Send(client);				
												
					// server receive the message
					serverMessage.Receive(server);
				
					// check that message received ok
					Assert.That(serverMessage.RoutingId, Is.Not.Null);					
					checkMessage(serverMessage);

					// reply to client, no need to set the message, using client data
					serverMessage.Send(server);

					// client receive the message
					clientMessage.Receive(client);
				
					// check that message received ok
					Assert.That(clientMessage.RoutingId, Is.Null);					
					checkMessage(clientMessage);
				}				
			}			
		}	
Example #42
0
			internal void Write(ZreMsg m)
			{
				// Version
				m.PutNumber1(2); // Version

				// Sequence
				m.PutNumber2(Sequence);

				// Group
				m.PutString(Group);

				// Status
				m.PutNumber1(Status);

			}
Example #43
0
        /// <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;
        }
Example #44
0
			internal void Write(ZreMsg m)
			{
				// Version
				m.PutNumber1(2); // Version

				// Sequence
				m.PutNumber2(Sequence);

			}
Example #45
0
File: ZreMsg.cs Project: NetMQ/Zyre
 /// <summary>
 /// Send a Whisper message to the socket
 /// Warning re WHISPER and SHOUT: The 0MQ spec http://rfc.zeromq.org/spec:36 
 ///     says "message content defined as one 0MQ frame. ZRE does not support multi-frame message contents."
 /// 	...on the other hand, it appears that zeromq/zyre also supports multi-frame contents, as per the top of zyre.c
 ///     This C# implementation allows multi-frame contents.
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 /// <param name="content">See warning above</param>
 /// <returns>true if message was successfully sent</returns>
 public static bool SendWhisper(IOutgoingSocket socket, ushort sequence, NetMQMessage content)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Whisper,
         Whisper =
         {
             Version = 2,
             Sequence = sequence,
             Content = content
         }
     };
     return msg.Send(socket);
 }
Example #46
0
 /// <summary>
 /// Send message to one peer
 /// </summary>
 /// <param name="peer">The peer to get msg</param>
 /// <param name="msg">the message to send</param>
 public void SendMessageToPeer(ZrePeer peer, ZreMsg msg)
 {
     peer.Send(msg);
 }
Example #47
0
        /// <summary>
        /// Check if messages were lost from peer, returns true if they were
        /// </summary>
        /// <param name="msg"></param>
        /// <returns>true if we have lost one or more message</returns>
        internal bool MessagesLost(ZreMsg msg)
        {
            Debug.Assert(msg != null);

            //  The sequence number set by the peer and our own calculated sequence number should be the same.
            if (msg.Id == ZreMsg.MessageId.Hello)
            {
                //  HELLO always MUST have sequence = 1
                _wantSequence = 1;
            }
            else
            {
                _wantSequence = _wantSequence == UshortMax ? (ushort) 0 : ++_wantSequence;
            }
            if (_wantSequence != msg.Sequence)
            {
                _loggerDelegate?.Invoke($"Sequence error for peer={Name} expected={_wantSequence}, got={msg.Sequence}");
                return true;
            }
            return false;
        }
Example #48
0
File: ZreMsg.cs Project: NetMQ/Zyre
 /// <summary>
 /// Send a Join message to the socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 /// <param name="group"></param>
 /// <param name="status"></param>
 /// <returns>true if message was successfully sent</returns>
 public static bool SendJoin(IOutgoingSocket socket, ushort sequence, string group, byte status)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Join,
         Join =
         {
             Version = 2,
             Sequence = sequence,
             Group = group,
             Status = status,
         }
     };
     return msg.Send(socket);
 }
Example #49
0
 /// <summary>
 /// Send message to all peers
 /// </summary>
 /// <param name="msg">the message to send</param>
 public void SendPeers(ZreMsg msg)
 {
     foreach (var peer in _peers.Values)
     {
         SendMessageToPeer(peer, msg);
     }
 }
Example #50
0
File: ZreMsg.cs Project: NetMQ/Zyre
 /// <summary>
 /// Send a Ping message to the socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="sequence"></param>
 /// <returns>true if message was successfully sent</returns>
 public static bool SendPing(IOutgoingSocket socket, ushort sequence)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Ping,
         Ping =
         {
             Version = 2,
             Sequence = sequence,
         }
     };
     return msg.Send(socket);
 }
Example #51
0
        /// <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>
        public ZrePeer RequirePeer(Guid uuid, string endpoint)
        {
            Debug.Assert(!string.IsNullOrEmpty(endpoint));
            ZrePeer peer;
            if (_peers.TryGetValue(uuid, out peer))
            {
                return peer;
            }

            // Purge any previous peer on same endpoint
            foreach (var existingPeer in _peers.Values)
            {
                PurgePeer(existingPeer, endpoint);
            }
            peer = ZrePeer.NewPeer(_peers, uuid);
            peer.SetOrigin(_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
                }
            };
            peer.Send(helloMessage);
            return peer;
        }
Example #52
0
 /// <summary>
 /// Send a Hello message to the socket
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="endpoint"></param>
 /// <param name="groups"></param>
 /// <param name="status"></param>
 /// <param name="name"></param>
 /// <param name="headers"></param>
 public static void SendHello(IOutgoingSocket socket, string endpoint, List<string> groups, byte status, string name, Dictionary<string, string> headers)
 {
     var msg = new ZreMsg
     {
         Id = MessageId.Hello,
         Hello =
         {
             Endpoint = endpoint,
             Groups = groups,
             Status = status,
             Name = name,
             Headers = headers
         }
     };
     msg.Send(socket);
 }