Can we delay responding to a XMPP presence subscription? - java

I am using a PacketListener to receive XMPP packets.
If I receive the following:
<presence from="jeanne#belle.com" to="betty#belle.com" type="subscribe"/>
is the XMPP server expecting me to respond immediately ?
Motivation: I want to cache all these subscription requests and allow the recipient to selectively ACCEPT/DENY (à la facebook invitations).
Is there an API in which I can request for all subscription requests from openfire ?

You do NOT need to reply immediately or even in a given session; the server stores the fact that you have a pending inbound subscription, and will re-inform you of the pending subscription every time you log in. Therefore, there should be no need to request the list either.

Related

Spring WebSocket: Order of subscriptions don't allow messages to be received

I followed the https://spring.io/guides/gs/messaging-stomp-websocket/ and added a few modifications (mainly Spring Security Auth and dynamic topics(Rooms)).
The order the client subscribes to topics doesn't allow messages onDisconnect event to be received by the client that's still in the room despite the server sysout showing that it sends.
I have 2 topics that the client subscribes to in a room and this order of subscriptions works but if I change the order of the subscriptions then the user that's still in the room won't receive a message:
// user direct message
stompClient.subscribe(`/user/topic/${roomId}`, (message) => {...}
// General
stompClient.subscribe(`/topic/${roomId}`, (message) => {...}
2 users connect and I send alerts to the client that the users joined and all is well until 1 client disconnects. In the order of subscriptions above the client that's still in the room will receive the message that a client has disconnected but if the subscription order is changed then the client will not receive the message that a client disconnected.
Does the order in how the client subscribes to topics matter?

How to send websocket message to a specific subscription in a session?

I have implemented a WebSocket server using Spring WebSocket and STOMP. There are multiple subscriptions over a single session and I want to send message to a specific subscription only.
Steps to reproduce:
Client connects to server by calling registered STOMP endpoint.
Client makes 2 subscription over the connection.
SUBSCRIBE
country:germany
id:sub-0
destination:/user/queue/countryUpdates
SUBSCRIBE
country:france
id:sub-1
destination:/user/queue/countryUpdates
In SimpUserRegistry there is 1 user and 1 session with 2 subscription.
Problem is if I send a message to one subscription it's send to other subscription as well.
At the time of sending the message I am adding subscription id in native headers, but it's not working.
SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
accessor.setNativeHeader("id", subscriptionId);
accessor.setNativeHeader("subscription", subscriptionId);
accessor.setSubscriptionId(subscriptionId);
accessor.setLeaveMutable(true);
messagingTemplate.convertAndSendToUser(simpUserId, REPLY_DESTINATION, message, accessor.getMessageHeaders());
What I've tried: If I add country to destination, each subscription have unique destination than there are no duplicate messages.
I want to use id/subscriptionId to determine the subscription and send message to that particular subscription.

Can gRPC bidi streaming server send a message to a client that it is not currently responding to?

Can gRPC bidi streaming server respond out of sequence to a client ? All examples on the net show server responding to an incoming request only. The StreamObserver interface contains implementation for the response responding to a request
In onNext method, can the StreamObserver parameter be cached and reused later to send messages ?
What I need :
I have cached the StreamObserver on the first request for Client1
On a request from Client2, I need to send a message to Client1
Using the cached StreamObserver object throws a CANCELLED error and I notice onComplete is called for the first request from Client1
Is there a way to do this ?
This seems to be a similar ask, but was not supported 2015, and am not sure if this now possible
Once the server receives the StreamObserver for responses to the client it can call the object from any thread at any time (although the object is not thread-safe, so concurrent calls are not permitted). There's no need to couple it with incoming requests in onNext().
The client calling onComplete() is normal and does not end the RPC. If your code turns around and calls onComplete(), however, at that point you can no longer send any more messages on the stream. You will probably want to observe client cancellations, which can be achieved by casting the StreamObserver to ServerCallStreamObserver and calling setOnCancelHandler(Runnable) at the start of the RPC.

Saga messaging implementation with RabbitMQ

I'm new to RabbitMQ and want to implement asynchronous messaging of SAGA with RabbitMQ.So I used RPC example of RabbitMQ to do the task. I've one orchestrator ( RPCClient) and multiple microservices ( RPCServer). Orchestrator uses unique queues to command microservices.And each microservice uses a common queue ( Reply_ Queue) to reply orchestrator. To keep log I want to get notifications in orchestrator side, when any microservice is down for any configurable time.
I read about consumer cancellation,but it only works when I delete the queue.How to get notifications in JAVA with keeping queue messages? And is it correct way to implement saga asynchronous messaging?
To implement a reliable RPC is hard, I can't give a detail guide about how to do this. If we ignore same special failure situation, I can give a simple workaround:
First, we assume that RPCClient never fail, RPCServer may fail anytime.
RPCClient need to know which request is timeout, so it can send request message with a TTL. After RPCServer receive request message and send response message, it should ACK the request message.
If RPCServer:
has failed before consume request message
OR
has failed before send response message
The request message will be republish to Dead Letter Exchange, so RPCClient can consume to some queue binded with that exchange, it can know which request is timeout.

Architecture advice about managing UDP calls

I would like to have an advice for this issue:
I am using Jbos 5.1.0, EJB3.0
I have system, which sending requests via UDP'S to remote modems, and suppose to wait for an answer from the target modem.
the remote modems support only UDP calls, therefor I o design asynchronous mechanism. (also coz I want to request X modems parallel)
this is what I try to do:
all calls are retrieved from Data Base, then each call will be added as a message to JMS QUE.
let's say i will set X MDB'S on that que, so I can work asynchronous. now each MDB will send UDP request to the IP-address(remote modem) which will be parsed from the que message.
so basicly each MDB, which takes a message is sending a udp request to the remote modem and [b]waiting [/b]for an answer from that modem.
[u]now here is the BUG:[/u]
could happen a scenario where MDB will get an answer, but not from the right modem( which it requested in first place).
that bad scenario cause two wrong things:
a. the sender which sent the message will wait forever since the message never returned to him(it got accepted by another MDB).
b. the MDB which received the message is not the right one, and probablly if it was on a "listener" mode, then it supposed to wait for an answer from diffrent sender.(else it wouldnt get any messages)
so ofcourse I can handle everything with a RETRY mechanisem. so both mdb's(the one who got message from the wrong sender, and the one who never got the answer) will try again, to do thire operation with a hope that next time it will success.
This is the mechanism, mybe you could tell me if there is any design pattren, or any other effective solution for this problem?
Thanks,
ray.
It's tough to define an exacting solution without knowing the details, but I will assume that when a response is received from a modem (either the correct one or not), it is possible to determine which exact modem the request came from.
If this is the case, I would separate out the request handler from the response handler:
RequestMDB receives a message from the [existing] queue, dispatches the request and returns.
A new component (call it the ResponseHandler) handles all incoming responses from the modems. The response sender is identified (a modem ID ?) and packages the response into a JMS message which is sent to a JMS Response Queue.
A new MDB (ResponseMDB) listens on the JMS Response Queue and processes the response for which the modem ID is now known.
In short, by separating concerns, you remove the need for the response processing MDB to only be able to process responses from a specific modem and can now process any response that is queued by the ResponseHandler.
The ResponseHandler (listening for responses from the modems) would need to be a multithreaded service. You could implement this as a JBoss ServiceMBean with some sort of ThreadPool support. It will need a reference to the JMS QueueConnectionFactory and the JMS response queue.
In order to handle request timeouts, I propose you create a scheduled task, one for each modem, named after the modem ID. When a request is sent, the task is scheduled for execution after a delay of the timeout period. When a response is received by the ResponseHandler, the ResponseHandler queues the response and then cancels the named task. If the timeout period elapsed without a cancellation, the scheduled task executes and queues another request (an reschedules the timeout task).
Easier said than done, I suppose, but I hope this helps.
//Nicholas

Categories

Resources