Notification system with p: poll / push

I tried to implement a basic notification system for a basic social network with p:poll at the presentation level and a simple NotificationService class that receives new notifications from the database and updates the NotificationBean notification list, which is viewcoped for each user. The process flow is similar to this:

 -Poll calls NotificationBean.getNewNotifications for example every 15 sec. --getNewNotifications calls NotificationService and DAO methods ---notificationList of user is refreshed ----DataTable on view layer shows new notifications 

But the p:poll problem is performance because it sends a request every time the interval expires.

PrimeFaces has PrimePush , which is based on the Atmosphere Framework, it opens web sockets and seems more suitable for creating a notification system.

But I do not know what components and what their properties should be used. It has a p:socket component with a channel property. Should I use usernames as channel values? Below is the code coming from the PrimeFaces storefront and summarizes the latest offers:

 <p:socket onMessage="handleMessage" channel="/notifications" /> 

As far as I understood from this example showcase , this p:socket listens on the notifications channel. And the pusher code snippet:

 PushContext pushContext = PushContextFactory.getDefault().getPushContext(); pushContext.push("/notifications", new FacesMessage(summary, detail)); 

But this will notify all user pages, I need a pusher that notifies a specific user. Let's say there are 2 users, and suppose User1 adds User2 as a friend. Must be pcs. eg:

 pushContext.push("User2/notifications", new FacesMessage("friendship request", "from User1")); 

But I'm not sure if this is the right use for this kind of functional requirement or not. Given the scalability of the application, there can be a costly cost to open as many channels in the process.

Thanks for the help.

+12
jsf jsf-2 primefaces
Apr 09 '13 at 13:52
source share
1 answer

The PrimeFaces function supports one or more channels to click. Be able to create private channels for certain reasons; for example, for each user, as in your case, you can create several channels. I used unique identifiers for this purpose.

Basically, I implemented a managed bean, which is a scope that handles the correspondence of a user channel that needs to be considered. You can support it in different ways.

 @ManagedBean @ApplicationScoped public class ChannelsBean { Map<String, String> channels = new HashMap<String, String>(); public void addChannel(String user, String channel) { channels.put(user, channel); } public String getChannel(String user) { return channels.get(user); } } 

Then enter this bean in your support bean that sends notifications.

 @ManagedBean @SessionScoped public class GrowlBean { private String channel; @ManagedProperty(value = "#{channelsBean}") private ChannelsBean channels; private String sendMessageUser; private String user; @PostConstruct public void doPostConstruction() { channel = "/" + UUID.randomUUID().toString(); channels.addChannel(user, channel); } public void send() { PushContext pushContext = PushContextFactory.getDefault().getPushContext(); pushContext.push(channels.getChannel(sendMessageUser), new FacesMessage("Hi ", user)); } //Getter Setters } 

You must specify the channel value for p: socket. Here is an example of a page launch;

 <p:growl widgetVar="growl" showDetail="true" /> <h:form> <p:panel header="Growl"> <h:panelGrid columns="2"> <p:outputLabel for="user" value="User: " /> <p:inputText id="user" value="#{growlBean.sendMessageUser}" required="true" /> </h:panelGrid> <p:commandButton value="Send" actionListener="#{growlBean.send}" /> </p:panel> </h:form> <p:socket onMessage="handleMessage" channel="#{growlBean.channel}" /> <script type="text/javascript"> function handleMessage(facesmessage) { facesmessage.severity = 'info'; growl.show([facesmessage]); } </script> 

For scalability issues, you must maintain active or inactive channels. You can delete one that is not in the session or inactive for some time. Remove channels using the @PreDestroy annotation when beans are destroyed. My solution has one channel for one user session.

My suggestion; do not use usernames explicitly on pages. This is not good for security reasons.

+8
Apr 17 '13 at 8:20
source share



All Articles