Reputation: 38705
currently I am using javaEE7 and I have a scenario as follow. Inside my JSF webapp, I have an event listener (not JSF event) that when an event invoke, do something, then update these information to browser of my web app.
I have a ApplicationScoped
bean with eager=true
, that init an event listener in init @PostConstruct. My event listener (not a JSF event listener) look as follow
public class AMIEventListener extends AbstractManagerEventListener {
public void init(){
//handle connection to Asterisk server using AMI
}
@Override
protected void handleEvent(NewCallerIdEvent event) {
AsteriskCaller caller = new AsteriskCaller(event.getCallerIdName(), event.getCallerIdNum());
//CallerRestClient restClient = new CallerRestClient(caller);
//restClient.sendCallerInfo();
}
}
So the method handleEvent
is invoking for a specific event when the phone is rang
, and I want to update these information onto the browser screen (screen popup CTI). What I have tried so far
1.Obtain the instance of my ViewScoped bean.
This does not work with FacesContext.getCurrentInstance() return null. I am assume that this because I am on a separate thread, which make sense since this is an event listener.
2.Have a web service, and sending data to the web service using Jersey client.
I am successfully send data to my web services JAX-RS, however from there, I am not able to send data to my JSF web page. I read and know that JSF and JAX-RS are two complete different technology, so they cant communicate
Can anyone please suggest an architecture that I can use?
3.I am thinking of using PrimeFaces push to update the data to the browser, however, I only want a computer browser to be display this information, not all whoever currently log in to the app to see the data. For that I am thinking of for each logged in user, it will have it own channel
with @PushEndPoint
accept some type of variable related to the current log in user. Is it an acceptable solution? So I might ending up having about 50-100 separate channels, will this create any side effect?
Upvotes: 0
Views: 381
Reputation: 9266
What you're trying to implement is like a Notification system where the server can actively send data to the client without any kind of triggers on the client side (eg. click button, open page).
If that's the case, PrimeFaces Push is definitely a solution. I am using the it to implement the Notification system in my application. Regarding the performance, you can try googling about the Atmosphere Framework, which is used for PrimeFaces Push.
UPDATE:
One important thing to note is that for PrimeFaces Push to work, your service needs to have access to the context of the web application. In other words, the implementation must be done inside the WAR
project. Otherwise, the PushContext
will be null
if you try to get it inside, say, an EJB
project. My NotificationServices
looks like the following:
@WebService(serviceName = "NotificationServices")
@Named(value="notificator")
public class NotificationServices {
private final PushContext pushContext = PushContextFactory.getDefault().getPushContext();
/**
* Push a notification to a user
*/
@WebMethod(operationName = "pushNotification")
public void pushNotification(@WebParam(name = "username") String username,
@WebParam(name = "message") String message) {
pushContext.push("/notification/" + username, message);
}
}
So, the remaining task is to connect users to their own channel after they've logged in. In my application, I used username
as the unique key for each channel. Then, you can use @WebServiceRef
to inject the above web service into any other services in your back-end implementation. At this point, you can simply invoke the pushNotification
method if you want to push any messages to the front end.
Since the service is also annotated with @Named
, you can also inject it in any front-end code using @Inject
if necessary.
Upvotes: 1