GreenLightning allows behaviors to communicate with each other using PubSub (short for Publish and Subscribe). One behavior can subscribe to a topic and thus listen to any messages coming from other behaviors about the same topic.
GreenLightning also has the concept of Private Topics - topics between behaviors are discovered at start, and a direct private connection between those behaviors is established, preventing other behaviors from listening if they do not subscribe to the same topic.
PubSub Example
Below is a very simple PubSub example. The GreetingBehavior will send out a greeting message to the topic "Greet" and publish another greeting if it receives a "SayHello" message. The ExampleBehavior will listen to the greeting message and send out the initial "SayHello" message.
We demonstrate usage of the default PubSubListener (filter topics manually using if-else or switch-case) and PubSubMethodListener (direct method call, no branching logic needed).
In our main file, we will simply register the behaviors and add their corresponding subscriptions:
PubSub.java
publicclassPubSubimplementsGreenApp{ @OverridepublicvoiddeclareConfiguration(Builder c) { } @OverridepublicvoiddeclareBehavior(GreenRuntime runtime) {// Create a pubSub listener that will broadcast a message if promptedruntime.addPubSubListener(newGreetingBehavior(runtime,"Greet"))// We want to know when someone is asking for a greeting..addSubscription("SayHello");// Create another behavior that will ask for a Hello on start up and // listen to it.ExampleBehavior example =newExampleBehavior(runtime,"SayHello");runtime.registerListener(example)// We want to know when someone greets us, so subscribe.addSubscription("Greet", example::listenToGreeting)// This just demonstrates multiple subscriptions are simpler using// PubSubMethodListener instead of PubSubListener.addSubscription("AnExample", example::anotherMessage); }}
In GreetingBehavior.java, we create a PubSubFixedTopicService to publish our message:
GreetingBehavior.java
publicclassGreetingBehaviorimplementsPubSubListener {privatefinalPubSubFixedTopicService channel;publicGreetingBehavior(GreenRuntime runtime,CharSequence publishTopic) {// Create a channel based on topic passed in that we will publish tothis.channel=runtime.newCommandChannel().newPubSubService(publishTopic.toString()); }// We have receive someone asking for a greeting, so send it! @Overridepublicbooleanmessage(CharSequence topic,ChannelReader payload) {//Note if this behavior is subscribed to more than 1 topic we will need//to branch here based on the value of topic. returnchannel.publishTopic(w ->w.append("Hello World!")); }}
In ExampleBehavior.java, we create another PubSubFixedTopicService and use it to publish our given topic on start (we are asking for a Greeting). Then, we have the listenToGreeting method as defined in PubSub.java listening to any new greetings:
ExampleBehavior.java
publicclassExampleBehaviorimplementsPubSubMethodListener,StartupListener {privatefinalPubSubFixedTopicService channel;publicExampleBehavior(GreenRuntime runtime,CharSequence publishTopic) {// Create a new command channel that we will use to ask for a greeting (SayHello topic).this.channel=runtime.newCommandChannel().newPubSubService(publishTopic.toString()); } @Overridepublicvoidstartup() {// On startup, let's ask for a greeting!channel.publishTopic(); }publicbooleanlistenToGreeting(CharSequence topic,ChannelReader payload) {// We received a greeting, so listen to itSystem.out.println("Received a greeting: "+payload.readUTF());returntrue; // if you were to return false, you will receive the same message again next time }publicbooleananotherMessage(CharSequence topic,ChannelReader payload) {// Do nothing here, it's just an example.returntrue; }}
Private Topics
Private Topics (always enabled) allow direct communication between behaviors without having to dispatch through a central router, improving performance and security.
However, you may not want Private Topics for certain topics (see warning below). You can use the method definePublicTopics on Builder:
@OverridepublicvoiddeclareConfiguration(Builder config) {// For our example above, this would disable dirct communication between// ExampleBehavior and GreetingBehavior. The messages would first go through// a grand dispatch before arriving at targeted subscribers.config.definePublicTopics("Greet","SayHello");}
Note that subscribing to a private topic at runtime is not possible. You will have to explicitly declare this topic public if you know that it will be dynamically subscribed to at a later point.