/// <summary> /// Construct new group object /// </summary> /// <param name="name">name of the new group</param> /// <param name="container">container of groups</param> /// <returns>the new group</returns> internal static ZyreGroup NewGroup(string name, Dictionary <string, ZyreGroup> container) { var group = new ZyreGroup(name); container[name] = group; return(group); }
/// <summary> /// Find or create group via its name /// </summary> /// <param name="groupName"></param> /// <returns></returns> private ZyreGroup RequirePeerGroup(string groupName) { ZyreGroup group; if (!_peerGroups.TryGetValue(groupName, out group)) { group = ZyreGroup.NewGroup(groupName, _peerGroups); } return(group); }
/// <summary> /// Remove peer from group, if it's a member /// </summary> /// <param name="group"></param> /// <param name="peer"></param> private void RemovePeerFromGroup(ZyreGroup group, ZyrePeer peer) { group.Leave(peer); }
// /// <summary> // /// Return a string showing the class name and method of method calling the method calling this method, used for reporting errors // /// </summary> // /// <returns>the name of the calling method</returns> // private static string MethodNameLevelAbove() // { // var stackTrace = new System.Diagnostics.StackTrace(new Exception(), false); // var stackFrame = stackTrace.GetFrames()[2]; // var mb = stackFrame.GetMethod(); // return mb.ReflectedType.Name + ":" + mb.Name + "()"; // } /// <summary> /// Remove peer from group, if it's a member /// </summary> /// <param name="group"></param> /// <param name="peer"></param> private void RemovePeerFromGroup(ZyreGroup group, ZyrePeer peer) { group.Leave(peer); }
/// <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); } }
/// <summary> /// Construct new group object /// </summary> /// <param name="name">name of the new group</param> /// <param name="container">container of groups</param> /// <returns>the new group</returns> internal static ZyreGroup NewGroup(string name, Dictionary<string, ZyreGroup> container) { var group = new ZyreGroup(name); container[name] = group; return group; }