/// <summary> /// Writes a message to a stream /// </summary> public async Task Write(Stream stream, TmqMessage message) { WriteType(stream, DataType.Insert); await WriteId(stream, message.MessageId); message.Content.Position = 0; await using MemoryStream ms = new MemoryStream(); await _writer.Write(message, ms); ms.Position = 0; await WriteContent(Convert.ToInt32(ms.Length), ms, stream); }
/// <summary> /// When a message received to Tmq Client, this method will be called /// </summary> private void ClientOnMessageReceived(ClientSocketBase <TmqMessage> client, TmqMessage message) { //only channel messages accepted if (message.Type != MessageType.Channel || string.IsNullOrEmpty(message.Target)) { return; } //find all subscriber actions List <QueueSubscription> subs; lock (_subscriptions) { subs = _subscriptions.Where(x => x.QueueId == message.ContentType && x.Channel.Equals(message.Target, StringComparison.InvariantCultureIgnoreCase)) .ToList(); } if (subs.Count == 0) { return; } //convert model, only one time to first susbcriber's type Type type = subs[0].MessageType; object model = _func(message, type); //call all subscriber methods if they have same type foreach (QueueSubscription sub in subs) { if (sub.MessageType == type) { try { if (sub.TmqMessageParameter) { sub.Action.DynamicInvoke(model, message); } else { sub.Action.DynamicInvoke(model); } } catch (Exception ex) { OnException?.Invoke(message, ex); } } } }
/// <summary> /// Fills binary data to the queue /// </summary> public PushResult FillData(IEnumerable <byte[]> items, bool createAsSaved, bool highPriority) { if (_queue.Status == QueueStatus.Stopped) { return(PushResult.StatusNotSupported); } int max = _queue.HighPriorityLinkedList.Count + _queue.RegularLinkedList.Count + items.Count(); if (_queue.Options.MessageLimit > 0 && max > _queue.Options.MessageLimit) { return(PushResult.LimitExceeded); } foreach (byte[] item in items) { TmqMessage message = new TmqMessage(MessageType.Channel, _queue.Channel.Name); message.FirstAcquirer = true; message.HighPriority = highPriority; message.AcknowledgeRequired = _queue.Options.RequestAcknowledge; message.ContentType = _queue.Id; if (_queue.Options.UseMessageId) { message.SetMessageId(_queue.Channel.Server.MessageIdGenerator.Create()); } message.Content = new MemoryStream(item); message.Content.Position = 0; message.CalculateLengths(); QueueMessage qm = new QueueMessage(message, createAsSaved); if (highPriority) { lock (_queue.HighPriorityLinkedList) _queue.HighPriorityLinkedList.AddLast(qm); } else { lock (_queue.RegularLinkedList) _queue.RegularLinkedList.AddLast(qm); } } _queue.Info.UpdateHighPriorityMessageCount(_queue.HighPriorityLinkedList.Count); _queue.Info.UpdateRegularMessageCount(_queue.RegularLinkedList.Count); return(PushResult.Success); }
/// <summary> /// Starts to follow message acknowledge /// </summary> public async Task <bool> FollowAcknowledge(TmqMessage message) { if (!message.AcknowledgeRequired || string.IsNullOrEmpty(message.MessageId)) { return(false); } DateTime expiration = DateTime.UtcNow + _client.AcknowledgeTimeout; AcknowledgeMessageDescriptor descriptor = new AcknowledgeMessageDescriptor(message, expiration); lock (_descriptors) _descriptors.Add(descriptor); return(await descriptor.Source.Task); }
public async Task Handle(MqClient client, TmqMessage message) { try { await HandleUnsafe(client, message); } catch (OperationCanceledException) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.LimitExceeded)); } catch (DuplicateNameException) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Duplicate)); } }
/// <summary> /// Creates new response message, with no content, of the message. /// </summary> public static TmqMessage ResponseStatus(TmqMessage request, ushort status) { TmqMessage response = new TmqMessage(); response.Type = MessageType.Response; response.SetMessageId(request.MessageId); response.ContentType = status; response.FirstAcquirer = true; response.SetTarget(request.Type == MessageType.Channel ? request.Target : request.Source); return(response); }
private void MessageReceived(ClientSocketBase <TmqMessage> client, TmqMessage message) { switch (message.Type) { case MessageType.Channel: if (message.ContentType == ModelTypes.ProducerEvent) { ProducerEvent e = message.GetJsonContent <ProducerEvent>().Result; Console.WriteLine(message.Target == "AckChannel" ? $"> AckChannel received: #{e.No}" : $"> BasicChannel received: #{e.No}"); } break; } }
/// <summary> /// Removes a channel and all queues in it /// </summary> public async Task <TmqResponseCode> RemoveChannel(string channel, bool verifyResponse) { TmqMessage message = new TmqMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.RemoveChannel; message.SetTarget(channel); message.ResponseRequired = verifyResponse; if (verifyResponse) { message.SetMessageId(UniqueIdGenerator.Create()); } return(await WaitResponse(message, verifyResponse)); }
public async Task UseUniqueMessageId(bool enabled) { int port = enabled ? 42701 : 42702; TestMqServer server = new TestMqServer(); server.Initialize(port); server.Server.Options.UseMessageId = enabled; server.Server.FindChannel("ch-1").FindQueue(MessageA.ContentType).Options.UseMessageId = false; server.Start(); TmqClient client = new TmqClient(); client.UseUniqueMessageId = false; await client.ConnectAsync("tmq://localhost:" + port); Assert.True(client.IsConnected); TmqResponseCode joined = await client.Join("ch-1", true); Assert.Equal(TmqResponseCode.Ok, joined); await Task.Delay(250); TmqMessage received = null; client.MessageReceived += (c, m) => received = m; MessageA a = new MessageA("A"); string serialized = Newtonsoft.Json.JsonConvert.SerializeObject(a); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized)); bool sent = await client.Push("ch-1", MessageA.ContentType, ms, false); Assert.True(sent); await Task.Delay(1000); Assert.NotNull(received); if (enabled) { Assert.NotNull(received.MessageId); } else { Assert.Null(received.MessageId); } }
/// <summary> /// Fills JSON object data to the queue. /// Creates new TmqMessage and before writing content and adding into queue calls the action. /// </summary> public async Task <PushResult> FillJson <T>(IEnumerable <T> items, bool createAsSaved, Action <TmqMessage, T> action) where T : class { if (_queue.Status == QueueStatus.Stopped) { return(PushResult.StatusNotSupported); } int max = _queue.HighPriorityLinkedList.Count + _queue.RegularLinkedList.Count + items.Count(); if (_queue.Options.MessageLimit > 0 && max > _queue.Options.MessageLimit) { return(PushResult.LimitExceeded); } foreach (T item in items) { TmqMessage message = new TmqMessage(MessageType.Channel, _queue.Channel.Name); message.FirstAcquirer = true; message.AcknowledgeRequired = _queue.Options.RequestAcknowledge; message.ContentType = _queue.Id; if (_queue.Options.UseMessageId) { message.SetMessageId(_queue.Channel.Server.MessageIdGenerator.Create()); } action(message, item); await message.SetJsonContent(item); QueueMessage qm = new QueueMessage(message, createAsSaved); if (message.HighPriority) { lock (_queue.HighPriorityLinkedList) _queue.HighPriorityLinkedList.AddLast(qm); } else { lock (_queue.RegularLinkedList) _queue.RegularLinkedList.AddLast(qm); } } _queue.Info.UpdateHighPriorityMessageCount(_queue.HighPriorityLinkedList.Count); _queue.Info.UpdateRegularMessageCount(_queue.RegularLinkedList.Count); return(PushResult.Success); }
/// <summary> /// Updates queue options /// </summary> public async Task <TmqResponseCode> SetQueueOptions(string channel, ushort queueId, Action <QueueOptions> optionsAction) { TmqMessage message = new TmqMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.UpdateQueue; message.SetTarget(channel); message.ResponseRequired = true; message.SetMessageId(UniqueIdGenerator.Create()); QueueOptions options = new QueueOptions(); optionsAction(options); message.Content = new MemoryStream(Encoding.UTF8.GetBytes(options.Serialize(queueId))); return(await WaitResponse(message, true)); }
/// <summary> /// Removes a queue in a channel in server /// </summary> public async Task <TmqResponseCode> RemoveQueue(string channel, ushort queueId, bool verifyResponse) { TmqMessage message = new TmqMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.RemoveQueue; message.SetTarget(channel); message.ResponseRequired = verifyResponse; message.Content = new MemoryStream(BitConverter.GetBytes(queueId)); if (verifyResponse) { message.SetMessageId(UniqueIdGenerator.Create()); } return(await WaitResponse(message, verifyResponse)); }
/// <summary> /// Gets all connected clients /// </summary> public async Task GetClients(MqClient client, TmqMessage message) { if (_server.AdminAuthorization == null) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } bool grant = await _server.AdminAuthorization.CanReceiveClients(client); if (!grant) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } List <ClientInformation> list = new List <ClientInformation>(); foreach (MqClient mc in _server.Clients) { list.Add(new ClientInformation { Id = mc.UniqueId, Name = mc.Name, Type = mc.Type, IsAuthenticated = mc.IsAuthenticated, Online = mc.ConnectedDate.LifetimeMilliseconds(), }); } TmqMessage response = message.CreateResponse(); message.ContentType = KnownContentTypes.ClientList; await response.SetJsonContent(list); await client.SendAsync(response); }
public void DisconnectDueToPingTimeout() { TestMqServer server = new TestMqServer(); server.Initialize(42105); server.Start(); TcpClient client = new TcpClient(); client.Connect("127.0.0.1", 42105); NetworkStream stream = client.GetStream(); stream.Write(PredefinedMessages.PROTOCOL_BYTES); TmqMessage msg = new TmqMessage(); msg.Type = MessageType.Server; msg.ContentType = KnownContentTypes.Hello; msg.SetStringContent("GET /\r\nName: Test-42105"); msg.CalculateLengths(); TmqWriter writer = new TmqWriter(); writer.Write(msg, stream).Wait(); Thread.Sleep(1000); Assert.Equal(1, server.ClientConnected); ThreadPool.UnsafeQueueUserWorkItem(async s => { byte[] buffer = new byte[128]; while (client.Connected) { int r = await s.ReadAsync(buffer); if (r == 0) { client.Dispose(); break; } } }, stream, false); Thread.Sleep(25000); Assert.False(client.Connected); Assert.Equal(1, server.ClientDisconnected); }
private void MessageReceived(ClientSocketBase <TmqMessage> client, TmqMessage message) { if (message.Type == MessageType.Client && message.ContentType == ModelTypes.ConsumerRequest) { ConsumerRequest request = message.GetJsonContent <ConsumerRequest>().Result; Console.WriteLine($"Consumer request received: {request.Guid}"); ProducerResponse model = new ProducerResponse(); model.RequestGuid = request.Guid; model.ResponseGuid = Guid.NewGuid().ToString(); TmqMessage response = message.CreateResponse(); response.ContentType = ModelTypes.ProducerResponse; response.SetJsonContent(model); TmqClient tmq = (TmqClient)client; tmq.Send(response); } }
public async Task Handle(MqClient client, TmqMessage message) { //priority has no role in ack message. //we are using priority for helping receiver type recognization for better performance if (message.HighPriority) { //target should be client MqClient target = _server.FindClient(message.Target); if (target != null) { await target.SendAsync(message); return; } } //find channel and queue Channel channel = _server.FindChannel(message.Target); if (channel == null) { //if high prio, dont try to find client again if (!message.HighPriority) { //target should be client MqClient target = _server.FindClient(message.Target); if (target != null) { await target.SendAsync(message); } } return; } ChannelQueue queue = channel.FindQueue(message.ContentType); if (queue == null) { return; } await queue.AcknowledgeDelivered(client, message); }
public async Task FromClientToClientManuel() { TestMqServer server = new TestMqServer(); server.Initialize(42302); server.Start(); server.Server.Server.Options.PingInterval = 300; server.Server.Server.Options.RequestTimeout = 300; await Task.Delay(250); TmqClient client1 = new TmqClient(); TmqClient client2 = new TmqClient(); client1.ClientId = "client-1"; client2.ClientId = "client-2"; client2.AutoAcknowledge = false; client2.MessageReceived += async(c, m) => { if (m.AcknowledgeRequired) { await client2.SendAsync(m.CreateAcknowledge()); } }; await client1.ConnectAsync("tmq://localhost:42302"); await client2.ConnectAsync("tmq://localhost:42302"); Assert.True(client1.IsConnected); Assert.True(client2.IsConnected); TmqMessage message = new TmqMessage(); message.HighPriority = true; message.Type = MessageType.Client; message.SetTarget(client2.ClientId); message.SetStringContent("Hello, World!"); bool acknowledge = await client1.SendWithAcknowledge(message); Assert.True(acknowledge); }
public async Task CatchResponseMessages(bool enabled) { int port = enabled ? 42711 : 42712; TestMqServer server = new TestMqServer(); server.Initialize(port); server.Start(); TmqClient client1 = new TmqClient(); TmqClient client2 = new TmqClient(); client1.ClientId = "client-1"; client2.ClientId = "client-2"; client1.CatchResponseMessages = enabled; await client1.ConnectAsync("tmq://localhost:" + port); await client2.ConnectAsync("tmq://localhost:" + port); Assert.True(client1.IsConnected); Assert.True(client2.IsConnected); bool responseCaught = false; client1.MessageReceived += (c, m) => responseCaught = true; client2.MessageReceived += async(c, m) => { TmqMessage rmsg = m.CreateResponse(); rmsg.SetStringContent("Response!"); await((TmqClient)c).SendAsync(rmsg); }; TmqMessage msg = new TmqMessage(MessageType.Client, "client-2"); msg.ResponseRequired = true; msg.SetStringContent("Hello, World!"); TmqMessage response = await client1.Request(msg); Assert.NotNull(response); Assert.Equal(msg.MessageId, response.MessageId); Assert.Equal(enabled, responseCaught); }
public async Task SendAndPull() { int port = 47411; TestMqServer server = new TestMqServer(); server.Initialize(port); server.Start(300, 300); TmqClient consumer = new TmqClient(); consumer.ClientId = "consumer"; await consumer.ConnectAsync("tmq://localhost:" + port); Assert.True(consumer.IsConnected); TmqResponseCode joined = await consumer.Join("ch-pull", true); Assert.Equal(TmqResponseCode.Ok, joined); TmqClient producer = new TmqClient(); await producer.ConnectAsync("tmq://localhost:" + port); Assert.True(producer.IsConnected); await producer.Push("ch-pull", MessageA.ContentType, "Hello, World!", false); await Task.Delay(700); Channel channel = server.Server.FindChannel("ch-pull"); ChannelQueue queue = channel.FindQueue(MessageA.ContentType); Assert.NotNull(channel); Assert.NotNull(queue); Assert.Single(queue.RegularMessages); TmqMessage pull1 = await consumer.Pull("ch-pull", MessageA.ContentType); Assert.NotNull(pull1); TmqMessage pull2 = await consumer.Pull("ch-pull", MessageA.ContentType); Assert.Null(pull2); }
/// <summary> /// This method process the ack message, when it is received /// </summary> public void ProcessAcknowledge(TmqMessage message) { if (message.Type != MessageType.Acknowledge || string.IsNullOrEmpty(message.MessageId)) { return; } MessageDescriptor descriptor; lock (_descriptors) descriptor = _descriptors.Find(x => x.Message.AcknowledgeRequired && x.Message.MessageId == message.MessageId); if (descriptor == null) { return; } descriptor.Completed = true; descriptor.Set(new object()); }
public async Task Handle(MqClient client, TmqMessage message) { //if server is not set or there is no connected server if (_server.NodeServer.Connectors.Length == 0) { return; } byte[] mdata = await _writer.Create(message); foreach (TmqStickyConnector connector in _server.NodeServer.Connectors) { bool grant = _server.NodeServer.Authenticator == null || await _server.NodeServer.Authenticator.CanReceive(connector.GetClient(), message); if (grant) { connector.Send(mdata); } } }
/// <summary> /// Handles pulling a message from a queue /// </summary> private async Task HandlePullRequest(MqClient client, TmqMessage message, Channel channel, ChannelQueue queue) { //only pull statused queues can handle this request if (queue.Status != QueueStatus.Pull) { if (!string.IsNullOrEmpty(message.MessageId)) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.BadRequest)); } return; } //client cannot pull message from the channel not in ChannelClient channelClient = channel.FindClient(client); if (channelClient == null) { if (!string.IsNullOrEmpty(message.MessageId)) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } //check authorization if (_server.Authorization != null) { bool grant = await _server.Authorization.CanPullFromQueue(channelClient, queue); if (!grant) { if (!string.IsNullOrEmpty(message.MessageId)) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } } await queue.State.Pull(channelClient, message); }
/// <summary> /// Inserts new message to database /// </summary> /// <returns></returns> public async Task <bool> Insert(TmqMessage message) { if (string.IsNullOrEmpty(message.MessageId)) { return(false); } await WaitForLock(); try { if (_messages.ContainsKey(message.MessageId)) { return(false); } _messages.Add(message.MessageId, message); Stream stream = File.GetStream(); await _serializer.Write(stream, message); if (Options.InstantFlush) { await stream.FlushAsync(); } else { File.FlushRequired = true; } return(true); } catch (Exception e) { TriggerError(ErrorHint.Insert, e); return(false); } finally { ReleaseLock(); } }
public async Task WithResponse() { TestMqServer server = new TestMqServer(); server.Initialize(42603); server.Start(); TmqClient client1 = new TmqClient(); TmqClient client2 = new TmqClient(); client1.ClientId = "client-1"; client2.ClientId = "client-2"; client2.AutoAcknowledge = true; await client1.ConnectAsync("tmq://localhost:42603"); await client2.ConnectAsync("tmq://localhost:42603"); Assert.True(client1.IsConnected); Assert.True(client2.IsConnected); client2.MessageReceived += async(c, m) => { if (m.Source == "client-1") { TmqMessage rmsg = m.CreateResponse(); rmsg.ContentType = 123; rmsg.SetStringContent("Hello, World Response!"); await((TmqClient)c).SendAsync(rmsg); } }; TmqMessage message = new TmqMessage(MessageType.Client, "client-2"); message.SetStringContent("Hello, World!"); TmqMessage response = await client1.Request(message); Assert.NotNull(response); Assert.Equal(123, response.ContentType); }
/// <summary> /// Leaves from the channel and sends response /// </summary> private async Task LeaveChannel(MqClient client, TmqMessage message) { Channel channel = _server.FindChannel(message.Target); if (channel == null) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound)); } return; } bool success = await channel.RemoveClient(client); if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, success ? KnownContentTypes.Ok : KnownContentTypes.NotFound)); } }
/// <summary> /// Applies decision. /// If save is chosen, saves the message. /// If acknowledge is chosen, sends an ack message to source. /// Returns true is allowed /// </summary> internal async Task <bool> ApplyDecision(Decision decision, QueueMessage message, TmqMessage customAck = null) { if (decision.SaveMessage) { await SaveMessage(message); } if (decision.SendAcknowledge == DeliveryAcknowledgeDecision.Always || decision.SendAcknowledge == DeliveryAcknowledgeDecision.IfSaved && message.IsSaved) { TmqMessage acknowledge = customAck ?? message.Message.CreateAcknowledge(); if (message.Source != null && message.Source.IsConnected) { bool sent = await message.Source.SendAsync(acknowledge); if (decision.AcknowledgeDelivery != null) { await decision.AcknowledgeDelivery(message, message.Source, sent); } } else if (decision.AcknowledgeDelivery != null) { await decision.AcknowledgeDelivery(message, message.Source, false); } } if (decision.KeepMessage) { AddMessage(message, false); } else if (!decision.Allow) { Info.AddMessageRemove(); _ = DeliveryHandler.MessageRemoved(this, message); } return(decision.Allow); }
public async Task FromClientToClientTimeout() { TestMqServer server = new TestMqServer(); server.Initialize(42393); server.Start(15, 15); server.Server.Server.Options.PingInterval = 300; server.Server.Server.Options.RequestTimeout = 300; await Task.Delay(250); TmqClient client1 = new TmqClient(); TmqClient client2 = new TmqClient(); client1.ClientId = "client-1"; client2.ClientId = "client-2"; client1.AcknowledgeTimeout = TimeSpan.FromSeconds(5); client2.AutoAcknowledge = false; await client1.ConnectAsync("tmq://localhost:42393"); await client2.ConnectAsync("tmq://localhost:42393"); Assert.True(client1.IsConnected); Assert.True(client2.IsConnected); TmqMessage message = new TmqMessage(); message.HighPriority = true; message.Type = MessageType.Client; message.SetTarget(client2.ClientId); message.SetStringContent("Hello, World!"); bool acknowledge = await client1.SendWithAcknowledge(message); Assert.False(acknowledge); }
public Task <PullResult> Pull(ChannelClient client, TmqMessage request) { return(Task.FromResult(PullResult.StatusNotSupported)); }
/// <summary> /// Gets connected instance list /// </summary> private async Task GetInstanceList(MqClient client, TmqMessage message) { if (_server.AdminAuthorization == null) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } bool grant = await _server.AdminAuthorization.CanManageInstances(client, message); if (!grant) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } List <InstanceInformation> list = new List <InstanceInformation>(); //slave instances List <MqClient> slaves = _server.NodeServer.Clients.GetAsClone(); foreach (MqClient slave in slaves) { list.Add(new InstanceInformation { IsSlave = true, Host = slave.RemoteHost, IsConnected = slave.IsConnected, Id = slave.UniqueId, Name = slave.Name, Lifetime = slave.ConnectedDate.LifetimeMilliseconds() }); } //master instances foreach (TmqStickyConnector connector in _server.NodeServer.Connectors) { NodeOptions options = connector.Tag as NodeOptions; TmqClient c = connector.GetClient(); list.Add(new InstanceInformation { IsSlave = false, Host = options?.Host, IsConnected = connector.IsConnected, Id = c.ClientId, Name = options?.Name, Lifetime = Convert.ToInt64(connector.Lifetime.TotalMilliseconds) }); } TmqMessage response = message.CreateResponse(); message.ContentType = KnownContentTypes.InstanceList; await response.SetJsonContent(list); await client.SendAsync(response); }
/// <summary> /// Finds the queue and sends the information /// </summary> private async Task GetQueueInformation(MqClient client, TmqMessage message) { if (_server.AdminAuthorization == null) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } Channel channel = _server.FindChannel(message.Target); if (channel == null) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound)); return; } bool grant = await _server.AdminAuthorization.CanReceiveChannelQueues(client, channel); if (!grant) { if (message.ResponseRequired) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized)); } return; } byte[] bytes = new byte[2]; await message.Content.ReadAsync(bytes); ushort id = BitConverter.ToUInt16(bytes); ChannelQueue queue = channel.FindQueue(id); if (queue == null) { await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound)); return; } QueueInformation information = new QueueInformation { Channel = channel.Name, Id = id, Status = queue.Status.ToString().ToLower(), InQueueHighPriorityMessages = queue.HighPriorityLinkedList.Count, InQueueRegularMessages = queue.RegularLinkedList.Count, OnlyFirstAcquirer = channel.Options.SendOnlyFirstAcquirer, RequestAcknowledge = channel.Options.RequestAcknowledge, AcknowledgeTimeout = Convert.ToInt32(channel.Options.AcknowledgeTimeout.TotalMilliseconds), MessageTimeout = Convert.ToInt32(channel.Options.MessageTimeout.TotalMilliseconds), WaitForAcknowledge = channel.Options.WaitForAcknowledge, HideClientNames = channel.Options.HideClientNames, ReceivedMessages = queue.Info.ReceivedMessages, SentMessages = queue.Info.SentMessages, Deliveries = queue.Info.Deliveries, Unacknowledges = queue.Info.Unacknowledges, Acknowledges = queue.Info.Acknowledges, TimeoutMessages = queue.Info.TimedOutMessages, SavedMessages = queue.Info.MessageSaved, RemovedMessages = queue.Info.MessageRemoved, Errors = queue.Info.ErrorCount, LastMessageReceived = queue.Info.GetLastMessageReceiveUnix(), LastMessageSent = queue.Info.GetLastMessageSendUnix(), MessageLimit = queue.Options.MessageLimit, MessageSizeLimit = queue.Options.MessageSizeLimit }; TmqMessage response = message.CreateResponse(); message.ContentType = KnownContentTypes.QueueInformation; await response.SetJsonContent(information); await client.SendAsync(response); }