Primefaces推送 - 仅限特定客户端

时间:2015-11-01 08:46:44

标签: jsf primefaces push

如何使用primefaces创建一些推送通知p:仅从我的数据库中推送ID = 1的实体? 更详细:我在我的数据库中有一个表"设备"。这意味着每次计算机/平板电脑连接到我的网络应用程序时,新设备都将存储在我的数据库中。 我还有一个设备的SessionBean。这意味着连接的设备知道"我是ID = 1"的设备。 现在我想只向ID = 1的设备发送推送通知 请问有人帮帮我吗?

非常感谢。

编辑: Bean类:NotifyResource和NotifyView

 @PushEndpoint("/{macAddress}")
@Singleton
public class NotifyResource {


    @PathParam(value = "macAddress")
    private String macAddress;


    @OnMessage(decoders = JSONDecoder.class, encoders = JSONEncoder.class)
    public void onMessage(RemoteEndpoint r, EventBus eventBus) {        
        System.out.println("pushing to " + macAddress);
    }


    @RequestScoped
  @RequestScoped
public class NotifyView {

    @Inject
    private DeviceBean deviceBean;


    public void send() {    
        EventBus eventBus = EventBusFactory.getDefault().eventBus();
        String macAddress = deviceBean.getDevice().getMacAddress();
        byte[]   bytesEncoded = Base64.encodeBase64(macAddress .getBytes());

        eventBus.publish("/" + new String(bytesEncoded), new FacesMessage("Test", "Tasasas"));        

    }
}

JSF PAGE

<p:growl widgetVar="growl" showDetail="true" />
    <p:socket onMessage="handleMessage" channel="/#{deviceBean.device.macAddress}" autoConnect="true" widgetVar='subscriber'/>

    <script type="text/javascript">
    function handleMessage(facesmessage) {
        facesmessage.severity = 'info';


    PF('growl').show([facesmessage]);
}

1 个答案:

答案 0 :(得分:1)

您实际上可以在推送端点上定义占位符。一般来说,您始终可以将多个用户放在一个推送组中。通过将每个用户放在“/ anything / hisOwnId”组中,您确保每个用户都有自己的频道,因为该ID是唯一的......

@PushEndpoint("{macAddress}")
@Singleton
public class PushResource
{

    @PathParam(value = "macAddress")
    private String macAddress;


    @OnMessage(decoders = JSONDecoder.class, encoders = JSONEncoder.class)
    public void onMessage(RemoteEndpoint r, EventBus eventBus) {        
        System.out.println("pushing to " + macAddress);
    }

    ....
}

在您的xhtml中,您定义了p:socket,在这种情况下,我将其设置为不自动连接。

要连接到特定频道,可以使用以下JavaScript命令:

PF('subscriber').connect('/5') /* Id 5 */

使用PrimeFaces,您还可以使用RequestContext.getCurrentInstance().execute("command");

从支持bean执行JavaScript命令

您也可以自动连接,但您必须确保用户已登录,才能检索ID。

<!-- Not sure, if there has to be a forward slash in the beginning -->
<p:socket onMessage="handleMessage" channel="#{currentUser.id}" autoConnect="true" widgetVar='subscriber' />

<script type="text/javascript">
    function handleMessage(msg) {
      alert('received push');
    }
</script>

将消息推送到特定频道(您的情况下是用户ID)

private final EventBus eventBus = EventBusFactory.getDefault().eventBus();

// Send message to specific path (Id equals 5)
eventBus.publish("5", pushMessage);

// Send global push message
eventBus.publish(pushMessage);

我还在web.xml中添加了以下条目

<servlet> 
<servlet-name>PrimePushServlet</servlet-name> 
<servlet-class>org.primefaces.push.PushServlet</servlet-class> 
<init-param> 
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name> 
<param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value> 
</init-param> 
<init-param> 
<param-name>org.atmosphere.util.IOUtils.readGetBody</param-name> 
<param-value>true</param-value> 
</init-param> 
<load-on-startup>1</load-on-startup> 
<async-supported>true</async-supported> 
</servlet> 
<servlet-mapping> 
<servlet-name>PrimePushServlet</servlet-name> 
<url-pattern>/primepush/*</url-pattern> 
</servlet-mapping>

您还可以查看PrimeFaces Chat Example。该应用程序使用聊天室作为路径。多个用户可以在一个聊天室中,因此该特定频道内的所有用户都会收到推送消息。

传递自定义实体

要传递自定义实体,而不仅仅是简单的Strings或FacesMessages,您必须编写自己的编码器/解码器类。

public class PushMessageDecoder implements Decoder<String, YourEntity>
{

    @Override
    public PushMessage decode(String s)
    {
        return (YourEntity) new JSONDecoder().decode(s);
    }
}

public class PushMessageEncoder implements Encoder<YourEntity, String>
{
    @Override
    public String encode(YourEntity message)
    {
        return new JSONObject(message).toString();
    }
}

在推送端点中,您必须在@OnMessage注释中指定自定义编码器/解码器。

@OnMessage(decoders = { PushMessageDecoder.class }, encoders = { PushMessageEncoder.class })

验证推送

如果推送端点按预期工作,您可以非常轻松地验证。

将消息推送到给定的频道,即

// 56156498494 is the mac address (not sure if special characters work in the path, you may have to encode the mac address).
eventBus.publish("/56156498494", pushMessage);

现在,只需在推送端点中的@onMessage函数中设置断点或制作system.out。您可以查看使用@PathParam注释的变量,并验证该变量的值实际上是您要将消息推送到的通道。

要验证客户端handleMessage函数是否正常工作并且实际上正在检索推送消息,只需在handleMessage函数中添加alert('foo');