我尝试在视图层上使用p:poll
的基本社交网络和一个简单的NotificationService
类实现基本通知系统,该类从DB获取新通知并刷新{{}的通知列表{1}}是每个用户的视图编组。与此类似的流程:
NotificationBean
但-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
关注的是它的性能,因为它会在每个时间间隔到期时发送一个查询。
PrimeFaces有PrimePush基于Atmosphere Framework,它打开网络套接字,似乎更适合创建通知系统。
但我不知道应该使用哪些组件及其属性。它具有p:poll
组件,具有p:socket
属性。我应该将用户名用作channel
值吗?下面来自PrimeFaces的代码展示并总结了最后的句子:
channel
据我所知this showcase example这个<p:socket onMessage="handleMessage" channel="/notifications" />
听p:socket
频道。推送代码片段是:
notifications
但这会通知所有用户页面,我需要一个通知特定用户的推送器。假设有2个用户并假设User1将User2添加为朋友。必须有某事。那样:
PushContext pushContext = PushContextFactory.getDefault().getPushContext();
pushContext.push("/notifications", new FacesMessage(summary, detail));
但我不确定这是否适用于此类功能要求。考虑到应用程序的可扩展性,每个进程打开如此多的通道可能会产生昂贵的成本。
感谢您的帮助。
答案 0 :(得分:8)
PrimeFaces推送支持一个或多个频道推送。能够出于特定原因创建私人频道;例如,对于每个用户而言,您可以创建多个频道。我为此目的使用了独特的ID。
基本上,我已经实现了一个托管bean,它是应用程序作用域,用于处理应该考虑的用户通道匹配。你可以用不同的方式来维护它。
@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);
}
}
然后将这个bean注入你的发送通知的支持bean。
@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
}
您应该将通道值提供给p:socket。这是该页面的启动示例;
<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>
对于可伸缩性问题,您应该维护活动或非活动通道。您可以删除一段时间未处于会话或非活动状态的会话。当bean正在销毁时,使用@PreDestroy注释删除通道。在我的解决方案中,有一个用户会话通道。
我的建议是;不要在页面上明确使用用户名。出于安全原因,它并不好。