This project has moved to Gitlab: https://gitlab.com/emerjoin-oss/hi-framework/core.
It's a light Java Framework that allows developers to write fully Ajax web applications combining the power of a Java back-end to a rich client-side powered by AngularJS.
Please read the documentation at https://docs.hi-framework.org/1.1.0/getting-started/
Now you can fire events from the backend and handle them on the views.
Creating an event object is as simple as the following example:
public ExampleEvent extends WebEvent {
//Your properties here
}
Events are published to channels and every user has his own private channel. A part from his private channel, a user can also be subscribed to other channels. Multiple users can be subscribed to the same channel at the same time. Channels with multiple users subscribed are considered groups.
The name of the user's private channel must be defined via ActiveUser. This is the same object used to subscribe/unsubscribe the user to/from channels.
Take a look at the code snippet below to learn how to define the user's private channel:
public class Whatever {
@Inject
private ActiveUser user;
public void setPrivateChannelName(){
user.setWebEventChannel("john.ive");
}
}
In the code snippet above we define "zeus" as the current user's private channel.
Let's now learn how to subscribe a user to a channel and also how to later unsubscribe:
public class Whatever {
@Inject
private ActiveUser user;
public void joinCorporateChannel(){
user.subscribe("corporate");
}
public void quitCorporateChannel(){
user.unsubscribe("corporate");
}
}
Let's publish an event to be received by every user that is online:
public class Whatever {
@Inject
private WebEventsContext eventsContext;
public void example(){
//Performs a broadcast
eventsContext.publish(new ExampleEvent());
}
}
Let's now publish an event to a limited set of users:
public class Whatever {
@Inject
private WebEventsContext eventsContext;
public void example(){
//Publish event to some users
eventsContext.publish(new ExampleEvent(),"john.ive",
"bill.gates","clarke.griffin");
}
}
Let's now publish an event to a bunch of groups and users:
public class Whatever {
@Inject
private WebEventsContext eventsContext;
public void example(){
//Publish event to groups and users at the same time
eventsContext.publish(new ExampleEvent(),"john.ive",
"corporate","bill.gates","admins");
}
}
You can publish an event to as many channels as you want at the same time, regardless of whether the channel is private or a group.
The center of all attentions on the frontend are views. Let's now learn how to handle events on views.
The snippet presents how to handle events on view controllers:
Hi.view(function($scope){
$scope.$on("ExampleEvent",function(event){
//Handle event here
});
$scope.$on("AnotherEvent",function(event){
//Handle event here
});
});
You might need to handle an event from the template or even from a custom script in your application. Here is how to proceed:
Hi.$on("ExampleEvent",function(event){
//Handle event here
});
Your application can react to backend connectivity status changes. See examples below:
Hi.$events.ready(function(){
console.log("Events ready");
});
Hi.$events.offline(function(){
console.warn("Disconnected");
});
There is one application-level configuration that you are allowed to do for web-events: the reconnect-interval. Checkout the configuration snippet below:
<?xml version="1.0" encoding="UTF-8" ?>
<app xmlns="http://hi-framework.org/XML/1.9.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://hi-framework.org/XML/1.6.0 http://hi-framework.org/xml/Schema_1_9_0.xsd">
...
<events>
<reconnect-interval>5000</reconnect-interval>
</events>
...
</app>
To start using the Web-Events feature you need to include a provider in your application. The Hi-Framework team worked on a provider to get you started. Here are the Maven coordinates of the provider:
<dependency>
<groupId>org.emerjoin.hi.web.events</groupId>
<artifactId>vm-scoped-provider</artifactId>
<version>1.0.0</version>
</dependency>
This ready-made provider won't work well in a scenarion where you have multiple instances of your application deployed, hence the name vm_scoped_provider. This provider assumes that all the event listeners are connected to the same application instance, thus assuming a single-instance deployment.
The provider abstraction allowed Hi-Framework to focus on implementing the events management core infrastructure:
The events infrastructure implemented by Hi-Framework works entirely on an application-instance level. When Hi-Framework is asked to deliver a WebEvent, it will deliver that event to all listeners that are connected to the current application-instance. The provider abstraction creates the possibility of informing all active application-instances to deliver that event. The same applies to channels subscriptions. When Hi-Framework is asked to subscribe the current user to a specific channel, it will only subscribe the listeners that are connected to the current application-instance. Providers are meant to implement cluster-awareness on top of the events infrastructure provided by Hi-Framework.
The management of the event consumers and the delivery of the event are both managed at the Hi-Framework level by the WebEventsController. A Web-events provider acts as an intermediate between the application and the WebEventsController. Every behaviour triggered on the application-level is only made effective by Hi-Framework WebEventsController, going through a Web-events provider:
When an application calls ActiveUser.subscribe("channel") or ActiveUser.unsubscribe("channel") the following CDI events are fired respectively:
Because WebEvents are published using the WebEventsContext abstraction, a Web-events provider is required to provide a WebEventsContext CDI bean.
The code snippet below presents the vm_scoped_provider implementation:
@ApplicationScoped
public class VMScopedWebEventsContext implements WebEventsContext {
@Inject
private WebEventsController eventsController;
@Override
public void publish(WebEvent event) {
WebEventPublishRequest request = new WebEventPublishRequest(event);
eventsController.execute(request);
}
@Override
public void publish(WebEvent event, String... channels) {
WebEventPublishRequest request = new WebEventPublishRequest(event, channels);
eventsController.execute(request);
}
public void onJoinChannel(@Observes JoinChannel event){
eventsController.joinChannel(event.getUser().getUniqueId(),
event.getChannel());
}
public void onQuitChannel(@Observes QuitChannel event){
eventsController.quitChannel(event.getUser().getUniqueId(),event.
getChannel());
}
}
Hi-Framework now allows you to handle content-expiration properly. You can now define a function on your template, to be invoked whenever the backend detects that front-end is outdated, meaning that it requires a reload. See the example below:
Hi.template({
...
$expired: function(){
console.warn("Content expired");
}
...
});