public async Task Handle(MqClient client, TmqMessage message) { //to prevent receive same message from instanced server that already sent from this server if (client.IsInstanceServer) { return; } //if server is not set or there is no connected server if (_server.ServerAuthenticator == null || _server.InstanceConnectors.Length == 0) { return; } byte[] mdata = await _writer.Create(message); foreach (TmqStickyConnector connector in _server.InstanceConnectors) { bool grant = await _server.ServerAuthenticator.CanReceive(connector.GetClient(), message); if (grant) { connector.Send(mdata); } } }
/// <summary> /// /// </summary> public async Task <TmqServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data) { string clientId; bool found = data.Properties.TryGetValue(TmqHeaders.CLIENT_ID, out clientId); if (!found || string.IsNullOrEmpty(clientId)) { clientId = _server.Server.ClientIdGenerator.Create(); } //if another client with same unique id is online, do not accept new client MqClient foundClient = _server.Clients.Find(x => x.UniqueId == clientId); if (foundClient != null) { await connection.Socket.SendAsync(await _writer.Create(MessageBuilder.Busy())); return(null); } //creates new node client object MqClient client = new MqClient(_server.Server, connection); client.Data = data; client.UniqueId = clientId.Trim(); client.Token = data.Properties.GetStringValue(TmqHeaders.CLIENT_TOKEN); client.Name = data.Properties.GetStringValue(TmqHeaders.CLIENT_NAME); client.Type = data.Properties.GetStringValue(TmqHeaders.CLIENT_TYPE); if (_server.Authenticator != null) { bool accepted = await _server.Authenticator.Authenticate(_server, client); if (!accepted) { return(null); } } client.RemoteHost = client.Info.Client.Client.RemoteEndPoint.ToString().Split(':')[0]; _server.Clients.Add(client); await client.SendAsync(MessageBuilder.Accepted(client.UniqueId)); return(client); }
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> /// Called when a new client is connected via TMQ protocol /// </summary> public async Task <TmqServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data) { string clientId; bool found = data.Properties.TryGetValue(TmqHeaders.CLIENT_ID, out clientId); if (!found || string.IsNullOrEmpty(clientId)) { clientId = _server.ClientIdGenerator.Create(); } //if another client with same unique id is online, do not accept new client MqClient foundClient = _server.FindClient(clientId); if (foundClient != null) { await connection.Socket.SendAsync(await _writer.Create(MessageBuilder.Busy())); return(null); } //creates new mq client object MqClient client = new MqClient(_server, connection, _server.MessageIdGenerator, _server.Options.UseMessageId); client.Data = data; client.UniqueId = clientId.Trim(); client.Token = data.Properties.GetStringValue(TmqHeaders.CLIENT_TOKEN); client.Name = data.Properties.GetStringValue(TmqHeaders.CLIENT_NAME); client.Type = data.Properties.GetStringValue(TmqHeaders.CLIENT_TYPE); //connecting client is a MQ server string serverValue = data.Properties.GetStringValue(TmqHeaders.TWINO_MQ_SERVER); if (!string.IsNullOrEmpty(serverValue) && (serverValue.Equals("1") || serverValue.Equals("true", StringComparison.InvariantCultureIgnoreCase))) { if (_server.ServerAuthenticator == null) { return(null); } bool accepted = await _server.ServerAuthenticator.Authenticate(_server, client); if (!accepted) { return(null); } client.IsInstanceServer = true; _server.SlaveInstances.Add(new SlaveInstance { ConnectedDate = DateTime.UtcNow, Client = client, RemoteHost = client.Info.Client.Client.RemoteEndPoint.ToString().Split(':')[0] }); await client.SendAsync(MessageBuilder.Accepted(client.UniqueId)); } //connecting client is a producer/consumer client else { //authenticates client if (_server.Authenticator != null) { client.IsAuthenticated = await _server.Authenticator.Authenticate(_server, client); if (!client.IsAuthenticated) { await client.SendAsync(MessageBuilder.Unauthorized()); return(null); } } //client authenticated, add it into the connected clients list _server.AddClient(client); //send response message to the client, client should check unique id, //if client's unique id isn't permitted, server will create new id for client and send it as response await client.SendAsync(MessageBuilder.Accepted(client.UniqueId)); if (_server.ClientHandler != null) { await _server.ClientHandler.Connected(_server, client); } } return(client); }
private async Task <PushResult> ProcessMessage(QueueMessage message) { //if we need acknowledge from receiver, it has a deadline. DateTime?ackDeadline = null; if (_queue.Options.RequestAcknowledge) { ackDeadline = DateTime.UtcNow.Add(_queue.Options.AcknowledgeTimeout); } //if there are not receivers, complete send operation List <ChannelClient> clients = _queue.Channel.ClientsClone; if (clients.Count == 0) { _queue.AddMessage(message, false); return(PushResult.NoConsumers); } //if to process next message is requires previous message acknowledge, wait here if (_queue.Options.RequestAcknowledge && _queue.Options.WaitForAcknowledge) { await _queue.WaitForAcknowledge(message); } message.Decision = await _queue.DeliveryHandler.BeginSend(_queue, message); if (!await _queue.ApplyDecision(message.Decision, message)) { return(PushResult.Success); } //create prepared message data byte[] messageData = await _writer.Create(message.Message); Decision final = new Decision(false, false, false, DeliveryAcknowledgeDecision.None); bool messageIsSent = false; //to all receivers foreach (ChannelClient client in clients) { //to only online receivers if (!client.Client.IsConnected) { continue; } //somehow if code comes here (it should not cuz of last "break" in this foreach, break if (!message.Message.FirstAcquirer && _queue.Options.SendOnlyFirstAcquirer) { break; } //call before send and check decision Decision ccrd = await _queue.DeliveryHandler.CanConsumerReceive(_queue, message, client.Client); final = ChannelQueue.CreateFinalDecision(final, ccrd); if (!ccrd.Allow) { continue; } //create delivery object MessageDelivery delivery = new MessageDelivery(message, client, ackDeadline); delivery.FirstAcquirer = message.Message.FirstAcquirer; //send the message bool sent = client.Client.Send(messageData); if (sent) { messageIsSent = true; //adds the delivery to time keeper to check timing up _queue.TimeKeeper.AddAcknowledgeCheck(delivery); //set as sent, if message is sent to it's first acquirer, //set message first acquirer false and re-create byte array data of the message bool firstAcquirer = message.Message.FirstAcquirer; //mark message is sent delivery.MarkAsSent(); //do after send operations for per message _queue.Info.AddDelivery(); Decision d = await _queue.DeliveryHandler.ConsumerReceived(_queue, delivery, client.Client); final = ChannelQueue.CreateFinalDecision(final, d); //if we are sending to only first acquirer, break if (_queue.Options.SendOnlyFirstAcquirer && firstAcquirer) { break; } if (firstAcquirer && clients.Count > 1) { messageData = await _writer.Create(message.Message); } } else { Decision d = await _queue.DeliveryHandler.ConsumerReceiveFailed(_queue, delivery, client.Client); final = ChannelQueue.CreateFinalDecision(final, d); } } message.Decision = final; if (!await _queue.ApplyDecision(final, message)) { return(PushResult.Success); } //after all sending operations completed, calls implementation send completed method and complete the operation if (messageIsSent) { _queue.Info.AddMessageSend(); } message.Decision = await _queue.DeliveryHandler.EndSend(_queue, message); await _queue.ApplyDecision(message.Decision, message); if (message.Decision.Allow && !message.Decision.KeepMessage) { _queue.Info.AddMessageRemove(); _ = _queue.DeliveryHandler.MessageRemoved(_queue, message); } return(PushResult.Success); }
private async Task <PushResult> ProcessMessage(QueueMessage message, ChannelClient receiver) { //if we need acknowledge from receiver, it has a deadline. DateTime?deadline = null; if (_queue.Options.RequestAcknowledge) { deadline = DateTime.UtcNow.Add(_queue.Options.AcknowledgeTimeout); } //if to process next message is requires previous message acknowledge, wait here if (_queue.Options.RequestAcknowledge && _queue.Options.WaitForAcknowledge) { await _queue.WaitForAcknowledge(message); } message.Decision = await _queue.DeliveryHandler.BeginSend(_queue, message); if (!await _queue.ApplyDecision(message.Decision, message)) { return(PushResult.Success); } //create prepared message data byte[] messageData = await _writer.Create(message.Message); //call before send and check decision message.Decision = await _queue.DeliveryHandler.CanConsumerReceive(_queue, message, receiver.Client); if (!await _queue.ApplyDecision(message.Decision, message)) { return(PushResult.Success); } //create delivery object MessageDelivery delivery = new MessageDelivery(message, receiver, deadline); delivery.FirstAcquirer = message.Message.FirstAcquirer; //send the message bool sent = receiver.Client.Send(messageData); if (sent) { //adds the delivery to time keeper to check timing up _queue.TimeKeeper.AddAcknowledgeCheck(delivery); //mark message is sent delivery.MarkAsSent(); _queue.Info.AddMessageSend(); //do after send operations for per message _queue.Info.AddDelivery(); message.Decision = await _queue.DeliveryHandler.ConsumerReceived(_queue, delivery, receiver.Client); } else { message.Decision = await _queue.DeliveryHandler.ConsumerReceiveFailed(_queue, delivery, receiver.Client); } if (!await _queue.ApplyDecision(message.Decision, message)) { return(PushResult.Success); } message.Decision = await _queue.DeliveryHandler.EndSend(_queue, message); await _queue.ApplyDecision(message.Decision, message); if (message.Decision.Allow && !message.Decision.KeepMessage) { _queue.Info.AddMessageRemove(); _ = _queue.DeliveryHandler.MessageRemoved(_queue, message); } return(PushResult.Success); }
/// <summary> /// Called when a new client is connected via TMQ protocol /// </summary> public async Task <TmqServerSocket> Connected(ITwinoServer server, IConnectionInfo connection, ConnectionData data) { string clientId; bool found = data.Properties.TryGetValue(TmqHeaders.CLIENT_ID, out clientId); if (!found || string.IsNullOrEmpty(clientId)) { clientId = _server.ClientIdGenerator.Create(); } //if another client with same unique id is online, do not accept new client MqClient foundClient = _server.FindClient(clientId); if (foundClient != null) { await connection.Socket.SendAsync(await _writer.Create(MessageBuilder.Busy())); return(null); } if (_server.Options.ClientLimit > 0 && _server.GetOnlineClients() >= _server.Options.ClientLimit) { return(null); } //creates new mq client object MqClient client = new MqClient(_server, connection, _server.MessageIdGenerator, _server.Options.UseMessageId); client.Data = data; client.UniqueId = clientId.Trim(); client.Token = data.Properties.GetStringValue(TmqHeaders.CLIENT_TOKEN); client.Name = data.Properties.GetStringValue(TmqHeaders.CLIENT_NAME); client.Type = data.Properties.GetStringValue(TmqHeaders.CLIENT_TYPE); //authenticates client if (_server.Authenticator != null) { client.IsAuthenticated = await _server.Authenticator.Authenticate(_server, client); if (!client.IsAuthenticated) { await client.SendAsync(MessageBuilder.Unauthorized()); return(null); } } //client authenticated, add it into the connected clients list _server.AddClient(client); //send response message to the client, client should check unique id, //if client's unique id isn't permitted, server will create new id for client and send it as response await client.SendAsync(MessageBuilder.Accepted(client.UniqueId)); if (_server.ClientHandler != null) { await _server.ClientHandler.Connected(_server, client); } return(client); }