idUdpServer send message to multiple - delphi

I know how to send a message from server
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, 'jhon|zack|randy', ABinding.IPVersion);
to one , but how to do it to several? Need to create an array: record ip data and port, or have built-in functions

Related

How to send a message from Helix controller to participant?

I want to send a message to all Participant nodes of my Helix cluster from Controller node. I tried following piece of code to send message to all registered participants of my cluster but their registered Participant message listeners are not receiving the message notification from Helix.
Message msg = new Message(factory.getMessageTypes().get(0), msgId);
msg.setMsgId(msgId);
msg.setSrcName(hostSrc);
msg.setTgtSessionId("*");
msg.setMsgState(MessageState.NEW);
msg.getRecord().setSimpleField("TestMessage", "Message from controller");
Criteria recipientCriteria = new Criteria();
recipientCriteria.setRecipientInstanceType(InstanceType.PARTICIPANT);
recipientCriteria.setInstanceName("%"); // To all recipients
recipientCriteria.setSessionSpecific(true); // To deliver only live participants
recipientCriteria.setSessionSpecific("DEV_CLUSTER"); // To only participants of this cluster
messagingService.send(recipientCriteria,msg);
Note that, when I am sending this message there is no resource exists in the cluster.
After debugging further what I have observed is CriteriaEvaluator.evaluateCriteria(....) operation is returning an empty list which further results into 0 messages to be sent to Participants nodes.
Kindly let me know if I am missing anything here while defining my criteria for Participants.
Thanks !
Update-1: our observation on this issue is as follows:
The received message at the participant side is read by both the Participant message listener(Say L1) and the handler created through MessageHandlerFactory(Which internally creating a listener HelixtaskExecutor (Say L2)).
In case if the message is read by HelixTaskExecutor(L2) first, it then immediately deletes the Znode in Zookeeper and the additionally configured message listener(L1) doesn't receive this message.
In case if the message is first read my additional message listener i.e. L1 then in such scenarios we don't face this problem as this additionally added listener doesn't delete the Znode from ZooKeeper.
We are still not sure how can we handle this problem as we want to use both the listener and MessageHandlers but facing the same problem I stated above.
Any inputs are appreciated.

Raid doesn't receive C_ChatInfo.SendAddonMessage

I'm making this addons that have to send to the raid my interrupt cooldown.
The problem is that whenever i send a message to the raid i am the only one that receive it.
This is the code that send the message:
C_ChatInfo.SendAddonMessage("KickRotation",string.format( "%0.2f",remainingCd ), "RAID")
This is the event handler:
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
frame:RegisterEvent("CHAT_MSG_ADDON")
frame:SetScript("OnEvent", function(self, event, ...)
local prefix, msg, msgType, sender = ...;
if event == "CHAT_MSG_ADDON" then
if prefix == "KickRotation" then
print("[KickRotation]" ..tostring(sender) .." potrĂ  interrompere tra: " ..msg);
end
end
if event == "PLAYER_ENTERING_WORLD" then
print("[KickRotation] v0.1 by Galfrad")
end
end)
Basically when the message is sended it is printed only to me.
Network messages are handled and transferred to the recipient channel (in this case, Raid Group) by the server. The reason that you are seeing the message locally, but the other people do not see it is that the message will be handled on the local system (sender) to reduce the repetition of data transmit.
Server however, only accepts and sends messages that are registered to it.
Therefore, you must first register your add-on messages to the server so the other players in the requested channel be able to receive it.
First, register your add-on messages with the name you have given already (But be sure to call the registration method only once per client):
local success = C_ChatInfo.RegisterAddonMessagePrefix("KickRotation") -- Addon name.
Next, check if your message was accepted and registered to the server. In case success is set to false (failure), you may want to handle proper warning messages and notifications to the user. The case of failure means that either server has disabled add-on messages or you have reached the limit of add-on message registrations.
Finally, send your message again check if it did not fail.
if not C_ChatInfo.SendAddonMessage("KickRotation",string.format( "%0.2f",remainingCd ), "RAID") then
print("[KickRotation] Failed to send add-on message, message rejected by the server.")
end

Does Firebase always guarantee added events in order?

I am developing messenger IOS app based on Firebase Realtime Database.
I want that all messages to be ordered based on timestamp.
There is a scenario as like below.
There are 3 clients. A, B and C.
1)
All clients register 'figure-1' listener to receive messages from others.
<figure-1>
ref.queryOrdered(byChild: "timestamp").queryStarting(atValue: startTime).observe(.childAdded, with:
{
....
// do work for the messages, print, save to storage, etc.
....
// save startTime to storage for next open.
startTime = max(timeOfSnapshot, startTime)
saveToStorage(startTime)
}
2)
Client A write message 1 to server with ServerValue.timestamp().
Client B write message 2 to server with ServerValue.timestamp().
Client C write message 3 to server with ServerValue.timestamp().
They sent messages extremely the same moment.
All clients have good speed wifi.
So, finally. Server data saved like 'figure-2'
<figure-2>
text : "Message 1", timestamp : 100000001
text : "Message 2", timestamp : 100000002
text : "Message 3", timestamp : 100000003
As my listener's code, i keep messages on storage and next listening timestamp for preventing downloading duplicated messages.
In this case.
Does Firebase always guarantee to trigger callback in order as like below?
Message 1
Message 2
Message 3
If it is not guaranteed, my strategy is absolutely wrong.
For example, some client received messages as like below.
Message 3 // the highest timestamp.
// app crash or out of storage
Message 1
Message 2
The client do not have chance to get message 1, 2 anymore.
I think if there are some nodes already, Firebase might trigger in order for those. Because, that is role of 'queryOrdered' functionality.
However, there are no node before register the listener and added new nodes additionally after then. What is will happen?
I suppose Firebase might send 3 packets to clients. (No matter how quickly the message arrives, Firebase has to send it out as soon as it arrives.)
Packet1 for message1
Packet2 for message2
Packet3 for message3
ClientA fail to receive for packet 1,2
ClientA success to receive for packet 3
Firebase re-send packet 1,2 again.
ClientA success to receive for packet 1,2
Eventually, all datas are consistent. But ordering is corrupted.
Does Firebase guarantee to occur events in order?
I have searched stack overflow and google and read official documents many times. However, i could not find the clear answer.
I have almost spent one week for this. Please give me piece of advice.
The order in which the data for a query is returns is consistent, and determined by the server. So all clients are guaranteed to get the results in the same order.
For new data that is sent to the database after the listeners are attached, all remote clients will receive it in the same order. The local client will see events for it's write operation right away though, before the data even reaches the database server.
In figure 2, it is actually quite simple: since each node has a unique timestamp, and they will be returned in the order of that timestamp. But even if they'd have the same timestamp, they'd be returned in the same order (timestamp first, then key) for each client.

Indy SMTP Server and Telnet

I have been fooling about with the SMTP client and server components in Indy 9 using demos with Delphi 7. Everything works fine. However, when I telnet into the server, the demo shows only the email subject and mail body, the From: and To: fields are not shown.
The code below shows that AMsg is lacking the relevant data.
procedure TForm1.IdSMTPServer1ReceiveMessageParsed(ASender: TIdCommand;
var AMsg: TIdMessage; RCPT: TIdEMailAddressList;
var CustomError: String);
begin
// This is the main event if you have opted to have the idSMTPServer to do your parsing for you.
// The AMessage contains the completed TIdMessage.
// NOTE: Dont forget to add IdMessage to your USES clause!
ToLabel.Caption := AMsg.Recipients.EMailAddresses;
FromLabel.Caption := AMsg.From.Text;
SubjectLabel.Caption := AMsg.Subject;
Memo1.Lines := AMsg.Body;
// Implement your file system here :)
end;
Can anybody suggest a reason?
First of all, a thankyou to Remy for his response.
Second, it seems I can't post images here, yet, but here is a link to images of server-telnet session https://postimg.org/image/f0n9j0kcx/. The telnet session shows the server responses.
Thanks also for reminding me about Wireshark, and the suggestion of using a TIdLog component.
It is tricky to know for sure since you did not show the actual SMTP commands you are sending via Telnet, but you are likely missing required commands/data that TIdSMTP sends. To see the actual SMTP commands/responses that are being exchanged, you can use a packet sniffer like Wireshark, or attach one of Indy's TIdLog... components to the TIdSMTP and/or TIdSMTPServer socket connections.
Any email address that is received via a MAIL FROM command and accepted by the server (see the OnCommandMail event) is passed to the OnReceive... events in the TIdSMTPServerThread(ASender.Thread).From property. The server will not accept a RCPT TO command if an email address has not been accepted from MAIL FROM first. If you do not assign an OnCommandMail handler, the server will accept any email address it receives.
Any email addresses that are received via RCPT TO commands and accepted by the server (see the OnCommandRCPT event) are passed to the OnReceive... events in the RCPT parameter, and also in the TIdSMTPServerThread(ASender.Thread).RCPTList property. The server will not accept a DATA command if at least one email address was not accepted from RCPT TO first. If you do not assign an OnCommandRCPT handler, the server will accept every email address it receives.
In the OnReceiveMessage... events, the provided TIdMessage object is first populated from the raw email data that is sent in the DATA command only. In the case of the OnReceiveMessageParsed event only, any email addresses that were previously accepted via RCPT TO are then merged into the TIdMessage.Recipients property if they do not already exist. However, any email address received in the MAIL FROM command is not merged into the TIdMessage.From property.
So, depending on what email data you are actually sending in the DATA command, the AMsg.From property may or may not be empty. But the AMsg.Recipients property certainly should not be.
Also, something else to keep in mind - TIdSMTPServer is multi-threaded (as most Indy servers are). Its events are fired in the context of worker threads, not the main UI thread. Your code is directly accessing VCL UI controls from outside of the main UI thread, which is not safe and can cause all kinds of problems. You must synchronize with the main UI thread, using either the VCL's TThread.Synchronize() or TThread.Queue() methods, or Indy's TIdSync or TIdNotify classes, or any other thread-safe sync mechanism of your choosing, as long as the synced code runs in the context of the main UI thread only.

Mirth: How to send ACK message to sender host and port

I am receiving lab HL7 messages from a static host and a dynamic port. For each message received I need to send a ACK message back to this host and port.
I have a destination TCP Writer channel with the correct message in there. Though the port number has to be fixed.
How do I tell Mirth to send this message to the sending host and port?
Thanks in advance
Abhi
You should configure your channel to use the LLP Listener instead, which has the option to reply with a custom HL7 ACK message. The message will be send back on the same connection so you don't have to keep track of the address of the sending system.
In Mirth you send a customized ACK message.
In Scripts, select the Postprocessor (This script executes once after a message has been processed)
and write this code
var ackString = ""; //build a javascript string for your custom ack
var ackResponse = ResponseFactory.getSuccessReponse(ackString);
responseMap.put("Custom ACK", ackResponse);
Mirth will then parse the Postprocessor script, and discovers the reponseMap code. On the source tab, go to the Send ACK radio list, you can now select "Respond from" and "Custom ACK" from the options in the dropdownlist avaiable.

Resources