I\'ve tried to implement the basic notification system for a basic social network with p:poll
on view layer and a simple NotificationService
class
PrimeFaces push supports one or more channels to push. To be able to create private channels for specific reasons; for example per user like in your case, you can create more than one channels. I had used unique ids for this purpose.
Basically, I've implemented a managed bean which is application scoped that handles user channel matching which should be considered. You can maintain 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 inject this bean in your backing bean which 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 should give the channel value to p:socket. Here is the kickoff example of the page;
<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 should maintain the active or inactive channels. You can remove the one which is not in session or inactive for some time. Remove channels by using @PreDestroy annotation when beans are destroying. There is one channel for one user session in my solution.
My suggestion is; do not use usernames explicitly on the pages. It is not good for security reasons.