I would like to send a simple message from one client to another one not opening a chat because there will never be a response and all messages fire the same event.
In the smack (4.1.7) documentation I found out that it is possible to do so but so far I did not find a way how to do it.
Do you have any ideas how to do it?
Would it be better (especially acording to performance: runtime and memory) to use the chat?
For receiving you'd probably want to use a synchronous stanza listener with a suitable filter.For example, if you want to receive messages with a body from user#example.org, then you could
XMPPConnection connection = …;
connection.addSyncStanzaListener(new StanzaListener() {
#Override
void process(Stanza stanza) {
Message message = (Message) stanza;
// Received new message with body from user#example.org
}, new AndFilter(MessageWithBodiesFilter.INSTANCE,
FromMatchesFilter.create("user#example.org")));
Sending messages is even easier
Message message = new Message("user#example.org", "Hi, how are you?");
XMPPConnection connection = …;
connection.sendStanza(message);
Hint: Reading the source code of Smack is a great way to learn about such stuff. If you look at the source of ChatManager, you will find what I've just written above.
Related
I just started with java and minecraft modding. I want to implement a very simple task but unfortunately I do not know the right event for it.
Messages sent via
Minecraft.getMinecraft().player.sendChatMessage(message);
from the client to the server I can use:
public void onChat(ClientChatReceivedEvent event)
to read it back in.
However, there are now also messages that are sent via
Minecraft.getMinecraft().player.sendMessage(m)
only direct to the client. Is there also a possibility to read these messages? Another mod writes these "client only" messages that I want to respond to.
You can. You have to read output packet that contains sent messages like that :
#Inject(method = "sendPacket(Lnet/minecraft/network/Packet;)V", at = #At("HEAD"), cancellable = true)
private void onSendPacket(Packet<?> packet, CallbackInfo callbackInfo) {
// System.out.println("Packet Sent: " + packet.toString());
// here you can get the packet type, then if it's chat's you can get content
// you can cancel it with: callbackInfo.cancel();
}
Source
So I have a one client-server based ecosystem where I am using RabbitMQ as a persistent Middleware.
Now the flow of a single message goes like this.
Step-1: Client A sends a message to the server with the destination
being set to Client B in the metadata of that message.
Step-2: Server upon receiving a message pushes the message to the
RabbitMQ and sends Client B a notification that he has some messages
to fetch.
Step-3: Client B upon getting notified calls the fetch message API to
get messages from the server.
Step-4: On the server, after getting called from the Client B pulls
messages from the RabbitMQ using the pull-based approach
(channel.basicGet(queueName, false)) and hands over the list of
messages.
Now in the above flow, there are few things that I have some doubt with.
First of all, if my client receives two notifications and calls the pull message API twice, there might be a concurrency problem.
Suppose I am not sending the message Acknowledgement while getting the message but I am sending afterwards, then can It be possible that the same message being sent to two pull API? If so is there any way to prevent this from happening?
Sample Code to Get Message From the MQ:
long currentMessageCount = channel.messageCount(QUEUE_NAME);
while (currentMessageCount-- > 0) {
GetResponse getResponse = channel.basicGet(QUEUE_NAME, false);
if (getResponse == null) {
break;
}
AMQP.BasicProperties props = getResponse.getProps();
Envelope envelope = getResponse.getEnvelope();
int messageCount = getResponse.getMessageCount();
byte[] body = getResponse.getBody();
/*
Do some logic
*/
channel.basicAck(envelope.getDeliveryTag(), false);
}
TIA
basicGet is rarely the correct solution. In Step 2, the client should be consuming from RabbitMQ. No notification that a message is ready is necessary. RabbitMQ will send the message to Client B as soon as it's in the queue. Step-3 and Step-4 become unnecessary.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.
I'm using SMSLib for sending and receiving messages. Everything's working great, but now I'd like to plug more than one modem. I want to receive messages by all of my modems and do something with them (I can do that, I think). I also want to send messages, but only through the selected modem (there's my problem). Until I had one gateway i did sending like this:
OutboundMessage msg = new OutboundMessage(recipientNumber, text);
Service.getInstance().sendMessage(msg);
But now, how can I select the one specific gateway, that I want to use to send my message?
I found a topic with a problem a bit like mine, but not exactly:
Use multiple gateway with SMSLIB
Each modem is a AGatway object in SMSLib so you need to set it up first:
SerialModemGateway modemGateway = new SerialModemGateway("FirstGateway", "/dev/ttyM0", "9600", "WAVECOM", "Fastrack");
Service.getInstance().addGateway(modemGateway);
Where FirstGateway is ID of your modem which is called gatewayId in SMSLib. All you have to do now is pass your gatewayId to sendMessage method or queueMessage (if you send messages asynchronously):
OutboundMessage msg = new OutboundMessage(recipientNumber, text);
Service.getInstance().sendMessage(msg, "FirstGateway");
or:
OutboundMessage msg = new OutboundMessage(recipientNumber, text);
msg.setGatewayId("FirstGateway");
Service.getInstance().sendMessage(msg);
I didnt notice that there is such a method sendMessage() which takes gatewayId as a second agrument. If so, there will be perfect. I'll check that tomorrow, are you sure about that? I'm using SmsLib 3.x
EDIT:
It's exactly as you said. I just put gatewayId as a second argument and it's working. Another options is that you can set gatewayId of created OutboundMessage:
OutboundMessage msg = new OutboundMessage(recipientNumber, text);
msg.setGatewayId("FirstGateway");
Service.getInstance().sendMessage(msg);
So easy.. Thanks!
I would't use sendMessage method with multiple gateways, use queueMessage it adds your msg to SMSLib service queue and sends it asynchronously.
Also , if you start your application with:
-Dsmslib.queuedir=yourQueuedMessagesDirectory
you will be able to store all unsent messages on hard drive and give SMSLib service facility to send them after application restart.
I have made a bot which can reply when the client sends a message. I want to send a message to the client without them sending me a message. I don't want to code in each and every message. Can someone please suggest a method for this? Thank you.
XMPPService xmpps = XMPPServiceFactory.getXMPPService();
Message msg = xmpps.parseMessage(req);
.....
......
msg = new MessageBuilder()
.withRecipientJids(jid)
.withBody(respMsg)
.build();
xmpps.sendMessage(msg);
what the above code does is, it sends the message after it receives a message from the client. my bot basically informs the clients about important announcements. so suppose i want to tell them something important without them asking. i just want to send a message and all my clients should receive it. do i need the JID of my clients? if so, then how do i get them? i am new to xmpp please help me.
Thank you.
It is not possible to broadcast messages to all jou xmpp contacts at once. You have to adress them one by one. If you look deepher in the xmpp code you will see that status updates will be broadcasted to all contacts that are not offline. Maybe you can use that to your advantage.
I am using Tapestry 5, Smack api 3.1.0.
I have established a connection and am able to communicate with a user through the xmpp server but the replies i get are sent to the standard output as they come in:
Chat chat = connection.getChatManager().createChat("blah#jabber.org", new MessageListener() {
public void processMessage(Chat chat, Message message) {
// Print out any messages we get back to standard out.
System.out.println("Received message: " + message.getBody()); // this works
showonbrowser = message.getBody();
System.out.println(showonbrowser) // this prints nothing
}
};
I am looking to get the replies to my html file so i can read them on the web instead of the console. However, when i try to set message.getBody() to showonbrowser (a property on the page) i see no result. Does anyone know how I get around this?
Regards,
Kace
Smack is multi-threading and it has a nasty habit of eating up exceptions that are thrown (silently.) Most likely you are not using a thread-safe GUI and its throwing an exception that you never get.
I think the processMessage method is being called after the page is rendered.
You are creating a MessageListener instance (through an anonymous class), so you don't know when the processMessage method will be called. I think you would have to do something with AJAX to do partial updates on the page, polling the server and getting any new messages to show them on the page.