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 发布代码实际上是正确的,不需要额外的斜杠。
我已经让 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 发布代码实际上是正确的,不需要额外的斜杠。