Task <string> IMqttStorageProvider.StoreMessage(InFlightMessage message) { Guid messageId = Guid.NewGuid(); inFlight.Add(messageId, new SimpleInFlightMessage(message.Topic, message.Payload)); return(Util.RunSynchronously <string>(() => messageId.ToString())); }
private List <InFlightMessage> ChooseMsg() { lock (_inFlight) { _inFlight.RemoveAll(m => IdIsLessThanEqualOther(m.Message.PacketId, _lastReceivedAck)); // If any were resent, then dont send anything new if (_inFlight.Count > 0) { DateTime now = DateTime.Now; if (_inFlight.Any(m => GetTimeBetween(m.LastSent, now) > InFlightTimeout)) { List <InFlightMessage> toResend = _inFlight.ToList(); Log.WarnFormat("{0} - Resending {1} packets from #{2}", Endpoint, toResend.Count, toResend[0].Message.PacketId); return(toResend); } } if (_inFlight.Count >= MaxInFlight) { return(null); } lock (_messageQueue) { if (_messageQueue.Any()) { // create new message, send it and track it var msg = new InFlightMessage(_messageQueue.Dequeue().WithPacketId(NextPacketId), 0); // TODO - should this be able to perform an ack? _inFlight.Add(msg); return(new List <InFlightMessage> { msg }); } } OutboundMessage obMsg = CompileNextMessage(); if (obMsg == null) { return(null); } uint ackId = 0; lock (_lastSentAckLock) { bool shouldSend = _readyToAck > _lastSentAck; if (shouldSend) { ackId = _readyToAck; } } var newMsg = new InFlightMessage(obMsg.WithPacketId(NextPacketId), ackId); _inFlight.Add(newMsg); return(new List <InFlightMessage> { newMsg }); } }
private void SendMessage(Socket socket, InFlightMessage msg) { byte[] body = CompileMessage(msg); msg.LastSent = DateTime.Now; try { socket.SendTo(body, SocketFlags.None, Endpoint); } catch (ObjectDisposedException) { Log.ErrorFormat("{0} - Discarding message due to socket being disposed", Endpoint); // Mark as timed out. This will cause it to be cleaned up shortly _lastReceivedTime = DateTime.MinValue; OnDisconnect?.Invoke(this); } }
private byte[] CompileMessage(InFlightMessage msg) { byte opcode = CompileOpcode(msg.Message.Type, msg.LastSent != DateTime.MinValue); if (msg.AckId.HasValue) { opcode |= (byte)ReceivedPacket.CommandCodeFlags.AckReply; } byte len1 = (byte)((ReceivedPacket.HeaderLength + msg.Message.Payload.Length) / 256 | opcode << 3); // opcode 0x08 + length byte len2 = (byte)((ReceivedPacket.HeaderLength + msg.Message.Payload.Length) % 256); byte[] buffer = { len1, len2, // Opcode & Length (byte)(SessionId >> 8), (byte)SessionId, // session id 0x00, 0x00, // ACKed Pkt Id 0x00, 0x00, // Unknown 0x00, 0x00, // unknown2 (byte)(msg.Message.PacketId / 256), (byte)(msg.Message.PacketId % 256), // pkt id }; if (msg.AckId.HasValue || msg.Message.Type == OutboundMessage.OutboundMessageType.Ack) { var ackId = msg.AckId.GetValueOrDefault(0); // set ack id buffer[4] = (byte)(ackId / 256); buffer[5] = (byte)(ackId % 256); // clear pkt id if (msg.Message.Type == OutboundMessage.OutboundMessageType.Ack) { buffer[10] = buffer[11] = 0x00; } } // If no payload, dont append it if (msg.Message.Payload.Length == 0) { return(buffer); } return(buffer.Concat(msg.Message.Payload).ToArray()); }