由于PrimeFaces推送将被终止,因此我开始迁移到OmniFaces推送。出于通知目的,它都按预期工作,但是我在应用程序上聊天时发现OmniFaces中缺少两件事:
1)根据需要更改套接字的用户。我需要私人对话。在PrimeFaces上,我基于记录的用户ID为每个对话创建一个通道,并将其传递给其套接字组件的connect方法。使用OmniFaces,我试图将套接字组件放置在PrimeFaces输出面板中,将用户属性绑定到视图作用域的bean,在ajax请求和oncomplete事件调用OmniFaces.Push.open('channelName')上更新面板,但是我可以在SocketObserver类上(从展示柜中看到)尚未更新用户。作为一种解决方法,我使用登录的用户ID作为用户创建了频道,并且如果与当前正在讲话的人不同的人发送了一条消息,我将在JavaScript回调中忽略该消息,而不是附加它。
2)当我未在PushContext.send上指定用户时,我希望将消息发送给通道上连接的每个人,类似于PrimeFaces上的“ / channel / *”。我对此的要求是更新此聊天应用程序的在线/离线用户列表。一种解决方法是,我可以为这些通知创建一个单独的通道,但是由于该应用程序不需要此通知,我更喜欢先在此处进行检查。
如有必要,我将添加代码,但首先,我想检查OmniFaces推送中是否存在这些概念。
谢谢
答案 0 :(得分:2)
在相同的JSF视图(ajax更新等)中,确实不可能更改<o:socket user="#{...}">
的值。根据{{3}},在OmniFaces 3.2-SNAPSHOT中已对其进行了改进。
在同一JSF视图中的任何ajax请求期间,<o:socket user="#{...}">
的任何动态值变化现在都将反映在推送行为中。
换句话说,现在可以进行以下构造:
<h:form>
<h:selectOneMenu value="#{bean.chat}">
<f:selectItems value="#{bean.chats}" />
<f:ajax render="@form" />
<h:selectOneMenu>
...
<o:socket channel="chat" user="#{bean.chat.id}" />
</h:form>
答案 1 :(得分:1)
如果像示例中那样,首先在user
上使用o:socket
属性
<o:socket channel="sess" scope="session" user="#{pushTestUser}" />
1)可以通过使用“用户ID”来实现,如展示柜push test page
所示。来自http://showcase.omnifaces.org/push/socket:
@Inject @Push
private PushContext someChannel;
public void sendMessage(Object message, User recipientUser) {
Long recipientUserId = recipientUser.getId();
someChannel.send(message, recipientUserId);
}
在此示例中,传递User
,这是一个“示例”对象,可以是您自己的对象,也可以是其他任何对象。在展示厅中,通过将id绑定到输入字段来传递用户,但是这也可以在服务器端完成。由你决定
2)似乎可以通过向通用频道甚至组发送消息来实现,如http://showcase.omnifaces.org/push/socket所示。
@Inject @Push
private PushContext someChannel;
public void sendMessage(Object message, Group recipientGroup) {
Collection<Long> recipientUserIds = recipientGroup.getUserIds();
someChannel.send(message, recipientUserIds);
}
这里的组是一个示例对象,它可以是您自己的,可以从“前端”传递,也可以在后端的某个地方读取。它只需要包含已订阅频道的用户ID(可以映射为GUID,而不必是内部用户ID)。所有只是示例方法。
所以我认为两者似乎都是可能的。