public static TcpMessage FromArraySegment(ArraySegment <byte> data) { var d = data.Array; if (data.Count < sizeof(int)) { throw new ArgumentException(string.Format("ArraySegment too short, length: {0}", data.Count), "data"); } var msgId = 0; for (var i = 0; i < 4; i++) { msgId |= (d[i] << (i * 8)); // little-endian order } //TODO: CLC Replace this with more robust lookup, Different version of system can have different ids for messages and this will not survive persistance var msgType = MessageHierarchy.GetMsgType(msgId); var messageBuffer = new byte[d.Length - sizeof(int)]; Buffer.BlockCopy(data.Array, data.Offset + sizeof(int), messageBuffer, 0, messageBuffer.Length); var ms = new MemoryStream(messageBuffer); Message msg; using (var reader = new BsonReader(ms)) { var serializer = new JsonSerializer(); msg = (Message)serializer.Deserialize(reader, msgType); } return(new TcpMessage(msg)); }
// Every wrapped message that came out of TCP/IP, TcpInboundMessageHandler published on the bus. // I handle EVERYTHING that comes from the bus, so I'm going to get that same message back // (instantaneously). Thus TcpInboundMessageHandler calls the IgnoreThisMessage() function, // which puts the message on the _messagesThatCameFromTcp list. TcpInboundMessageHandler then // publishes the message on the CommandBus, which immediately hands it back to me. The Handle() // method (below) then keeps me from sending it BACK out on TCP, and thus we avoid the feedback loop. public void IgnoreThisMessage(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); if (message.MsgId == Guid.Empty) { Log.Error("Message " + message.MsgId + " (Type " + type.Name + ") - INTERNAL ERROR: there should NEVER be a message with that MsgId value"); } if (_messagesThatCameFromTcp.TryAdd(message.MsgId, message)) { Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") came from TCP, now added to MessagesThatCameFromTcp hash. Hash now contains " + _messagesThatCameFromTcp.Count + " entries."); } }
public void Handle(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); Message removedMessage; if (_messagesThatCameFromTcp.TryRemove(message.MsgId, out removedMessage)) { Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") came from TCP originally, NOT sent back on TCP. MessagesThatCameFromTcp hash now contains " + _messagesThatCameFromTcp.Count + " entries."); return; } Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") to be sent over TCP."); _outboundMessageQueuedHandler.Publish(message); }
public void Publish(Message message) { if (message == null) { Log.Error("Message was null, publishing aborted"); return; } var type1 = MessageHierarchy.GetMsgType(message.MsgTypeId); var handlers = _handlers[message.MsgTypeId]; for (int i = 0, n = handlers.Count; i < n; ++i) { var handler = handlers[i]; if (_watchSlowMsg) { var before = DateTime.UtcNow; handler.TryHandle(message); var elapsed = DateTime.UtcNow - before; if (elapsed <= _slowMsgThreshold) { continue; } Log.Trace("SLOW BUS MSG [{0}]: {1} - {2}ms. Handler: {3}.", Name, type1.Name, (int)elapsed.TotalMilliseconds, handler.HandlerName); if (elapsed > QueuedHandler.VerySlowMsgThreshold)// && !(message is SystemMessage.SystemInit)) { Log.Error("---!!! VERY SLOW BUS MSG [{0}]: {1} - {2}ms. Handler: {3}.", Name, type1.Name, (int)elapsed.TotalMilliseconds, handler.HandlerName); } } else { handler.TryHandle(message); } } }
protected void TcpMessageArrived(ArraySegment <byte> obj) { TcpMessage tcpMessage; try { tcpMessage = TcpMessage.FromArraySegment(obj); } catch (Exception ex) { Log.ErrorException(ex, "TcpMessage.FromArraySegment() threw an exception:"); throw; } Type type = MessageHierarchy.GetMsgType(tcpMessage.WrappedMessage.MsgTypeId); Log.Trace("Message " + tcpMessage.WrappedMessage.MsgId + " (Type " + type.Name + ") received from TCP."); if (_inboundSpamMessageTypes.Contains(type)) { if (_inboundSpamMessageQueuedHandler == null) { Log.Error("TCP message (a Message) has arrived, but _inboundSpamMessageQueuedHandler is null."); return; } _inboundSpamMessageQueuedHandler.Publish(tcpMessage.WrappedMessage); } else { if (_inboundMessageQueuedHandler == null) { Log.Error("TCP message (a Message) has arrived, but _inboundMessageQueuedHandler is null."); return; } _inboundMessageQueuedHandler.Publish(tcpMessage.WrappedMessage); } }
public void Handle(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") to be sent over TCP."); if (TcpConnection == null) { Log.Debug("TCP connection not yet established - Message " + message.MsgId + " (Type " + type.Name + ") will be discarded."); return; } try { var framed = Framer.FrameData((new TcpMessage(message).AsArraySegment())); TcpConnection.EnqueueSend(framed); } catch (Exception ex) { Log.ErrorException(ex, "Exception caught while handling Message " + message.MsgId + " (Type " + type.Name + ")"); } }
public void Handle(Message message) { Type type1 = MessageHierarchy.GetMsgType(message.MsgTypeId); dynamic msg = message; var type2 = msg.GetType(); if (!type1.Equals(type2)) { var error = $"Message object-type mismatch. MsgTypeId={message.MsgTypeId}, which MessageHierarchy claims is a {type1.FullName}. However, .Net Reflection says that the command is a {type2.FullName}"; Log.Error(error); throw new Exception(error); } var before = DateTime.UtcNow; MessageReceived(msg, type1, "TcpBusSide"); _tcpOutboundMessageHandler.IgnoreThisMessage(message); Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); _mainBus.Publish(message); PostHandleMessage(msg, type1, (DateTime.UtcNow - before)); }