Primefaces 推送给特定用户

Primefaces push to specific user

我已经让 Primefaces 推送成功地用于全局路径,但是我在使参数化路径工作时遇到了一些困难。这个想法是将 FacesMessages 推送给个人用户。

所以我的 index.xhtml:

<p:socket onMessage="handlePush" channel="/#{parliamentManager.user}" autoConnect="true" widgetVar="subscriber"/>

在 ParliamentManager 中,我获取用户并连接到频道:

@PostConstruct
    public void postInit() {
      logger.log(Level.INFO,"Session started");
      ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
      Map<String, Object> sessionMap = externalContext.getSessionMap();

      user = (User) sessionMap.get("user");
      logger.log(Level.INFO, "user trader is: {0}", 
              new Object[]{user.getTrader().getTraderId().toString()});

      RequestContext requestContext = RequestContext.getCurrentInstance();
      requestContext.execute("alert('PostConstruct')");
      requestContext.execute("PF('subscriber').connect('/" + user + "')");
    }

在发生验证的 RequestScoped Stateful bean 中,我尝试推送消息(目前使用硬编码用户):

if((book.getPrice() * bidOrder.getAmount()) > bidOrder.getTrader().getBalance())
        {
            EventBus eventBus = EventBusFactory.getDefault().eventBus();
            eventBus.publish("jimmy" , new FacesMessage("Error", "You have " + bidOrder.getTrader().getBalance() 
            + " and are trying to buy " + book.getPrice()*bidOrder.getAmount()));
            return;
        } 

但是我的 PushResource onMessage 从未被触发。我怀疑我在我的 pushresource 某处为参数或 eventBus.publish 消息使用了错误的语法,尽管我不确定它应该是什么:

推送资源:

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

private static final Logger logger = Logger.getLogger("politse.web.PushResource");

@PathParam("user")
private String user;

@OnMessage(decoders = JSONDecoder.class, encoders = JSONEncoder.class)
public void onMessage(RemoteEndpoint r, EventBus eventBus) {        
    logger.log(Level.INFO, "PushResource.onMessage user: {0}", 
            new Object[]{user});
}

}

在 eventBus.publish 中没有“/”的用户可能存在此问题

好吧,我在初始代码中犯了一些错误,当我将 onOpen 添加到我的资源对象并记录频道名称时,这些错误变得很明显。首先,我的套接字通道变量指向用户实体对象而不是用户 ID。所以我在 ParliamentManager 中将 userId 创建为字符串 属性。这创建了一个正确命名的频道。

<p:socket onMessage="handlePush" channel="/#{parliamentManager.userId}" autoConnect="true" widgetVar="subscriber"/>

此外,如果 autoConnect=true,我也不需要连接到频道,所以我从 ParliamentManager @PostConstruct 中删除了它。我的编码器也错了,我把它改成正确接受FacesMessage。

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

private static final Logger logger = Logger.getLogger("politse.web.PushResource");

@PathParam("user")
private String user;

@OnOpen
public void onOpen(RemoteEndpoint r, EventBus eventBus) {
    logger.log(Level.INFO, "PushResource.onOpen endpoint: {0}", 
            new Object[]{r});
}

@OnClose
public void onClose(RemoteEndpoint r, EventBus eventBus) {
    logger.log(Level.INFO, "PushResource.onClose endpoint: {0}", 
            new Object[]{r});
}

@OnMessage(encoders = {JSONEncoder.class})
public FacesMessage onMessage(FacesMessage message) {
    logger.log(Level.INFO, "PushResource.onMessage facesMessage");
    return message;
}

}

EventBus 发布代码实际上是正确的,不需要额外的斜杠。