Primefaces Push无法获得动态路径

时间:2015-08-25 14:28:42

标签: primefaces push atmosphere

这有效:

Facelet代码段:

<p:socket channel="/redirectMonitoring">
    <p:ajax event="message" oncomplete="window.location.replace('/foo.xhtml')" />
</p:socket>

资源:

@PushEndpoint("/redirectMonitoring")
@Singleton
public class RedirectMonitorResource {
    @OnMessage() public void onMessage(Boolean ignore) {}
}

CDI bean:

@Model
public class RedirectBean {
    public void redirect() {
        EventBus eventBus = EventBusFactory.getDefault().eventBus();
        eventBus.publish("/redirectMonitoring", Boolean.TRUE);
    }
}

但是当我尝试使路径动态如下:

的facelet:

<p:socket onMessage="handleMessage" channel="/redirectMonitoring/{sessionId}" autoConnect="false" widgetVar='subscriber'/>
<script type="text/javascript">
    function handleMessage(message) {
        window.location.replace(message);
    }
</script>

通过会话ID连接的Bean:

@Model
public class LoginController {
    private void onLogin(@Observes @LoggedIn User loggedInUser) {
        RequestContext.getCurrentInstance().execute(
            "PF('subscriber').connect('/redirectMonitoring/" + WebUtil.getSession().getId() + "')");
    }
}

资源:

@PushEndpoint("/redirectMonitoring/{sessionId}")
@Singleton
public class RedirectMonitorResource {
    @PathParam("sessionId") private String sessionId;

    @OnMessage(encoders = {JSONEncoder.class}) public String onMessage(String message) { return message; }
}

CDI bean:

@Model
public class RedirectBean {
    public void redirect(String sessionId) {
        EventBus eventBus = EventBusFactory.getDefault().eventBus();
        eventBus.publish("/redirectMonitoring/" + sessionId, "/foo.xhtml");
    }
}

网页浏览器没有加载/foo.xhtml,我在日志中收到以下错误:

20:12:24,811 ERROR [org.atmosphere.container.JSR356Endpoint] (default I/O-5) : java.io.IOException: An existing connection was forcibly closed by the remote host
    at sun.nio.ch.SocketDispatcher.read0(Native Method) [rt.jar:1.8.0_05]
    at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43) [rt.jar:1.8.0_05]
    at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223) [rt.jar:1.8.0_05]
    at sun.nio.ch.IOUtil.read(IOUtil.java:192) [rt.jar:1.8.0_05]
    at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:375) [rt.jar:1.8.0_05]
    at org.xnio.nio.NioSocketConduit.read(NioSocketConduit.java:280) [xnio-nio-3.2.2.Final.jar:3.2.2.Final]
    at org.xnio.conduits.AbstractStreamSourceConduit.read(AbstractStreamSourceConduit.java:51) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at org.xnio.ssl.JsseSslStreamSourceConduit.read(JsseSslStreamSourceConduit.java:84) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at io.undertow.conduits.IdleTimeoutConduit.read(IdleTimeoutConduit.java:144)
    at org.xnio.conduits.ConduitStreamSourceChannel.read(ConduitStreamSourceChannel.java:127) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at io.undertow.server.protocol.framed.AbstractFramedChannel.receive(AbstractFramedChannel.java:244)
    at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:20)
    at io.undertow.websockets.core.AbstractReceiveListener.handleEvent(AbstractReceiveListener.java:15)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:632)
    at io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener.handleEvent(AbstractFramedChannel.java:618)
    at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66) [xnio-api-3.2.2.Final.jar:3.2.2.Final]
    at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:87) [xnio-nio-3.2.2.Final.jar:3.2.2.Final]
    at org.xnio.nio.WorkerThread.run(WorkerThread.java:539) [xnio-nio-3.2.2.Final.jar:3.2.2.Final]

P.S。我确实设置了断点以确保会话ID在

"PF('subscriber').connect('/redirectMonitoring/" + WebUtil.getSession().getId() + "')"

匹配

中的会话ID
eventBus.publish("/redirectMonitoring/" + sessionId, "/foo.xhtml");

非常感谢任何建议/指示/建议!

更新:

我正在使用PrimeFaces 5.2 + Atmosphere 2.3.4。

我确实将p:socket更改为autoConnect="true",但这样做并没有帮助。

以下是我在浏览器针对Web应用程序发出请求时通过浏览器控制台/网络选项卡看到的内容:

https://localhost:8443/app/primepush/redirectMonitoring/%7BsessionId%7D?X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=5f40ca65-0ab0-4c4c-ab58-7b9b790eb78f&_=1440535767013

Browser console/network tab

但是,当Web应用程序尝试通过/redirectMonitoring端点向Web浏览器发送消息时,我在控制台/网络选项卡上看不到任何活动。

这是另一条线索:

当我在静态路径版本的RedirectMonitorResource#onMessage中设置断点时,会在调试会话中触发断点:

@PushEndpoint("/redirectMonitoring")
@Singleton
public class RedirectMonitorResource {
    @OnMessage() 
    public void onMessage(Boolean ignore) {} // <-- breakpoint here is triggered
}

但是,当我在动态路径版本中设置断点时,断点被触发。 RedirectMonitorResource#onMessage不会在动态路径版本中调用:

@PushEndpoint("/redirectMonitoring/{sessionId}")
@Singleton
public class RedirectMonitorResource {
    @PathParam("sessionId") private String sessionId;

    @OnMessage(encoders = {JSONEncoder.class}) 
    public String onMessage(String message) { 
        return message;                          // <-- breakpoint here not triggered 
    } 
}

1 个答案:

答案 0 :(得分:0)

解决方案是改变p:socket channel属性:

<p:socket channel="/redirectMonitoring/{sessionId}" ... />

到此:

<p:socket channel="/redirectMonitoring/#{session.id}" ... />