Pub/Sub with Rich Clients

177 views
Skip to first unread message

Derek

unread,
Aug 13, 2013, 5:37:45 PM8/13/13
to akka...@googlegroups.com
What is the recommended approach for using distributed pub/sub between a server and rich, Java (Swing) clients?  I'd like the clients to subscribe to topics to which the server publishes.

I have looked at the Cluster Client referenced below but it appears that it only supports sending/publishing from client to the server but not the other way around.  Is there any way for clients to subscribe to cluster topics externally?


Would appreciate suggestions if there are better options for pushing messages from a server to subscribed Java clients.  Thanks.

Jason O'Gray

unread,
Aug 14, 2013, 2:26:54 PM8/14/13
to akka...@googlegroups.com
Is there a reason why the client's couldn't just members of the cluster itself, and then you could broadcast (http://doc.akka.io/docs/akka/2.2.0/scala/routing.html#broadcast-messages) the message? It's how I would envision solving this.

Björn Antonsson

unread,
Aug 14, 2013, 3:51:04 PM8/14/13
to Akka User List
Hi Derek,
There actually seems to be a way to register an actor using the cluster client as a topic subscriber to the PubSubMediator.

To do this you would have to register the PubSubMediator to itself (by using Put, or ClusterReceptionistExtension(system).registerService) to make it available to cluster clients. The default mediator in the DistributedPubSubExtension, ends up at the path /user/distributedPubSubMediator

You would then send a Subscribe("topic", actorRef) wrapped inside a Send to the path "/user/distributedPubSubMediator", to register the actorRef as a subscriber to the topic.

B/

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

-- 
Björn Antonsson
Typesafe – Reactive Apps on the JVM
twitter: @bantonsson

Björn Antonsson

unread,
Aug 14, 2013, 3:54:47 PM8/14/13
to akka...@googlegroups.com
Hi Jason,

On Wednesday, 14 August 2013 at 20:26, Jason O'Gray wrote:
Is there a reason why the client's couldn't just members of the cluster itself, and then you could broadcast (http://doc.akka.io/docs/akka/2.2.0/scala/routing.html#broadcast-messages) the message? It's how I would envision solving this.

One problem would be the size of the cluster as soon as you get a big number of clients.

B/
 

On Tuesday, August 13, 2013 5:37:45 PM UTC-4, Derek wrote:
What is the recommended approach for using distributed pub/sub between a server and rich, Java (Swing) clients?  I'd like the clients to subscribe to topics to which the server publishes.

I have looked at the Cluster Client referenced below but it appears that it only supports sending/publishing from client to the server but not the other way around.  Is there any way for clients to subscribe to cluster topics externally?


Would appreciate suggestions if there are better options for pushing messages from a server to subscribed Java clients.  Thanks.

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Derek

unread,
Aug 14, 2013, 7:19:33 PM8/14/13
to akka...@googlegroups.com
Thanks for your reply.  I did try this originally and it did work - any node subscribing within the cluster was capable of receiving the messages published to the topic.  However, I don't think it makes sense to run a cluster this way?  What if the server (assume a single server with many clients connected to it) goes down?  One of the clients, running on a user's desktop, will then become the new leader!  This is what I observed in my initial testing but I am very much an akka newbie so maybe more can be done via configuration to improve on the behavior?  The Cluster Client seemed to make a lot more sense to me (auto cluster re-connect is built in, etc.).

Derek

unread,
Aug 14, 2013, 7:25:30 PM8/14/13
to akka...@googlegroups.com
Thanks Bjorn, think I understand that.  I'll give it a try tomorrow and report back. 

Patrik Nordwall

unread,
Aug 15, 2013, 3:31:30 AM8/15/13
to akka...@googlegroups.com
Hi Derek and Björn,


On Thu, Aug 15, 2013 at 1:25 AM, Derek <dkn...@gmail.com> wrote:
On Wednesday, August 14, 2013 2:51:04 PM UTC-5, Björn Antonsson wrote:
Hi Derek,

On Tuesday, 13 August 2013 at 23:37, Derek wrote:

What is the recommended approach for using distributed pub/sub between a server and rich, Java (Swing) clients?  I'd like the clients to subscribe to topics to which the server publishes.

I have looked at the Cluster Client referenced below but it appears that it only supports sending/publishing from client to the server but not the other way around.  Is there any way for clients to subscribe to cluster topics externally?


Would appreciate suggestions if there are better options for pushing messages from a server to subscribed Java clients.  Thanks.

There actually seems to be a way to register an actor using the cluster client as a topic subscriber to the PubSubMediator.

To do this you would have to register the PubSubMediator to itself (by using Put, or ClusterReceptionistExtension(system).registerService) to make it available to cluster clients. The default mediator in the DistributedPubSubExtension, ends up at the path /user/distributedPubSubMediator

You would then send a Subscribe("topic", actorRef) wrapped inside a Send to the path "/user/distributedPubSubMediator", to register the actorRef as a subscriber to the topic.


There is a problem with this solution, which I didn't foresee when Björn and I talked about it yesterday. The cluster client establishes a connection to one of the nodes in the cluster, and the subscription will be registered in the mediator of that node. The problem is when this node goes down. The subscription will disappear with the node, and the client will not notice (except from not receiving any more messages for the topic).

Similar can happen if there is connectivity problem between the client and the cluster node, then the client will establish a new connection to another node, but the subscription is lost.

I'm not sure if there is a reasonable solution to this problem.
It might be possible that you can watch some actor on the cluster side from the client to get notified when the node (or network) goes down and then re-subscribe.

/Patrik



--

Patrik Nordwall
Typesafe Reactive apps on the JVM
Twitter: @patriknw

paul.fo...@gmail.com

unread,
Aug 15, 2013, 9:59:19 AM8/15/13
to akka...@googlegroups.com
Bjorn, Derek, et al,

Perhaps I am missing something, but do we need clustering here at all?  Clustering is still an experimental module, and Akka, of course, fully supports remote (and location-transparent) Actors out of the gate - isn't that all that's needed?

Here is one scenario:

- On the server exists a Publisher Actor

- When a client comes into existence, it creates an Actor system, a Subscriber Actor, and pings the Publisher with this reference, which then adds the Subscriber to its list of Routees.  (Or, instead of the Publisher managing its Subscribers manually, we could probably use a Router that would send each pub-sub message as a Broadcast.)

- To handle reconnects, the Subscribers Watch the Publisher.  If it terminates, they start attempting reconnect at intervals until successful.

Is this workable?

Björn Antonsson

unread,
Aug 15, 2013, 2:39:52 PM8/15/13
to akka...@googlegroups.com
Hi Paul,

On Thursday, 15 August 2013 at 15:59, paul.fo...@gmail.com wrote:
Bjorn, Derek, et al,

Perhaps I am missing something, but do we need clustering here at all?  Clustering is still an experimental module, and Akka, of course, fully supports remote (and location-transparent) Actors out of the gate - isn't that all that's needed?

The clustering is not experimental as of Akka 2.2.0.

Of course you don't need the cluster to do a client server implementation, I think that the thing here was to try to leverage existing code that gave you a more robust solution than a single server.

B/


Here is one scenario:

- On the server exists a Publisher Actor

- When a client comes into existence, it creates an Actor system, a Subscriber Actor, and pings the Publisher with this reference, which then adds the Subscriber to its list of Routees.  (Or, instead of the Publisher managing its Subscribers manually, we could probably use a Router that would send each pub-sub message as a Broadcast.)

- To handle reconnects, the Subscribers Watch the Publisher.  If it terminates, they start attempting reconnect at intervals until successful.

Is this workable?

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.

paul.fo...@gmail.com

unread,
Aug 15, 2013, 3:54:23 PM8/15/13
to akka...@googlegroups.com
Hello Bjorn,

Thanks for the reply - can you please tell me if you see any holes in the simple system I proposed?  Thanks much.

Jason O'Gray

unread,
Aug 15, 2013, 4:28:48 PM8/15/13
to akka...@googlegroups.com
As an alternative, couldn't you use akka-camel to implement this push style? The client and the cluster would each have endpoints and when a client starts it would go through a list of known cluster seeds to find one that is up. The client would then register with the cluster, and the cluster would then have the ability to talk with the client directly and vice versa.

This could lead to other headaches depending on the client's network, but seems to be a viable alternative, at least upon first glance.

paul.fo...@gmail.com

unread,
Aug 15, 2013, 5:04:13 PM8/15/13
to akka...@googlegroups.com
Hi Jason,

We have some experience with Camel, but, I must admit that at first blush using Camel in such a manner (and running it on *clients*) seems a bit much.

FYI, the current implementation is JMS (HornetQ), and it is quite simple.  A Topic gives you pub-sub and the HornetQ client handles reconnects internally.

(Why switch to Akka?  Because we are heavily into Scala & Typesafe, are using Akka thoroughly elsewhere, and are contemplating a move to Play 2 from a JEE server.  And because there are some other issues with JMS.)

Björn Antonsson

unread,
Aug 16, 2013, 5:30:27 AM8/16/13
to akka...@googlegroups.com
Hi Paul,

On Thursday, 15 August 2013 at 21:54, paul.fo...@gmail.com wrote:

Hello Bjorn,

Thanks for the reply - can you please tell me if you see any holes in the simple system I proposed?  Thanks much.

On Thursday, August 15, 2013 1:39:52 PM UTC-5, Björn Antonsson wrote:
Hi Paul,

On Thursday, 15 August 2013 at 15:59, paul.fo...@gmail.com wrote:
Bjorn, Derek, et al,

Perhaps I am missing something, but do we need clustering here at all?  Clustering is still an experimental module, and Akka, of course, fully supports remote (and location-transparent) Actors out of the gate - isn't that all that's needed?

The clustering is not experimental as of Akka 2.2.0.

Of course you don't need the cluster to do a client server implementation, I think that the thing here was to try to leverage existing code that gave you a more robust solution than a single server.

B/


Here is one scenario:

- On the server exists a Publisher Actor

- When a client comes into existence, it creates an Actor system, a Subscriber Actor, and pings the Publisher with this reference, which then adds the Subscriber to its list of Routees.  (Or, instead of the Publisher managing its Subscribers manually, we could probably use a Router that would send each pub-sub message as a Broadcast.)

I think that it would be easier to let the Publisher handle the subscribers instead of using a Router.
 

- To handle reconnects, the Subscribers Watch the Publisher.  If it terminates, they start attempting reconnect at intervals until successful.

Remote DeathWatch is only reliable since Akka 2.2.0. You can't use this approach on earlier versions or you might miss that the Publisher JVM went down. Also the Publisher should watch the subscribers as well so it can clean them out when they go away.
 

Is this workable?

If you're OK with a SPOF client-server solution, then yes, it's workable.

B/

paul.fo...@gmail.com

unread,
Aug 16, 2013, 10:03:55 AM8/16/13
to akka...@googlegroups.com
Thanks much, Bjorn.  We are currently on 2.1.2 but should be able to upgrade to 2.2 pretty easily.

Ashish Patel

unread,
Aug 18, 2013, 6:12:04 AM8/18/13
to akka...@googlegroups.com
Hi Derek,

Im trying to do a similar thing i.e distributed pub-sub in a cluster but the remote end and even the local node do not get the messages when I use CluserClient.SendAll.
I have no idea what the issue is but am looking for a simple example.

As you seem to have got this working would it be possible to share the code you have for a simple example.
I've attached my code which runs but the message is never received when I send using ClusterClient.

Ive read the Akka pages but am having a very hard time making sense of them as the lack of fully working examples in Java.

Thanks
application.conf
ClientReceptionist2.java
Publisher.java
Subscriber.java

Derek

unread,
Aug 19, 2013, 10:51:26 AM8/19/13
to akka...@googlegroups.com
Ashish,

The example that I got working was simply using the base cluster support, not the Cluster Client.  So in my case the server and the clients were all peers in the cluster.  For various reasons this type of configuration doesn't make sense -- seemed like Cluster Client is exactly what we need, but Bjorn and Patrik have outlined limitations in what can currently be done with Cluster Client.

That being said, I think I see some issues with your application.conf file (which tripped us up of for a while too).  
   1) In the remote section use the actual IP of the server instead of localhost.  When the server binds to localhost in this way I believe it will no accept external connections.
   2) Same thing would then apply to the seed nodes -- if you have a cluster with multiple members it is my understanding that you would want to use the actual IP address(es) of the machine(s) that are to serve as the cluster leader.

I am very new to Akka myself so please let me know if these suggestions helped.

We are now on to investigating the solution proposed above by Paul.  

Thanks everyone for your suggestions.
-Derek

Patrik Nordwall

unread,
Aug 19, 2013, 1:41:57 PM8/19/13
to akka...@googlegroups.com
Derek, thinking some more about this I have come to the conclusion that it is not difficult to create a client side subscriber.
What is needed is an actor on the cluster side that can be watched by the client, to be able re-subscribe when needed.
It is best illustrated with some code: https://gist.github.com/patriknw/6271877
Disclaimer: untested
WDYT?



--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.



--

Ashish Patel

unread,
Aug 19, 2013, 3:51:32 PM8/19/13
to akka...@googlegroups.com
Hi Derek,

You suggestions definitely help and those by Patrik too - it got the initial example working.
Im now using proper IP address of the "ClusterSystem" and then I use the same ip and port in the Remote Section in the application.conf too.

This got it working in that I can send messages through the receptionist on the ClusterSystem on one IP.

Next, Im trying to create another ClusterSystem2 on a different IP and then connect to the receptionist on ClusterSystem - this worked as I can see it in the log that ClusterSystem2 connected to receptionist on ClusterSystem.
BUT when I send a message from system2 to ClusterSystem , its never received.

Thanks for your help with this.

cheers,
Ash.


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to a topic in the Google Groups "Akka User List" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/akka-user/5sWghsQF9oc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to akka-user+...@googlegroups.com.

Derek

unread,
Aug 19, 2013, 6:42:47 PM8/19/13
to akka...@googlegroups.com
Hi Patrik,

Today I have implemented a very simple solution as laid out by Bjorn, Paul, etc. above.  It is a basic client-server pub/sub that utilizes a server-side actor that maintains it's own set of "subscribers".  When clients come online they send a subscribe message to the server.  Both client and server watch each other - so that the client knows if the server goes down and therefore must initiate a reconnect and so that the server knows when a client has terminated so that it can remove it from its subscribers.  Surprising how little code is needed.  Now, as you guys pointed out, this leaves us with a SPOF but that is ok for us for now.

Given my experience from today, I now know that it's ~trivial to set up this type of watch & re-connect behavior.  What I have not done is explore further into the Cluster Client.  If I understand what you guys had suggested earlier about the PubSubMediator registering with the Receptionist, etc., it sounds to me like that should all work (but I won't be trying it out for the moment b/c we are not running a server cluster yet--a project for another day!).

One quick question for you -- if using Cluster Client and registering client subscribers with the pub sub mediator, when a client is terminated is it automatically cleaned up on the server side?  This is something I need to do "manually" (via watch) with what I got working today.

Thanks again,
-Derek

Patrik Nordwall

unread,
Aug 20, 2013, 2:13:04 AM8/20/13
to akka...@googlegroups.com
On Tue, Aug 20, 2013 at 12:42 AM, Derek <dkn...@gmail.com> wrote:
Hi Patrik,

Today I have implemented a very simple solution as laid out by Bjorn, Paul, etc. above.  It is a basic client-server pub/sub that utilizes a server-side actor that maintains it's own set of "subscribers".  When clients come online they send a subscribe message to the server.  Both client and server watch each other - so that the client knows if the server goes down and therefore must initiate a reconnect and so that the server knows when a client has terminated so that it can remove it from its subscribers.  Surprising how little code is needed.  Now, as you guys pointed out, this leaves us with a SPOF but that is ok for us for now.

Great that you have found a solution that works.


Given my experience from today, I now know that it's ~trivial to set up this type of watch & re-connect behavior.  What I have not done is explore further into the Cluster Client.  If I understand what you guys had suggested earlier about the PubSubMediator registering with the Receptionist, etc., it sounds to me like that should all work (but I won't be trying it out for the moment b/c we are not running a server cluster yet--a project for another day!).

Another added value if you have a server cluster is that you can publish messages to the clients from any server node, without knowing which node the client is connected to, but if you only have one server that is of course not needed.
 

One quick question for you -- if using Cluster Client and registering client subscribers with the pub sub mediator, when a client is terminated is it automatically cleaned up on the server side?  This is something I need to do "manually" (via watch) with what I got working today.

Yes, watch is used by the pub sub mediator to cleanup terminated subscribers.

/Patrik
Reply all
Reply to author
Forward
0 new messages