BPC Frontend and Backend Eventing
Events can be exchanged between the frontend and backend via WebSocket. The following describes how:
-
create an event in the backend
-
send the event to the frontend via WebSocket
-
handle the event in the frontend
-
send a global event from the frontend to the backend
Creating an Event in the Backend
An event can be created using the EventManager and sent to the frontend.
The ` EventManager ` can be called via BpcServicesTracker.
Below is an example of creating an event in the backend and sending it to the frontend.
In this example, it is assumed that the class ` NotificationManager ` has already been registered in the ` BundleContext ` and therefore receives the ` BundleContext ` as a parameter.
public class NotificationManager implements BpcService {
private final BundleContext bundleContext;
private final BpcServicesTracker<EventManager> eventManagerTracker;
public NotificationManager(BundleContext bundleContext) {
this.bundleContext = bundleContext;
this.eventManagerTracker = new BpcServicesTracker<>(bundleContext, EventManager.class);
}
public void sendGreetingEvent() {
try {
// Name of event is the last part in the URI
// In this case, event name is greetUser
eventManagerTracker.getService().fireEvent("de/virtimo/bpc/core/notification/greetUser", DictionaryUtil.dictionaryOf(
"message", "Hello world"
));
} catch (ServiceNotFoundException ex) {
LOG.log(Level.WARNING, "Failed to send the notification added event.", ex);
}
}
}
@Path("/")
public class BpcEndpoint {
private static final Logger LOG = Logger.getLogger(BpcEndpoint.class.getName());
private final BundleContext bundleContext;
private BpcServicesTracker<NotificationManager> notificationManagerTracker;
public BpcEndpoint(BundleContext bundleContext) {
LOG.info("BpcEndpoint bundleContext=" + bundleContext);
this.bundleContext = bundleContext;
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response getInitialPage() {
NotificationManager notificationManager = notificationManagerTracker.getService();
notificationManager.sendGreetingEvent();
return Response.ok().build();
}
}
If you now call the endpoint /, the event is sent to the frontend via WebSocket.
This event is named greetUser.
Receiving and Handling Events in the Frontend
The event is received in the frontend as a global ExtJS event. The following shows how to intercept and handle this event in the frontend.
Ext.define("BPC.controller.WebSocketMessageController", {
extend: "Ext.app.Controller",
listen: {
global: {
"greetUser": "onGreetUser"
}
},
onGreetUser: function (event) {
const message = event.properties.message;
alert(message.message);
}
});
Ext.define("BPC.controller.WebSocketMessageController", {
extend: "Ext.app.Controller",
init : function () {
Ext.on("greetUser", (event) => {
const message = event.properties.message;
alert(message.message);
});
}
});
Sending events from the frontend to the backend via WebSocket
It is possible to send a global ExtJS event to the backend via WebSocket. To do this, specify in the module interface which events should be forwarded to the backend.
Once the events have been specified, the frontend forwards the triggered event to the backend. This event can be received there via the EventService. By default, the event is automatically forwarded to all active clients.
|
Since the event and its associated data are automatically distributed to all clients, please handle sensitive data with care here. |
Below is an example of how to provide this information.
Ext.define("demo.BpcInterface", {
extend : "BpcCommon.BpcInterface",
config : {
/**
* An array of component-xtypes which will be added to the configuration GUI for this module. They
* will get the Ext.data.Model of the corresponding module as parameter and can be used via this.module.
*/
moduleConfigurationComponents : [],
/**
* A string which points to the baseModuleView, ExtJS class, string
*/
baseModuleView : null,
/**
* A string which points to the mainView, ExtJS class, string
*/
mainView : null,
/**
* Array of global event names, which should be forwarded to the backend.
*/
forwardedEvents : [
"chat"
]
}
});
// Fire global forwarded event
Ext.fireEvent("chat", {});
See also BpcInterface
Receiving and handling events in the backend
The event can be received in the backend as follows:
public public class DemoModule extends AbstractInstantiableModule {
private static final Logger LOG = Logger.getLogger(DemoModule.class.getName());
private final EventRegistration eventRegistration;
public DemoModule(ModuleManager moduleManager) {
super(moduleManager);
this.eventRegistration = new EventRegistration(null);
}
public void setModuleBundle(Bundle moduleBundle) {
super.setModuleBundle(moduleBundle);
BundleContext bundleContext = moduleBundle.getBundleContext();
eventRegistration.setBundleContext(bundleContext);
eventRegistration.forClientEvents(new ChatEventHandler(bundleContext), "chat");
}
@Override
public void destroy() {
LOG.info("destroy");
super.destroy();
// unregister the event handlers
eventRegistration.unregisterAllEventHandler();
// stop the service trackers
BpcServicesTracker.stopAll(this);
}
// ... other module funtioncs
private class ChatEventHandler extends AbstractEventHandler {
BundleContext bundleContext;
public ChatEventHandler(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
@Override
protected void processEvent(Event event) {
String eventTopic = event.getTopic();
if (eventTopic.equals(CLIENT_EVENT_DOMAIN + "chat")) {
Map<String, Object> data = (HashMap) event.getProperty("data");
LOG.warning("A client send a message hihi: " + data.get("text"));
}
}
}
}