public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 3) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } // get the randon number NetMQFrame randomNumberFrame = message.Pop(); RandomNumber = randomNumberFrame.ToByteArray(); // get the length of the ciphers array NetMQFrame ciphersLengthFrame = message.Pop(); int ciphersLength = BitConverter.ToInt32(ciphersLengthFrame.Buffer, 0); // get the ciphers NetMQFrame ciphersFrame = message.Pop(); CipherSuites = new CipherSuite[ciphersLength]; for (int i = 0; i < ciphersLength; i++) { CipherSuites[i] = (CipherSuite)ciphersFrame.Buffer[i * 2 + 1]; } }
/// <summary> /// verifies if the message replied obeys the MDP 0.2 protocol /// </summary> /// <remarks> /// socket strips [client adr][e] from message /// message -> /// [empty frame][protocol header][service name][reply] /// [empty frame][protocol header][service name][result code of service lookup] /// </remarks> private void ExtractFrames(NetMQMessage reply) { if (reply.FrameCount < 4) { throw new ApplicationException("[CLIENT ERROR] received a malformed reply"); } var emptyFrame = reply.Pop(); if (emptyFrame != NetMQFrame.Empty) { throw new ApplicationException($"[CLIENT ERROR] received a malformed reply expected empty frame instead of: { emptyFrame } "); } var header = reply.Pop(); // [MDPHeader] <- [service name][reply] OR ['mmi.service'][return code] if (header.ConvertToString() != m_mdpClient) { throw new ApplicationException($"[CLIENT INFO] MDP Version mismatch: {header}"); } // var service = reply.Pop(); // [service name or 'mmi.service'] <- [reply] OR [return code] // if (service.ConvertToString() != m_serviceName) // throw new ApplicationException($"[CLIENT INFO] answered by wrong service: {service.ConvertToString()}"); }
private CommitForStorage getCommit(NetMQMessage message) { var context = message.Pop().ConvertToString(); var stream = message.Pop().ConvertToString(); var expectedVersion = message.PopInt64(); var eventCount = message.PopInt32(); var events = new EventForStorage[eventCount]; for (int i = 0; i < eventCount; i++) { var eventId = new Guid(message.Pop().ToByteArray()); var timestamp = message.PopDateTime(); var typeKey = message.PopString(); var headers = message.PopStringOrNull(); var body = message.PopString(); //-1 to override concurrency check. Being lazy and not using a constant. var version = expectedVersion == -1 ? -1 : expectedVersion + i; events[i] = new EventForStorage(eventId, version, timestamp, typeKey, headers, body); } return new CommitForStorage(context, stream, events); }
public NetMQMessage DecryptApplicationMessage([NotNull] NetMQMessage cipherMessage) { if (!SecureChannelReady) { throw new NetMQSecurityException(NetMQSecurityErrorCode.SecureChannelNotReady, "Cannot decrypt messages until the secure channel is ready"); } if (cipherMessage == null) { throw new ArgumentNullException("cipherMessage"); } if (cipherMessage.FrameCount < 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames"); } NetMQFrame protocolVersionFrame = cipherMessage.Pop(); NetMQFrame contentTypeFrame = cipherMessage.Pop(); if (!protocolVersionFrame.ToByteArray().SequenceEqual(m_protocolVersion)) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version"); } ContentType contentType = (ContentType)contentTypeFrame.Buffer[0]; if (contentType != ContentType.ApplicationData) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Not an applicagtion data message"); } return(m_recordLayer.DecryptMessage(ContentType.ApplicationData, cipherMessage)); }
private void ReceiveFromRemote(object sender, NetMQSocketEventArgs e) { NetMQMessage msg = e.Socket.ReceiveMultipartMessage(); string msgtype = msg.Pop().ConvertToString(); Guid remoteId = new Guid(msg.Pop().Buffer); string name = msg.Pop().ConvertToString(); switch (msgtype) { case "ENTER": HandleEnterMessage(remoteId, name); break; case "WHISPER": HandleWhisperMessage(remoteId, name, msg); break; case "SHOUT": HandleShoutMessage(remoteId, name, msg); break; default: break; } }
/// <summary> /// Remove the two frames from the given NetMQMessage, interpreting them thusly: /// 1. a byte with the HandshakeType, assumed to be ClientKeyExchange /// 2. a byte-array containing the EncryptedPreMasterSecret. /// </summary> /// <param name="message">a NetMQMessage - which must have 2 frames</param> /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 1.</exception> public override void SetFromNetMQMessage(NetMQMessage message) { NetMQFrame lengthFrame = message.Pop(); NetMQFrame encryptedPreMasterSecretLengthFrame = message.Pop(); base.SetFromNetMQMessage(message); }
public void Login(string accountNo, string password) { NetMQMessage msg = Channels.SendRequest( BuildMessage( Header(ID_S_ACCOUNT_LOGIN_REQT), new LoginAccountRequest() { AccountNo = accountNo, Password = password })); ResponseHeader header = ResponseHeader.Parser.ParseFrom(msg.Pop().ToByteArray()); WriteLog(header.ToString()); LoginAccountResponse response = LoginAccountResponse.Parser.ParseFrom(msg.Pop().ToByteArray()); WriteLog(response.ToString()); if (header.Code != ResponseStatusCode.ResponseCodeOk) { throw new Exception(header.Message); } Channels.OnSubscribeRecieved += On_SubscribeReceived; Channels.ConnectSubscribe(); Token = response.Token; AccountNo = accountNo; }
private void On_SubscribeReceived(NetMQMessage message) { int count = message.FrameCount; if (count < 3) { return; } string accountNo = message.Pop().ConvertToString(); var msgHeader = message.Pop().ToByteArray(); var payload = message.Pop(); ReportHeader header = ReportHeader.Parser.ParseFrom(msgHeader); if (header.ApiId == ID_STOCK_PLACE_REPORT) { PlacedReport report = PlacedReport.Parser.ParseFrom(payload.ToByteArray()); PlaceReportReceived?.Invoke(accountNo, header, report); } else if (header.ApiId == ID_STOCK_FILL_REPORT) { FillReport report = FillReport.Parser.ParseFrom(payload.ToByteArray()); FillReportReceived?.Invoke(accountNo, header, report); } else if (header.ApiId == ID_STOCK_CANCEL_REPORT) { CancellationReport report = CancellationReport.Parser.ParseFrom(payload.ToByteArray()); CancelReportReceived?.Invoke(accountNo, header, report); } }
public static void Main(string[] args) { NetMQContext context = NetMQContext.Create(); NetMQSocket server = context.CreateRequestSocket(); server.Bind("tcp://*:5555"); NetMQMessage message = new NetMQMessage(); NetMQMessage getmass = new NetMQMessage(); message.Append("Hallo "); message.Append(40); Client client = new Client(); Thread t = new Thread(new ThreadStart(client.runClient)); t.Start(); while (true) { server.SendMessage(message, false); getmass = server.ReceiveMessage(false); System.Console.WriteLine(getmass.Pop().ConvertToString()); System.Console.WriteLine(getmass.Pop().ConvertToInt32()); } }
public NetMQMessage InQueue(NetMQMessage msg) { var outMsg = new NetMQMessage(); if (msg.FrameCount != 2) { outMsg.Append(0); outMsg.Append("占座失败", Encoding.UTF8); return(outMsg); } var seat = msg.Pop().ConvertToInt32(); var name = msg.Pop().ConvertToString(Encoding.UTF8); if (!_queue.ContainsKey(seat) || !_queue[seat].IsNullOrEmpty()) { outMsg.Append(0); outMsg.Append("占座失败", Encoding.UTF8); return(outMsg); } _queue[seat] = name; outMsg.Append(1); outMsg.Append("占座成功", Encoding.UTF8); ShowQueue(); return(outMsg); }
private void HandleUpdate(NetMQMessage m) { var topic = m.Pop().ConvertToString(); long msgid = m.Pop().ConvertToInt64(); var currentMsgid = _messageIds[topic]; if (msgid - currentMsgid > 1 && msgid != 0 && currentMsgid != 0) { try { _messageSequenceGapAction?.Invoke(topic, currentMsgid, msgid); } catch { // ignored } } _messageIds[topic] = msgid; DateTime publishTime = DateTime.FromBinary(m.Pop().ConvertToInt64()); //TODO: do something with publishTime - perf counter, latency alert int frame = m.FrameCount; while (frame-- > 0) { var message = m.Pop().Buffer; var type = _knownTypes[_topics[topic]]; var obj = type.Serializer.Deserialize(message); var key = type.KeyExtractor.Extract(obj); _lastValueCache.AddOrUpdate(topic, key, obj); } }
/// <summary> /// Return a new NetMQMessage that holds three frames: /// 1. a frame with a single byte representing the HandshakeType, which is ClientHello, /// 2. a frame containing the RandomNumber, /// 3. a frame containing the list of CipherSuites. /// </summary> /// <returns>the resulting new NetMQMessage</returns> public override NetMQMessage ToNetMQMessage() { NetMQMessage message = base.ToNetMQMessage(); var handShakeType = message.Pop(); var random = message.Pop(); message.Push(random); message.Push(Version); //压缩方法长度 message.Append(new byte[1] { 1 }); //压缩方法 message.Append(new byte[1] { 0 }); message.Append(new byte[] { 0, 0 }); ////todo:测试 //message.RemoveFrame(message.Last); ////扩展长度 //byte[] extension = "00 0a 00 16 00 14 00 17 00 18 00 19 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 16 00 0b 00 02 01 00 00 0d 00 16 00 14 06 03 06 01 05 03 05 01 04 03 04 01 04 02 02 03 02 01 02 02 00 17 00 00 ff 01 00 01 00".ConvertHexToByteArray(); //message.Append(extension.LengthToBytes(2)); //message.Append(extension); InsertLength(message); message.Push(handShakeType); return(message); }
/// <summary> /// Remove the three frames from the given NetMQMessage, interpreting them thusly: /// 1. a byte with the HandshakeType, presumed here to be ClientHello, /// 2. a byte-array containing the RandomNumber, /// 3. a byte-array with the list of CipherSuites. /// </summary> /// <param name="message">a NetMQMessage - which must have 2 frames</param> /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 3.</exception> public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 3) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } // get the random number NetMQFrame randomNumberFrame = message.Pop(); RandomNumber = randomNumberFrame.ToByteArray(); // get the length of the cipher-suites array NetMQFrame ciphersLengthFrame = message.Pop(); int ciphersLength = BitConverter.ToInt32(ciphersLengthFrame.Buffer, 0); // get the cipher-suites NetMQFrame ciphersFrame = message.Pop(); CipherSuites = new CipherSuite[ciphersLength]; for (int i = 0; i < ciphersLength; i++) { CipherSuites[i] = (CipherSuite)ciphersFrame.Buffer[i * 2 + 1]; } }
/// <summary> /// Check the message envelope for errors /// and get the MDP Command embedded. /// The message will be altered! /// </summary> /// <param name="request">NetMQMessage received</param> /// <returns>the received MDP Command</returns> private MDPCommand GetMDPCommand(NetMQMessage request) { // don't try to handle errors if (request.FrameCount < 3) { throw new ApplicationException("Malformed request received!"); } var empty = request.Pop(); if (!empty.IsEmpty) { throw new ApplicationException("First frame must be an empty frame!"); } var header = request.Pop(); if (header.ConvertToString() != m_mdpWorker) { throw new ApplicationException("Invalid protocol header received!"); } var cmd = request.Pop(); if (cmd.BufferSize > 1) { throw new ApplicationException("MDP Command must be one byte not multiple!"); } var command = (MDPCommand)cmd.Buffer[0]; // Log ($"[WORKER] received a {command}"); return(command); }
public NetMQMessage DecryptApplicationMessage(NetMQMessage cipherMessage) { if (!SecureChannelReady) { throw new NetMQSecurityException(NetMQSecurityErrorCode.SecureChannelNotReady, "Cannot decrypt messages until the secure channel is ready"); } if (cipherMessage == null) { throw new ArgumentNullException("cipherMessage is null"); } if (cipherMessage.FrameCount < 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames"); } NetMQFrame protocolVersionFrame = cipherMessage.Pop(); NetMQFrame contentTypeFrame = cipherMessage.Pop(); if (!protocolVersionFrame.ToByteArray().SequenceEqual(m_protocolVersion)) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version"); } ContentType contentType = (ContentType)contentTypeFrame.Buffer[0]; if (contentType != ContentType.ApplicationData) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Not an applicagtion data message"); } return m_recordLayer.DecryptMessage(ContentType.ApplicationData, cipherMessage); }
public bool ProcessMessage(NetMQMessage incomingMessage, IList <NetMQMessage> outgoingMesssages) { ContentType contentType = ContentType.Handshake; if (incomingMessage != null) { NetMQFrame protocolVersionFrame = incomingMessage.Pop(); byte[] protocolVersionBytes = protocolVersionFrame.ToByteArray(); if (protocolVersionBytes.Length != 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame"); } if (!protocolVersionBytes.SequenceEqual(m_protocolVersion)) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version"); } NetMQFrame contentTypeFrame = incomingMessage.Pop(); if (contentTypeFrame.MessageSize != 1) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for message size"); } contentType = (ContentType)contentTypeFrame.Buffer[0]; if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unkown content type"); } if (ChangeSuiteChangeArrived) { incomingMessage = m_recordLayer.DecryptMessage(contentType, incomingMessage); } } bool result = false; if (contentType == ContentType.Handshake) { result = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag); foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages) { outgoingMesssages.Add(outgoingMesssage); } m_outgoingMessageBag.Clear(); } else { ChangeSuiteChangeArrived = true; } return(SecureChannelReady = result && ChangeSuiteChangeArrived); }
public ZeroMqNotificationReader Init() { if (Initialized) { throw new InvalidOperationException($"{nameof(ZeroMqNotificationReader)} already initialized."); } var completionSource = new TaskCompletionSource <object>(); var token = _source.Token; _receiveTask = Task.Factory.StartNew(() => { var timeout = TimeSpan.FromSeconds(1); using (var subSocket = new SubscriberSocket(EndPoint)) { try { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.SubscribeToAnyTopic(); while (!token.IsCancellationRequested) { var zMessage = new NetMQMessage(2); var messageReceived = subSocket.TryReceiveMultipartMessage(timeout, ref zMessage, 2); completionSource.TrySetResult(null); if (!messageReceived) { continue; } var topic = zMessage.Pop().ConvertToString(Encoding.UTF8); var json = zMessage.Pop().ConvertToString(Encoding.UTF8); OnNotificationReceived?.Invoke(topic, json); } } catch (Exception e) { OnError?.Invoke(e); } } }, TaskCreationOptions.LongRunning); _receiveTask.ContinueWith(t => { // Propagate exception from initialization if occured if (t.Exception != null) { completionSource.TrySetException(t.Exception); } }); completionSource.Task.GetAwaiter().GetResult(); Initialized = true; return(this); }
/// <summary> /// Remove the two frames from the given NetMQMessage, interpreting them thusly: /// 1. a byte with the HandshakeType, /// 2. a byte-array containing the X.509 digital certificate. /// </summary> /// <param name="message">a NetMQMessage - which must have 2 frames</param> /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 1.</exception> public override void SetFromNetMQMessage(NetMQMessage message) { NetMQFrame lengthFrame = message.Pop(); NetMQFrame certslengthFrame = message.Pop(); NetMQFrame certlengthFrame = message.Pop(); base.SetFromNetMQMessage(message); }
/// <summary> /// Strip the message from the first frame and if empty the following frame as well /// </summary> /// <returns>the first frame of the message</returns> private static NetMQFrame Unwrap (NetMQMessage msg) { var result = msg.Pop (); if (msg.First.IsEmpty) msg.Pop (); return result; }
/// <summary> /// returns the first frame and deletes the next frame if it is empty /// /// CHANGES message! /// </summary> private static NetMQFrame UnWrap (NetMQMessage message) { var frame = message.Pop (); if (message.First == NetMQFrame.Empty) message.Pop (); return frame; }
/// <summary> /// get the identity of the sending socket /// we hereby assume that the message has the following /// sequence of frames and strips that off the message /// /// [identity][empty][data] /// /// whereby [data] cold be a wrapped message itself! /// </summary> /// <param name="msg"></param> /// <returns></returns> static byte[] Unwrap(NetMQMessage msg) { var idFrame = msg.Pop(); // throw away the empty frame msg.Pop(); return(idFrame.Buffer); }
/// <summary> /// returns the first frame and deletes the next frame if it is empty /// /// CHANGES message! /// </summary> private NetMQFrame UnWrap(NetMQMessage message) { var frame = message.Pop(); if (message.First == NetMQFrame.Empty) { message.Pop(); } return(frame); }
/// <summary> /// Strip the message from the first frame and if empty the following frame as well /// </summary> /// <returns>the first frame of the message</returns> private NetMQFrame Unwrap(NetMQMessage msg) { var result = msg.Pop(); if (msg.First.IsEmpty) { msg.Pop(); } return(result); }
///<summary> /// Construct a Message from ReceivedFrames - according to /// <para>Frame 1 - RequestTypeName</para> /// <para>Frame 2 - Successful parsing and use of Incoming Instance of RequestType / on Response it is the successful deserialization</para> /// <para>Frame 3 - Actual Payload and instance of the RequestType</para> ///</summary> internal static XtResult <TMessage> ParseRqRepMessage <TMessage>(this NetMQMessage msg, SocketConfiguration configuration) where TMessage : class { configuration.Logger.Log(new DebugLogMsg($"parsing [{typeof(TMessage)}]")); const string operation = "parse-rq-rep-msg"; #region precondition checks if (msg.FrameCount != 3) { var exc = ZeroMqXtSocketException.MissedExpectedFrameCount(msg.FrameCount); configuration.Logger.Log(new DebugLogMsg(exc.Message)); return(XtResult <TMessage> .Failed(exc, operation)); } byte[] typeFrame = msg.Pop().ToByteArray(); byte[] successFrame = msg.Pop().ToByteArray(); byte[] payloadFrame = msg.Pop().ToByteArray(); string msgType = typeof(TMessage).TypeFrameName(); string typeFromFrame = configuration.Serializer.Deserialize <string>(typeFrame); if (typeFromFrame != msgType) { var exception = ZeroMqXtSocketException.Frame1TypeDoesNotMatch <TMessage>(typeFromFrame); configuration.Logger.Log(new DebugLogMsg(exception.Message)); return(XtResult <TMessage> .Failed(exception, operation)); } bool isSuccess = Convert.ToBoolean(configuration.Serializer.Deserialize <string>(successFrame)); if (!isSuccess) { var exceptnText = configuration.Serializer.Deserialize <string>(payloadFrame); var excption = new ZeroMqXtSocketException("Server failed with" + exceptnText); configuration.Logger.Log(new DebugLogMsg(excption.Message)); return(XtResult <TMessage> .Failed(excption, operation)); } #endregion try { // actual message body deserialization TMessage result = configuration.Serializer.Deserialize <TMessage>(payloadFrame); if (result == default(TMessage)) { return(XtResult <TMessage> .Failed(new ArgumentNullException($"{typeof(TMessage)} yielded the default value on deserializing! Proceeding is not safe."), operation)); } configuration.Logger.Log(new DebugLogMsg($"parsing was successful for [{typeof(TMessage)}]")); return(XtResult <TMessage> .Success(result, operation)); } catch (System.Exception ex) { return(XtResult <TMessage> .Failed(ZeroMqXtSocketException.SerializationFailed(ex.Message), operation)); } }
/// <summary> /// Strip the first frame of a message and the following if it is empty /// </summary> /// <returns>the first frame and changes the message</returns> private static NetMQFrame Unwrap(NetMQMessage msg) { var id = msg.Pop(); // forget the empty frame if (msg.First.IsEmpty) { msg.Pop(); } return(id); }
public void Handle(NetMQFrame[] sender, NetMQMessage message) { Logger.Debug("[Queue_SubscribeHandler] Received subscribe request."); var requestId = message.Pop(); var context = message.Pop().ConvertToString(); var queueId = message.Pop().ConvertToString(); var subscriberId = message.Pop().ConvertToString(); var filter = message.Pop().ConvertToString(); var utcStartTime = message.PopDateTime(); var allocationSize = message.PopInt32(); var allocationTimeInMilliseconds = message.PopInt32(); var subscribe = new SubscribeToQueue(context, queueId, subscriberId, filter, utcStartTime, allocationSize, allocationTimeInMilliseconds); var queuedEvents = _storage.Subscribe(subscribe); var events = queuedEvents.Events; var msg = new NetMQMessage(); msg.Append(sender); msg.AppendEmptyFrame(); msg.Append(ResProtocol.ResClient01); msg.Append(requestId); msg.Append(ResCommands.QueuedEvents); msg.Append(context); msg.Append(queueId); msg.Append(subscriberId); msg.Append(DateTime.UtcNow.ToNetMqFrame()); msg.Append(queuedEvents.AllocationId.ToNetMqFrame()); var count = events.Length; msg.Append(count.ToNetMqFrame()); foreach (var e in events) { msg.Append(e.EventId.ToByteArray()); msg.Append(e.Stream); msg.Append(e.Context); msg.Append(e.Sequence.ToNetMqFrame()); msg.Append(e.Timestamp.ToNetMqFrame()); msg.Append(e.TypeKey); msg.Append(e.Headers.ToNetMqFrame()); msg.Append(e.Body); } var result = new QueuedMessagesFetched(msg); while (!_outBuffer.Offer(result)) _spin.SpinOnce(); }
private void DealerSocket_ReceiveReady(object sender, NetMQSocketEventArgs e) { NetMQMessage message = e.Socket.ReceiveMultipartMessage(); string address = message.Pop().ConvertToString(Encoding.UTF8); string content = message.Pop().ConvertToString(Encoding.UTF8); OwinResponse response = _serializer.Deserialize <OwinResponse>(content); if (_requests.TryRemove(response.RequestId, out var taskCompletion)) { taskCompletion.SetResult(response); } }
public static void Main(string[] args) { Console.WriteLine("Hello World!"); var serverTread = new Thread(() => { Log("Start server."); var _server = new ReliableServer("tcp://*:6669"); var index = 0; while (true) { var message = new NetMQMessage(); message.Append("A"); message.Append("hello: " + index); message.Append("world"); _server.Publish(message); Console.WriteLine("publishing: " + message); Thread.Sleep(100); index++; } }); serverTread.Start(); // client_thread_.Start(); //new SimpleClient().Run("tcp://localhost:6669"); var clientTread = new Thread(() => { Log("Start client."); var _client = new ReliableClient("tcp://localhost:6669"); _client.Subscribe("A"); while (true) { NetMQMessage msg = null; msg = _client.ReceiveMessage(); if (msg != null) { var topic = msg.Pop().ConvertToString(); var message = msg.Pop().ConvertToString(); var output = String.Format("reviced topic: {0}, message: {1}", topic, message); Log(output); } Thread.Sleep(10); } }); clientTread.Start(); Console.ReadLine(); }
public static List <Int64> UnpackMessageListInt64(this NetMQMessage msg) { var cnt = (int)msg.Pop().ConvertToInt32(); var buff = msg.Pop().ToByteArray(); var rdr = new BinaryReader(new MemoryStream(LZ4Codec.Unwrap(buff))); List <Int64> ret = new List <Int64>(); while (cnt-- > 0) { ret.Add(rdr.ReadInt64()); } return(ret); }
protected override void OnOutgoingMessage(NetMQMessage message) { byte[] identity = message.Pop().ToByteArray(); // Each frame is a full ZMQ message with identity frame while (message.FrameCount > 0) { var data = message.Pop().ToByteArray(false); bool more = message.FrameCount > 0; WriteOutgoing(identity, data, more); } }
public static List <T> UnpackMessageList <T>(NetMQMessage msg, Func <Stream, T> parseObject) where T : IMessage { var cnt = (int)msg.Pop().ConvertToInt32(); var buff = msg.Pop().ToByteArray(); var rdr = new MemoryStream(buff); List <T> ret = new List <T>(); while (cnt-- > 0) { ret.Add(parseObject(rdr)); } return(ret); }
protected static Tuple <NetMQMessage, Tuple <ServermoduleID, CallID> > SplitMessageInContentAndMetaData(NetMQMessage message) { var servermoduleID = Convert.ToInt32(message.Pop().ConvertToString()); var callID = Convert.ToInt32(message.Pop().ConvertToString()); return(new Tuple <NetMQMessage, Tuple <ServermoduleID, CallID> >(message, new Tuple <ServermoduleID, CallID>(new ServermoduleID() { ID = servermoduleID }, new CallID() { ID = callID }))); }
public void ProcessMessage(NetMQMessage message, NetMQSocket socket) { if (message.FrameCount < 3) throw new MalformedMessageReceivedException(message.FrameCount); var sender = message.PopUntilEmptyFrame(); var protocolFrame = message.Pop(); var protocol = protocolFrame.ConvertToString(); ensureProtocol(protocol); var command = message.Pop().ConvertToString(); _dispatcher.Dispatch(command, sender, message); }
private static void Main(string[] args) { var deciSecond = new TimeSpan(10000); using (var subscriber = new SubscriberSocket()) // For receiving updates from presentation host using (var publisher = new WSPublisher()) // For publishing updates from presentation host to audience using (var responder = new WSRouter()) // Handling on-demand requests for late-joining or crashing clients { subscriber.Bind("tcp://*:3000"); subscriber.SubscribeToAnyTopic(); publisher.Bind("ws://*:3001"); responder.Bind("ws://*:3002"); byte step = 0; subscriber.ReceiveReady += (_, __) => { if (!subscriber.TryReceiveFrameBytes(deciSecond, out var received)) { return; } step = received[0]; Console.Out.WriteLine("Sending " + step + " to audience."); publisher.TrySendFrame(deciSecond, new[] { step }); }; responder.ReceiveReady += (_, __) => { NetMQMessage msg = null; if (!responder.TryReceiveMultipartMessage(deciSecond, ref msg)) { return; } var identity = msg.Pop().Buffer; var request = msg.Pop().ConvertToString(); msg.Clear(); if (request == "Which slide are we on?") { responder.TrySendMultipartBytes(deciSecond, identity, new[] { step }); } else { if (!responder.TrySendFrame(deciSecond, identity, true)) { return; } responder.TrySendFrameEmpty(deciSecond); } }; new NetMQPoller { subscriber, responder }.Run(); // Polling both subscriber and router sockets. } }
public QueryFillsResponse QueryFill(RequestHeader header, QueryFillsRequest payload) { NetMQMessage response = Channels.SendRequest(BuildMessage(header, payload)); ResponseHeader responseHeader = ResponseHeader.Parser.ParseFrom(response.Pop().ToByteArray()); WriteLog(responseHeader.ToString()); QueryFillsResponse responsePayload = QueryFillsResponse.Parser.ParseFrom(response.Pop().ToByteArray()); WriteLog(responsePayload.ToString()); FillsReceived?.Invoke(responsePayload); return(responsePayload); }
public Task Send(ArraySegment<byte> data, params object[] connectionIDs) { var task = new Task(() => { var msg = new NetMQMessage(); if (_socket is RouterSocket) { msg.Append(new byte[0]); msg.AppendEmptyFrame(); } msg.Append(data.Count == data.Array.Length ? data.Array : data.ToArray()); if (connectionIDs.Length <= 0) _socket.SendMultipartMessage(msg); else { foreach (var connection in connectionIDs) { if (_socket is RouterSocket && connection is byte[]) { msg.Pop(); msg.Push(((byte[])connection)); } _socket.SendMultipartMessage(msg); } } }); task.Start(_scheduler); return task; }
/// <summary> /// Remove the three frames from the given NetMQMessage, interpreting them thusly: /// 1. a byte with the HandshakeType, /// 2. RandomNumber (a byte-array), /// 3. a 2-byte array with the CipherSuite in the 2nd byte. /// </summary> /// <param name="message">a NetMQMessage - which must have 3 frames</param> public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } // Get the random number NetMQFrame randomNumberFrame = message.Pop(); RandomNumber = randomNumberFrame.ToByteArray(); // Get the cipher suite NetMQFrame cipherSuiteFrame = message.Pop(); CipherSuite = (CipherSuite)cipherSuiteFrame.Buffer[1]; }
public virtual void SetFromNetMQMessage(NetMQMessage message) { if (message.FrameCount == 0) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } // remove the handshake type column message.Pop(); }
public void Handle(NetMQFrame[] sender, NetMQMessage message) { Log.Debug("[CommitHandler] Got a commit to write..."); var requestId = message.Pop(); var commit = getCommit(message); var task = _writer.Store(commit); var commitContinuationContext = new CommitContinuationContext(sender, commit.CommitId, requestId); task.ContinueWith(onComplete, commitContinuationContext, TaskContinuationOptions.ExecuteSynchronously); Log.Debug("[CommitHandler] Commit queued up..."); }
public void Handle(NetMQFrame[] sender, NetMQMessage message) { Logger.Debug("[Query_LoadEventsByStream] Received a request."); var requestId = message.Pop(); var context = message.Pop().ConvertToString(); var stream = message.Pop().ConvertToString(); var fromVersion = message.PopInt64(); var maxVersion = message.PopNullableInt64(); var events = _storage.LoadEventsForStream(context, stream, fromVersion, maxVersion); var msg = new NetMQMessage(); msg.Append(sender); msg.AppendEmptyFrame(); msg.Append(ResProtocol.ResClient01); msg.Append(requestId); msg.Append(ResCommands.QueryEventsByStreamResponse); var count = events.Length; msg.Append(count.ToNetMqFrame()); foreach (var e in events) { msg.Append(e.EventId.ToByteArray()); msg.Append(e.Stream); msg.Append(e.Context); msg.Append(e.Sequence.ToNetMqFrame()); msg.Append(e.Timestamp.ToNetMqFrame()); msg.Append(e.TypeKey); msg.Append(e.Headers.ToNetMqFrame()); msg.Append(e.Body); } var result = new QueryEventsForStreamLoaded(msg); while (!_buffer.Offer(result)) _spin.SpinOnce(); }
/// <summary> /// Remove the two frames from the given NetMQMessage, interpreting them thusly: /// 1. a byte with the HandshakeType, assumed to be ClientKeyExchange /// 2. a byte-array containing the EncryptedPreMasterSecret. /// </summary> /// <param name="message">a NetMQMessage - which must have 2 frames</param> public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 1) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } NetMQFrame preMasterSecretFrame = message.Pop(); EncryptedPreMasterSecret = preMasterSecretFrame.ToByteArray(); }
public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 1) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } NetMQFrame verifyDataFrame = message.Pop(); VerifyData = verifyDataFrame.ToByteArray(); }
public override void SetFromNetMQMessage(NetMQMessage message) { base.SetFromNetMQMessage(message); if (message.FrameCount != 1) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message"); } NetMQFrame certificateFrame = message.Pop(); byte[] certificteBytes = certificateFrame.ToByteArray(); Certificate = new X509Certificate2(); Certificate.Import(certificteBytes); }
protected override void OnIncomingMessage(byte[] identity, NetMQMessage message) { byte[] data = message.Pop().ToByteArray(); if (data.Length > 0 && (data[0] == 1 || data[0] == 0)) { if (data[0] == 0) { m_subscriptions.Remove(data, 1, identity); } else { m_subscriptions.Add(data, 1, identity); } } }
protected override void OnOutgoingMessage(NetMQMessage message) { m_subscriptions.Match(message[0].ToByteArray(false), message[0].MessageSize, s_markAsMatching, this); while(message.FrameCount >0) { var frame = message.Pop().ToByteArray(); bool more = message.FrameCount > 0; for (int i = 0; i < m_matching; i++) { WriteOutgoing(m_identities[i], frame, more); } } m_matching = 0; }
public static ZreMessage Decode(NetMQMessage message) { var msg = new ZreMessage(0); var frame = message.Pop(); if (frame == null) { return null; } msg._needle = frame.ToByteArray(); msg._needleReader = new BinaryReader(new MemoryStream(msg._needle)); msg._needleWriter = new BinaryWriter(new MemoryStream(msg._needle)); msg._ceiling = msg._needle.Length + frame.MessageSize; var signature = msg._needleReader.GetNumber2(); if (signature != (0xAAA0 | ZreConstants.ProtocolSignature)) { return null; } msg._id = (ZreMessageType)msg._needleReader.GetNumber1(); switch (msg._id) { case ZreMessageType.Hello: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); msg._endpoint = msg._needleReader.GetString(); var listSize = msg._needleReader.GetNumber4(); msg._groups = new HashSet<string>(); while (listSize-- > 0) { var groupName = msg._needleReader.GetLongString(); msg._groups.Add(groupName); } msg._status = msg._needleReader.GetNumber1(); msg._name = msg._needleReader.GetString(); var hashSize = msg._needleReader.GetNumber4(); msg._headers = new ConcurrentDictionary<string, string>(); while (hashSize-- > 0) { var key = msg._needleReader.GetString(); var value = msg._needleReader.GetLongString(); msg._headers.Add(key, value); } } break; case ZreMessageType.Whisper: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); // Get zero or more remaining frames, leaving current // frame untouched msg._content = new NetMQMessage(); while (!message.IsEmpty) { msg._content.Append(message.Pop()); } if (msg._content.IsEmpty) { msg._content.AppendEmptyFrame(); } } break; case ZreMessageType.Shout: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); msg._group = msg._needleReader.GetString(); // Get zero or more remaining frames, leaving current // frame untouched msg._content = new NetMQMessage(); while (!message.IsEmpty) { msg._content.Append(message.Pop()); } if (msg._content.IsEmpty) { msg._content.AppendEmptyFrame(); } } break; case ZreMessageType.Join: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); msg._group = msg._needleReader.GetString(); msg._status = msg._needleReader.GetNumber1(); } break; case ZreMessageType.Leave: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); msg._group = msg._needleReader.GetString(); msg._status = msg._needleReader.GetNumber1(); } break; case ZreMessageType.Ping: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); } break; case ZreMessageType.PingOk: { msg._version = msg._needleReader.GetNumber1(); if (msg._version != ZreConstants.ProtocolVersion) { return null; } msg._sequence = msg._needleReader.GetNumber2(); } break; } return msg; }
/// <summary> /// process REQUEST from a client. MMI requests are implemented here directly /// </summary> /// <param name="sender">client identity</param> /// <param name="message">the message received</param> public void ProcessClientMessage (NetMQFrame sender, NetMQMessage message) { // should be // REQUEST [service name][request] OR // DISCOVER ['mmi.service'][service to discover] if (message.FrameCount < 2) throw new ArgumentException ("The message is malformed!"); var serviceFrame = message.Pop (); // [request] OR [service to discover] var serviceName = serviceFrame.ConvertToString (); var request = Wrap (sender, message); // [CLIENT ADR][e][request] OR [service name] // if it is a "mmi.service" request, handle it locally // this request searches for a service and returns a code indicating the result of that search // 200 => service exists and worker are available // 400 => service exists but no workers are available // 501 => service does not exist if (serviceName == "mmi.service") { var returnCode = "501"; var name = request.Last.ConvertToString (); if (m_services.Exists (s => s.Name == name)) { var svc = m_services.Find (s => s.Name == name); returnCode = svc.DoWorkersExist () ? "200" : "400"; } // set the return code to be the last frame in the message var rc = new NetMQFrame (returnCode); // [return code] request.RemoveFrame (message.Last); // [CLIENT ADR][e] -> [service name] request.Append (serviceName); // [CLIENT ADR][e] <- ['mmi.service'] request.Append (rc); // [CLIENT ADR][e]['mmi.service'] <- [return code] // remove client return envelope and insert // protocol header and service name, // then rewrap envelope var client = UnWrap (request); // [return code] request.Push (MDPClientHeader); // [protocol header][return code] var reply = Wrap (client, request); // [CLIENT ADR][e][protocol header][return code] // send to back to CLIENT(!) Socket.SendMessage (reply); Log (string.Format ("[BROKER] MMI request processed. Answered {0}", reply)); } else { // get the requested service object var service = ServiceRequired (serviceName); // a standard REQUEST received Log (string.Format ("[BROKER] Dispatching request -> {0}", request)); // send to a worker offering the requested service // will add command, header and worker adr envelope ServiceDispatch (service, request); // [CLIENT ADR][e][request] } }
/// <summary> /// Strip the message from the first frame and if empty the following frame as well /// </summary> /// <returns>the first frame of the message</returns> private NetMQFrame Unwrap(NetMQMessage msg) { var result = msg.Pop(); if (msg.First.IsEmpty) msg.Pop(); return result; }
public static ZreEvent Create(NetMQMessage message) { if (message == null || message.IsEmpty || message.FrameCount < 3) { return null; } var self = new ZreEvent(); var type = message.Pop().ConvertToString(); self.Sender = message.Pop().ConvertToString(); self.Name = message.Pop().ConvertToString(); if (type == Enter) { self.Type = ZreEventType.Enter; var headersFrame = message.Pop(); if (headersFrame != null) { var headers = headersFrame.ToByteArray().UnpackHeaders(); self.Headers = headers; } self.Address = message.Pop().ConvertToString(); } else if (type == Exit) { self.Type = ZreEventType.Exit; } else if (type == Join) { self.Type = ZreEventType.Join; self.Group = message.Pop().ConvertToString(); } else if (type == Leave) { self.Type = ZreEventType.Leave; self.Group = message.Pop().ConvertToString(); } else if (type == Whisper) { self.Type = ZreEventType.Whisper; self.Message = message; } else if (type == Shout) { self.Type = ZreEventType.Shout; self.Group = message.Pop().ConvertToString(); self.Message = message; } else if (type == Stop) { self.Type = ZreEventType.Stop; } else if (type == Evasive) { self.Type = ZreEventType.Evasive; } return self; }
public NetMQMessage DecryptMessage(ContentType contentType, NetMQMessage cipherMessage) { if (SecurityParameters.BulkCipherAlgorithm == BulkCipherAlgorithm.Null && SecurityParameters.MACAlgorithm == MACAlgorithm.Null) { return cipherMessage; } if (cipherMessage.FrameCount < 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames, iv and sequence number"); } NetMQFrame ivFrame = cipherMessage.Pop(); m_decryptionBulkAlgorithm.IV = ivFrame.ToByteArray(); using (var decryptor = m_decryptionBulkAlgorithm.CreateDecryptor()) { NetMQMessage plainMessage = new NetMQMessage(); NetMQFrame seqNumFrame = cipherMessage.Pop(); byte[] frameBytes; byte[] seqNumMAC; byte[] padding; DecryptBytes(decryptor, seqNumFrame.ToByteArray(), out frameBytes, out seqNumMAC, out padding); ulong seqNum = BitConverter.ToUInt64(frameBytes, 0); int frameCount = BitConverter.ToInt32(frameBytes, 8); int frameIndex = 0; ValidateBytes(contentType, seqNum, frameIndex, frameBytes, seqNumMAC, padding); if (CheckReplayAttack(seqNum)) { throw new NetMQSecurityException(NetMQSecurityErrorCode.ReplayAttack, "Message already handled or very old message, might be under replay attack"); } if (frameCount != cipherMessage.FrameCount) { throw new NetMQSecurityException(NetMQSecurityErrorCode.EncryptedFramesMissing, "Frames was removed from the encrypted message"); } frameIndex++; foreach (NetMQFrame cipherFrame in cipherMessage) { byte[] data; byte[] mac; DecryptBytes(decryptor, cipherFrame.ToByteArray(), out data, out mac, out padding); ValidateBytes(contentType, seqNum, frameIndex, data, mac, padding); frameIndex++; plainMessage.Append(data); } return plainMessage; } }
/// <summary> /// verifies if the message replied obeys the MDP 0.2 protocol /// </summary> /// <remarks> /// socket strips [client adr][e] from message /// message -> /// [empty frame][protocol header][service name][reply] /// [empty frame][protocol header][service name][result code of service lookup] /// </remarks> private void ExtractFrames(NetMQMessage reply) { if (reply.FrameCount < 4) throw new ApplicationException("[CLIENT ERROR] received a malformed reply"); var emptyFrame = reply.Pop(); if (emptyFrame != NetMQFrame.Empty) { throw new ApplicationException($"[CLIENT ERROR] received a malformed reply expected empty frame instead of: { emptyFrame } "); } var header = reply.Pop(); // [MDPHeader] <- [service name][reply] OR ['mmi.service'][return code] if (header.ConvertToString() != m_mdpClient) throw new ApplicationException($"[CLIENT INFO] MDP Version mismatch: {header}"); var service = reply.Pop(); // [service name or 'mmi.service'] <- [reply] OR [return code] if (service.ConvertToString() != m_serviceName) throw new ApplicationException($"[CLIENT INFO] answered by wrong service: {service.ConvertToString()}"); }
/// <summary> /// Strip the first frame of a message and the following if it is empty /// </summary> /// <returns>the first frame and changes the message</returns> private static NetMQFrame Unwrap(NetMQMessage msg) { var id = msg.Pop(); // forget the empty frame if (msg.First.IsEmpty) msg.Pop(); return id; }
/// <summary> /// Check the message envelope for errors /// and get the MDP Command embedded. /// The message will be altered! /// </summary> /// <param name="request">NetMQMessage received</param> /// <returns>the received MDP Command</returns> private MDPCommand GetMDPCommand(NetMQMessage request) { // don't try to handle errors if (request.FrameCount < 3) throw new ApplicationException("Malformed request received!"); var empty = request.Pop(); if (!empty.IsEmpty) throw new ApplicationException("First frame must be an empty frame!"); var header = request.Pop(); if (header.ConvertToString() != m_mdpWorker) throw new ApplicationException("Invalid protocol header received!"); var cmd = request.Pop(); if (cmd.BufferSize > 1) throw new ApplicationException("MDP Command must be one byte not multiple!"); var command = (MDPCommand)cmd.Buffer[0]; Log(string.Format("[WORKER] received {0}/{1}", request, command)); return command; }
/// <summary> /// get the identity of the sending socket /// we hereby assume that the message has the following /// sequence of frames and strips that off the message /// /// [identity][empty][data] /// /// whereby [data] cold be a wrapped message itself! /// </summary> /// <param name="msg"></param> /// <returns></returns> private static byte[] Unwrap(NetMQMessage msg) { var idFrame = msg.Pop(); // throw away the empty frame msg.Pop(); return idFrame.Buffer; }
/// <summary> /// Process handshake and change cipher suite messages. This method should be called for every incoming message until the method returns true. /// You cannot encrypt or decrypt messages until the method return true. /// Each call to the method may include outgoing messages that need to be sent to the other peer. /// </summary> /// <param name="incomingMessage">the incoming message from the other peer</param> /// <param name="outgoingMesssages">the list of outgoing messages that need to be sent to the other peer</param> /// <returns>true when the method completes the handshake stage and the SecureChannel is ready to encrypt and decrypt messages</returns> /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidContentType: Unknown content type.</exception> /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for protocol version frame.</exception> /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for message size.</exception> /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidProtocolVersion: Wrong protocol version.</exception> /// <remarks> /// Note: Within this library, this method is ONLY called from within the unit-tests. /// </remarks> public bool ProcessMessage(NetMQMessage incomingMessage, IList<NetMQMessage> outgoingMesssages) { ContentType contentType = ContentType.Handshake; if (incomingMessage != null) { // Verify that the first two frames are the protocol-version and the content-type, NetMQFrame protocolVersionFrame = incomingMessage.Pop(); byte[] protocolVersionBytes = protocolVersionFrame.ToByteArray(); if (protocolVersionBytes.Length != 2) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame"); } if (!protocolVersionBytes.SequenceEqual(m_protocolVersion)) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version"); } NetMQFrame contentTypeFrame = incomingMessage.Pop(); if (contentTypeFrame.MessageSize != 1) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for message size"); } // Verify that the content-type is either handshake, or change-cipher-suit.. contentType = (ContentType)contentTypeFrame.Buffer[0]; if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake) { throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unknown content type"); } if (ChangeSuiteChangeArrived) { incomingMessage = m_recordLayer.DecryptMessage(contentType, incomingMessage); } } bool result = false; if (contentType == ContentType.Handshake) { result = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag); // Move the messages from the saved list over to the outgoing Messages collection.. foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages) { outgoingMesssages.Add(outgoingMesssage); } m_outgoingMessageBag.Clear(); } else { ChangeSuiteChangeArrived = true; } return (SecureChannelReady = result && ChangeSuiteChangeArrived); }
/// <summary> /// Utility to read a Guid from a message. /// We transmit 16 bytes that define the Uuid. /// </summary> /// <param name="message"></param> /// <returns></returns> private static Guid PopGuid(NetMQMessage message) { var bytes = message.Pop().ToByteArray(); Debug.Assert(bytes.Length == 16); var uuid = new Guid(bytes); return uuid; }
/// <summary> /// process a READY, REPLY, HEARTBEAT, DISCONNECT message sent to the broker by a worker /// </summary> /// <param name="sender">the sender identity frame</param> /// <param name="message">the message sent</param> public void ProcessWorkerMessage (NetMQFrame sender, NetMQMessage message) { // should be // READY [mdp command][service name] // REPLY [mdp command][client adr][e][reply] // HEARTBEAT [mdp command] if (message.FrameCount < 1) throw new ApplicationException ("Message with too few frames received."); var mdpCommand = message.Pop (); // get the mdp command frame it should have only one byte payload if (mdpCommand.BufferSize > 1) throw new ApplicationException ("The MDPCommand frame had more than one byte!"); var cmd = (MDPCommand) mdpCommand.Buffer[0]; // [service name] or [client adr][e][reply] var workerId = sender.ConvertToString (); // get the id of the worker sending the message var workerIsKnown = m_knownWorkers.Any (w => w.Id == workerId); switch (cmd) { case MDPCommand.Ready: if (workerIsKnown) { // then it is not the first command in session -> WRONG // if the worker is know to a service, remove it from that // service and a potential waiting list therein RemoveWorker (m_knownWorkers.Find (w => w.Id == workerId)); Log (string.Format ("[BROKER] READY out of sync. Removed worker {0}.", workerId)); } else { // now a new - not know - worker sent his READY initiation message // attach worker to service and mark as idle - worker has send READY as first message var serviceName = message.Pop ().ConvertToString (); var service = ServiceRequired (serviceName); // create a new worker and set the service it belongs to var worker = new Worker (workerId, sender, service); // now add the worker AddWorker (worker, service); Log (string.Format ("[BROKER] READY processed. Worker {0} added to service {1}", workerId, serviceName)); } break; case MDPCommand.Reply: if (workerIsKnown) { var worker = m_knownWorkers.Find (w => w.Id == workerId); // remove the client return envelope and insert the protocol header // and service name then rewrap the envelope var client = UnWrap (message); // [reply] message.Push (worker.Service.Name); // [service name][reply] message.Push (MDPClientHeader); // [protocol header][service name][reply] var reply = Wrap (client, message); // [client adr][e][protocol header][service name][reply] Socket.SendMessage (reply); Log (string.Format ("[BROKER] REPLY from {0} received and send to {1} -> {2}", workerId, client.ConvertToString (), message)); // relist worker for further requests AddWorker (worker, worker.Service); } break; case MDPCommand.Heartbeat: if (workerIsKnown) { var worker = m_knownWorkers.Find (w => w.Id == workerId); worker.Expiry = DateTime.UtcNow + m_heartbeatExpiry; Log (string.Format ("[BROKER] HEARTBEAT from {0} received.", workerId)); } break; default: Log ("[BROKER] ERROR: Invalid MDPCommand received or message received!"); break; } }
/// <summary> /// Utility to read a Guid from a message. /// We transmit 16 bytes that define the Uuid. /// </summary> /// <param name="message"></param> /// <returns></returns> private static Guid PopGuid(NetMQMessage message) { var bytes = message.Pop().ToByteArray(); if (bytes.Length != 16) { throw new Exception("Unexpected guid length"); } var uuid = new Guid(bytes); return uuid; }