2013-04-09 19 views
12

ビューレイヤでp:pollの基本ソーシャルネットワークの基本通知システムを実装しようとしましたが、NotificationServiceクラスでは新しい通知をDBから取得し、NotificationBeanこれは各ユーザーについて表示されます。これに似たプロセスフロー:p:poll/pushを使用した通知システム

-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 Frameworkに基づいて、Webソケットを開き、通知システムを作成するのに適しているように見えます。PrimePushがあります。

しかし、どのコンポーネントとどのプロパティを使用するべきかわかりません。これは、channelプロパティを持つp:socketコンポーネントを持っています。ユーザー名をchannelの値として使用する必要がありますか? PrimeFacesからのコードの下には、最後の文章を紹介し、まとめたものです。

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

は、私の知る限り理解されるように this showcase exampleからこの p:socketnotificationsチャネルをリッスンします。私は、特定のユーザに通知プッシャーを必要とし、

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

しかし、これは、すべてのユーザーページに通知します:そしてプッシャーコードスニペットです。たとえば、2人のユーザーがおり、User1がUser2を友人として追加したとします。 sthがなければなりません。

しかし、これはこの種の機能要件の正しい使用法であるかどうかはわかりません。アプリケーションのスケーラビリティを考慮すると、プロセスごとに非常に多くのチャネルを開くコストが高くなる可能性があります。

ありがとうございます。

+0

あるユーザーが他のユーザーに直接メッセージを送信したいですか? –

+0

@RongNKは 'message'の理解の仕方によって決まります。質問では、私は通知を含むリストについて言及しました。 user1が自分のステータスに友人やコメントとしてuser2を追加した場合、私の実装に適した普通のStringリストまたはモデルクラスリストであるuser2の通知リストに通知を追加する必要があります。そう、はい、それは即時にする必要があります。 –

+0

(私の英語は申し訳ありません)あなたは投票を使用したくないと思うので、サーバーはマッサージを放送し、各クライアントはフィルターをかけるか、サーバーはクライアントのアドレスを保存して特定のアドレスに送信する必要があります。あなたの問題を解決するためにプロをしましょう:) –

答えて

8

PrimeFacesプッシュは、プッシュする1つ以上のチャネルをサポートします。特定の理由でプライベートチャネルを作成できるようにするにはあなたの場合のようにユーザーごとに、複数のチャンネルを作成することができます。私はこの目的のためにユニークなIDを使用していました。

基本的に、私は、管理対象のBeanを実装しました。この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アノテーションを使用してチャネルを削除します。私のソリューションには、1つのユーザーセッションに1つのチャネルがあります。

私の提案は、ページでユーザー名を明示的に使用しないでください。セキュリティ上の理由から、それは良くありません。

+0

それは正しいと思われますが、私はまだパフォーマンスについてのいくつかの懸念を持っている、他の予防措置がありますか?ちなみにお返事ありがとうございます、あなたが想像しているように、私は、確かにケーキを取るよりも、賞金満期を待つつもりです。 –

+0

私はJSF自体のパフォーマンス上の懸念を認識しています。ユーザーのビューステートを保存することに偏った多くの人々がパフォーマンスを低下させます。しかし、それはたくさんの機能を提供しています。実際に自分自身でそれを味わいたいと思います。私がこれを行うときには、最大限のパフォーマンスを得るためにきれいに実装する必要があります。だからこそ私はこの質問をしてきたので、私は 'p:poll'を取り除きたいのです。 –

+0

@erencanはこのアプリケーションスコープのbeanです_thread safe_?複数の同時ユーザーがいるため、これに注意する必要があります。 – oko

関連する問題