Primefaces Push не может получить динамический путь к работе
Это работает:
Фрагмент сниппета:
<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:
@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>
Бин, который подключается через идентификатор сессии:
@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:
@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]
PS Я установил точки останова, чтобы гарантировать, что идентификатор сеанса в
"PF('subscriber').connect('/redirectMonitoring/" + WebUtil.getSession().getId() + "')"
соответствует идентификатору сеанса в
eventBus.publish("/redirectMonitoring/" + sessionId, "/foo.xhtml");
Любые предложения / указатели / советы будут с благодарностью!
ОБНОВИТЬ:
Я использую PrimeFaces 5.2 + Atmosphere 2.3.4.
Я изменил p:socket
в autoConnect="true"
но это не помогло.
Вот что я вижу через консоль браузера / вкладку сети, когда браузер делает запрос к веб-приложению:
https://localhost:8443/app/primepush/redirectMonitoring/%7BsessionId%7D?X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=5f40ca65-0ab0-4c4c-ab58-7b9b790eb78f&_=1440535767013
Тем не менее, когда веб-приложение пытается отправить сообщение в веб-браузер через /redirectMonitoring
конечная точка Я не вижу активности на консоли / вкладке сети.
Вот еще один ключ:
Когда я устанавливаю точку останова на 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 ответ
Решением было изменить атрибут канала p:socket следующим образом:
<p:socket channel="/redirectMonitoring/{sessionId}" ... />
к этому:
<p:socket channel="/redirectMonitoring/#{session.id}" ... />