Websocket client to send JSON messages

Hi,

I want my application to be able to send JSON messages to a websocket sever.
The idea is when I assing a task to an agent, I send task information to the server which will then redistribute it to the actual agents and send me back information when the task is complete.

What shall I create to achieve that?
Could someone point me to a step-by-step guide or examples?

Thanks in advance.

Hi @kontrag,

If I understand you correctly, then your solution should be mostly based on 2 parts:

  1. https://docs.camunda.org/manual/7.6/user-guide/process-applications/process-application-event-listeners/ Process Application listener which sends information to your service that will distribute message to the agents over websockets.

  2. Intermediate catch event https://docs.camunda.org/manual/7.6/reference/bpmn20/events/message-events/#message-intermediate-catching-event which allows you to continue process once tasks are completed.

Does that help you?
Askar

Hi @aakhmerov,

  • Which type of Process Application listener do you mean?
    Should it be an Execution Listener in the task which will send JSON messages to the messeging server?

  • You suggestion is that after every task that I need to get information that is completed I should put an intermediate catching message event. But that means that the catching event should be in a waiting state (meaning that the preceding task has already been completed). How is that possible?
    Also, how will I correlate a message coming from a messaging server to the catching message event?

  • What about external tasks?

Thanks for your ideas!
Kostas

HI @kontrag

Cheers,
Askar

Hi @aakhmerov,

  • You’ve pointed a link which has information on Task and Execution Event listeners. What is your suggestion? Which of these two types of Listeners should I use?
  • I have a task which has to be completed by a robot. I need to send task information to a messaging server which will then trigger the robot to move and perform what is needed. And finally the robot (through the messaging server) should inform me back that the task is completed and the process flow can move on. So, how can I reach an intermediate catching message event if the preceding task is still not completed?
  • I am asking whether External Tasks are used for such purposes. I’m not experienced and I haven’t used such a Task and I ask whether you think it could serve my purposes that I described above.

Thanks!

Anyone else any suggestion?

Thanks!

I’m looking at this from a general integration architecture background - and, not sure I’d use “external tasks”. Reason is that Camunda provides a robust service orchestration framework capable of managing long-running business transactions. And, this is somewhat of a personal choice… but, why not implement (or delegate) task implementations with Java? Noting that I avoid JavaScript outside of web-UI requirements.

Choices… and patterns.

The BPMN (model) groups together and describe business function by setting boundaries around and relationship between one or more tasks. Tasks are related to other tasks and roles(workers/robots). Good fit for telling a robot what to do in terms of task-driven, or originating, event instructions. And these robots naturally conserve effort/energy - goal oriented.

So a process model organizes tasks. And, as each task receives tokens (context), their underlying java components get called. These java-based services are then free to assemble event payloads (JSON) before posting them to various middle-ware channels such as messaging, etc… For critical activities, I prefer messaging infrastructure supporting transaction services.

Since you’re orchestrating robots - I’d lean towards a more data-centric view.

Briefly…

  1. Camunda orchestrates the tasks into meaningfully aligned, goal-oriented, activities such as “build a car”.
  2. Tasks, and their java implementations, then assemble and send messages into the event-stream, middle-ware channels, etc.
  3. While Camunda is handling the long-running business-transactions, the middle-ware handles traditional transaction services (alongside event-processing). Thinking in terms of message-based, event-oriented systems.
  4. Services (SOA) listen for and react to these events. For example, the robot does X because it was told to do so via certain event types and payloads.
1 Like

Hi,

I wrote a websocket ClientEndpoint to send a message to a websocket server.
The opening of the web socket connection and the sending of the message is called as a Java delegate code on a Send Task.

I would like to ask your advice on how to handle the opening of a session and the sending of the messages throughout a process which has many Send Tasks.

I mean, if I open a session in the beginning of the process, then can I maintain it in the next steps in the process to send messages using this session? How?
Or do you think I should open a new session every time I have a new “Send Task”?

Thanks in advance!

Depends…

Opening a new connection is costly - but, how sensitive is your application to these delays? I would also recommend a server platform capable of advanced features such as object pools.

Example:

  • If you have a java-delicate needing to send hundreds+ outbound messages, and this occurs in the same session, then I’d use Apache Camel’s integration components. Reason I like Camel is that it has a ready supply of advanced integration features with fully documented config’ options.
  • If you’re wrapping the socket connection as a resource, then you’ll need to set this new resource (like a JMS connection) into something you can manage in your application server so that you can setup object-instance pools.

This is a little different than task-execution sessions. The process-instance session, which is reasonably available via Camunda’s CDI features, adds in instance serialization. And, this sort of defeats advantages from using HTTP connector instance pooling. Meaning… if you’re trying to shave 100’s of milliseconds on connect+send latency, then it’s better to avoid adding to this latency with process-instance object marshaling (serialization).

What I would do is create a discrete performance test and measure the gains/costs. In most cases, the user won’t notice a 500ms latency in response. However, if you’re connecting and sending thousands of messages within a single process instance, then connection pooling becomes a requirement both at the client and server side of this interface protocol.

Hi,

I have a class handling the receipt of a websocket message.
I want from this class to call some code (in another class) to correlate a Catching Message Event
The calling code will be like this:

MessageCorrelationBuilder correlationBuilder = runtimeService.createMessageCorrelation("Task_Completed_By_Agent_X");
  correlationBuilder.processInstanceId(commonDataAccessor.getCallerProcessInstanceID());
  correlationBuilder.processInstanceVariableEquals(CommonDataAccessor.UNIQUE_BUSINESS_KEY, commonDataAccessor.getUniqueBusinessKey());
  correlationBuilder.correlateAllWithResult();

How do I inject the RuntimeService or the execution from the first class?
I have CDI as dependency.

Thanks!

Good to see CDI… this makes it easy (reasonably) -

Though this project is a little rough… in progress with an upgrade (switching over to pure JsonNode - no JSON parsing - ideally. It has lots of examples for referencing the BPM engine.

See my straight-through-process example. Specifically, Reference Implementation showing Apache Camel. However, rather than JMS you’re using sockets. But, basically responding to an event and then calling on Camunda via the event-handler.

Though I’m correlating via JMS, you can use Camunda’s message-events. Reason I prefer JMS is it allows decoupling between the sub-systems.

Here’s an example of starting a BPM process instance via a Apache-Camel event handler.

It looks like you’re already doing this though via an injected runtimeService - so, not sure if this helps. You might try using CDI-events - recommend referencing JBoss/Wildfly examples (aka “quickstarts”). They have a good CDI event example showing response via JSF.

Apologies for the java-source formatting (in the todo list).