Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 带有p:poll/push的通知系统_Jsf_Jsf 2_Primefaces - Fatal编程技术网

Jsf 带有p:poll/push的通知系统

Jsf 带有p:poll/push的通知系统,jsf,jsf-2,primefaces,Jsf,Jsf 2,Primefaces,我已经尝试为一个基本的社交网络实现基本通知系统,在视图层上使用p:poll,以及一个简单的NotificationService类,该类从DB获取新通知,并刷新NotificationBean的通知列表,该列表为每个用户设置了查看范围。工艺流程与此类似: -Poll calls NotificationBean.getNewNotifications for example every 15 sec. --getNewNotifications calls NotificationService

我已经尝试为一个基本的社交网络实现基本通知系统,在视图层上使用
p:poll
,以及一个简单的
NotificationService
类,该类从DB获取新通知,并刷新
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
但是,
p:poll
关注的是它的性能,因为它在每个间隔到期时都发送一个查询

PrimeFaces有一个基于Atmosphere框架的应用程序,它打开了web套接字,似乎更适合创建通知系统

但我不知道应该使用哪些组件以及它们的哪些属性。它有
p:socket
组件,具有
channel
属性。我应该使用用户名作为
频道
值吗?以下代码来自PrimeFaces showcase,总结了最后几句话:

<p:socket onMessage="handleMessage" channel="/notifications" /> 
但这将通知所有用户页面,我需要一个推送通知特定用户。假设有2个用户,假设User1将User2添加为好友。一定有这样的事:

pushContext.push("User2/notifications", new FacesMessage("friendship request", "from User1"));
但我不确定这是否是这种功能需求的正确用法。考虑到应用程序的可扩展性,在一个进程中打开这么多频道的成本可能会很高


谢谢你的帮助

PrimeFaces push支持一个或多个要推动的通道。能够为特定原因创建私人渠道;例如,对于每个用户,您可以创建多个频道。为此,我使用了唯一的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);
    }

}
您应该将通道值指定给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>  

函数handleMessage(facesmessage){
facesmessage.severity='info';
咆哮秀([facesmessage]);
}  
对于可伸缩性问题,您应该维护活动或非活动通道。您可以删除一段时间内未处于会话或非活动状态的。当bean正在销毁时,使用@PreDestroy注释删除通道。在我的解决方案中,一个用户会话只有一个通道


我的建议是,;不要在页面上明确使用用户名。出于安全原因,这不太好。

您想让一个用户立即向其他用户发送消息吗?@ronnk这取决于您对
消息的理解方式。在问题中,我提到了包含通知的列表。如果user1将user2添加为好友或对其状态的注释,则应将通知附加到user2的通知列表中,该列表可以是普通字符串列表,也可以是更适合我的实现的模型类列表。所以,是的,这必须是立即的。(对不起我的英语)好的,我想你们不想使用轮询,所以服务器将广播消息,每个客户端将进行筛选,或者服务器必须存储客户端的地址并发送到特定的地址,我认为。让专业人士来解决您的问题:)是的,这正是我需要的:)这似乎是正确的,但我仍然很少担心它的性能,是否有其他预防措施?顺便说一句,感谢您的回答,正如您可能想象的那样,我将等待赏金到期,而不是蛋糕。我知道JSF本身的性能问题,很多人对存储用户的视图状态有偏见,这会降低性能。但它提供了很多功能,实际上我想亲自体验一下,当我这么做的时候,它应该被灵活地实现,以获得最大的性能。这就是为什么我问了这个问题,这就是为什么我想摆脱
p:poll
@erencan这个应用程序范围的bean线程安全吗?由于有多个并发用户,您应该注意这一点。@oko应用程序范围的bean不是线程安全的。此外,hashmap put方法不是原子的。所以可能会出现一些问题。正如我所建议的,这是一个实现细节。您可以通过使用事务在数据库中保持通道,或使addChannel方法同步。@ÖmerFarukAlmalı就我跟踪atmosphere的源代码而言,有一个查找表,可以像您想象的那样维护ip和通道匹配。唯一的可能是重载此查找表。该表位于org.atmosphere.cpr.DefaultBroadcasterFactory中,并存储在store hashmap中。应该需要对大气进行一些实现才能刷新此表。
@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: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>