I have a problem, and I don't know exactly what to search for.
I have a spring boot app which broadcast the message via web socket with a stomp javascript client. The question is if I can put a lock on the message when it is sent because I want no one to send another message at the same time. The system that I want to make is like a traffic light.
If you can give me an example or what to look for.
You should use synchronized keyword and wait for the client response. synchronized keyword ensures that only one thread can execute the method at the same time. And you need client response because you can sequentially send two messages, say in two seconds interval, but your client will get them at the same time. Response can be some dummy ok-message.
public class Traffic {
synchronized void Send() {
// write message to websocket
// read response from websocket
}
}
Related
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.
Let's say I have a Load Balancer (LB) in front of 1..n VertX (V) instances, each VertX instance is connected to a queue (Q), and I have 1..m Backends (BE).
A user clicks on a button which makes a post request or even opens a web socket, the load balancer forwards the request to one of the VertX instances, which fires a request to the queue, one of the Backends consumes the message and sends a response back; if the correct VertX instance consumes it, it can lookup the response handler and write a response to the user, if the wrong VertX instance consumes it, there won't be a response handler to write a response to and the user will wait indefinitely for a response.
See this sketch:
Alternatively, V2 dies and the load balancer reconnects the user to V1 which means even if I could send it back to the exact same one that made the request, it's not guaranteed to still be there once the response comes back, but the user might still be there awaiting a response via another VertX instance.
What I'm currently doing is to generate a GUID for each new connection, then as soon as the websocket connects, store the websocket handler inside a hashmap against the GUID and then when the BE wants to respond, it does a fanout to all 1..n VertX instances, the one that currently has the correct GUID in its hashmap can then write a response to the user.
Same for handling POST / GET in this manner.
Pseudocode:
queue.handler { q ->
q.handler {
val handler = someMap.get(q.guid)
// only respond if handler exists
if (handler != null){
handler.writeResponse(someresponsemessagehere)
}
}
}
vertx.createHttpServer().websocketHandler { ws ->
val guid = generateGUID()
someMap.put(guid, ws)
ws.writeFinalTextFrame("guid=${guid}")
ws.handler {
val guid = extractGuid(it)
// send request to BE including generated GUID
sendMessageToBE(guid, "blahblah")
}
}.requestHandler { router.accept(it) }.listen(port)
This does however mean that if I have a 1000 VertX applications running, that the backend will need to fanout its message to a 1000 frontend instances of which only one will make use of the message.
VertX seems like it already takes care of async operations very well, is there a way in VertX to identify each websocket connection instead of having to maintain a map of GUIDs mapped to websocket handlers / post handlers?
Also, referring to the picture, is there a way for V3 to consume the message, but still be able to write a response back to the websocket handler that's currently connected to V2?
What you're missing from your diagram is the Vertx EventBus.
Basically you can assume that your V1...Vn are interconnected:
V1<->V2<->...<->Vn
Let's assume that Va receives your outbound Q message (the red line), that is intended for Vb.
It then should send it to Vb using EventBus:
eventBus.send("Vb UUID", "Message for Vb, also containing WebSocket UUID", ar -> {
if (ar.succeeded()) {
// All went well
}
else {
// Vb died or has other problems. Your choice how to handle this
}
});
I have an application using MQTT implemented with the paho-mqtt-1.0.2 and I am using ActiveMQ as the broker. I have a class implementing the MqttCallback, what I am wondering is why does the client hang
#Override
messageArrived(...)
do work
mqtt.publish(TOPIC,PAYLOAD,2,false) <- here
I want to send a "response" message to the broker for the next step of the work to be done. Similar to this, I read in the docs for that callback function
It is possible to send a new message within an implementation of this callback (for example, a response to this message), but the implementation must not disconnect the client, as it will be impossible to send an acknowledgment for the message being processed, and a deadlock will occur.
Has anyone out there tried doing the above and get it to work?
I also tried using the MqttAsyncClient and that ended up with
"Error too many publishes in progress" leading to undelivered messages.
I know how to get around this issue, I'm not looking for workaround; I'm looking for receiving and publishing on the thread where messageArrived() gets executed.
Happy Hunting!
I'm new to socket programming and programming a Java UDP simple client-server application. I'm writing a time/date server client. The client can ask the server for the time and date and it waits for a response. Also, every minute, the server updates all clients with the current time. The client needs to
be able to initiate contact with the server and wait for a message back
listen for periodic updates from the server
How can I do this using a single DatagramSocket?
I was thinking of creating two threads: one that listens and one that writes. The problem is that in the case that the client initiates contact with the server, it needs to wait to receive an acknowledgement from the server. So, the writing thread also needs to listen for packets from the server sometimes. But in this case, I have two threads listening and the wrong thread will get the acknowledgement.
Is there a way to specify which thread gets the input? Or is there some other way to solve this problem?
I've been searching for this answer but unable to find it. The closest I've found is Java sockets: can you send from one thread and receive on another?
If there is just one writer thread then it could send the request and go into a wait loop. The listener thread would then get the response, add it to a shared variable (maybe an AtomicReference), and then notify the writer that response has been received.
// both write and listener threads will need to share this
private final AtomicReference<Response> responseRef =
new AtomicReference<Response>();
...
// writer-thread
writeRequest(request);
synchronize (responseRef) {
while (responseRef.get() == null) {
// maybe put a timeout here
responseRef.wait();
}
}
processResponse(response);
...
// listener-thread
Response response = readResponse();
synchronize (responseRef) {
responseRef.set(response);
responseRef.notify();
}
If you have multiple writers or multiple requests being sent at the same time then it gets more complicated. You'll need to send some sort of unique id with each request and return it in the response. Then the response thread can match up the request with the response. You'd need a ConcurrentHashMap or other shared collection so that the responder can match up the particular request, add the response, and notify the appropriate waiting thread.
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