示例#1
0
        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()));
        }
示例#2
0
        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);
            }
        }
示例#4
0
        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());
        }