Notification system with p:poll/push

前端 未结 1 1753
执念已碎
执念已碎 2020-12-05 08:30

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

相关标签:
1条回答
  • 2020-12-05 09:05

    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.

    0 讨论(0)
提交回复
热议问题