为什么Omnifaces Websocket <o:socket>无法与Websphere 9一起使用?

时间:2019-01-16 21:20:27

标签: java websocket websphere omnifaces

我有一个基于Omniface套接字演示(http://showcase.omnifaces.org/push/socket)创建的测试应用,该应用的计数器在单击时递增,并且在Tomcat 8.5上运行,以某种方式将其部署到Webphere 9服务器时不起作用

在Websphere 9中,当我在浏览器中查看源代码时出现此错误。

<script type="text/javascript" id="j_id_h">Error 500: javax.servlet.ServletException: o:socket endpoint is not enabled. You need to set web.xml context param &#39;org.omnifaces.SOCKET_ENDPOINT_ENABLED&#39; with value &#39;true&#39;.

以上错误来自PushBean.xhtml中的<o:socket行:

<o:socket channel="counter" onmessage="updateCounter" onclose="onclosePush" connected="#{pushBean.connected}" />

我可以告诉<o:socket>标签不起作用,并且已经在web.xml中启用了套接字端点,请参见下面的web.xml文件。

Web.xml


    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>WebSocketServerJSFOmni</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      <context-param>
        <param-name>org.omnifaces.SOCKET_ENDPOINT_ENABLED</param-name>
        <param-value>true</param-value>
      </context-param>
      <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
      </servlet-mapping>
    </web-app>

PushBean.java

    package org.omnifaces.showcase.push;

    import java.io.Serializable;
    import java.util.concurrent.atomic.AtomicLong;

    import javax.inject.Inject;
    import javax.inject.Named;

    import org.omnifaces.cdi.Push;
    import org.omnifaces.cdi.PushContext;
    import org.omnifaces.cdi.ViewScoped;

    @Named
    @ViewScoped
    public class PushBean implements Serializable {

        private static AtomicLong counter = new AtomicLong();

        private boolean connected;

        @Inject @Push(channel="counter")
        private PushContext push;

        public void toggle() {
            connected = !connected;
        }

        public void increment() {
            long newvalue = counter.incrementAndGet();
            push.send(newvalue);
        }

        public boolean isConnected() {
            return connected;
        }

        public Long getCount() {
            return counter.get();
        }

    }

PushBean.xhtml


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:o="http://omnifaces.org/ui"
        xmlns:of="http://omnifaces.org/functions">

    <h:head>
    </h:head>

    <body>

        <h3>Global counter</h3>
        <p>
            Below is a static counter which has the same value application wide.
        </p>

        <h1><h:panelGroup id="count">#{pushBean.count}</h:panelGroup></h1>

        <h:form>
            <p>
                If you enable the push, then a websocket will be opened.
                Note that it's by default always auto-connected when included in the page, but for demo purposes we're initially disabling it.
            </p>
            <p>
                <h:panelGroup id="toggle">
                    Push is #{pushBean.connected ? 'connected' : 'disconnected'} 
                    <h:commandButton value="#{pushBean.connected ? 'disconnect' : 'connect'} it" action="#{pushBean.toggle}">
                        <f:ajax render="toggle increment :count"/>
                    </h:commandButton>
                </h:panelGroup>
            </p>
            <p>
                If push is connected and you press the "increment!" button, then the static counter will increment in bean and the push will send out the new value to the same channel in all connected clients.
                To see it yourself, open the same page in multiple tabs/windows/browsers/machines and trigger the push in only one of it.
                Note that the counter also won't increment from other side if push is still disconnected on current page.
            </p>
            <p>
                <h:commandButton id="increment" value="increment!" action="#{pushBean.increment}" disabled="#{not pushBean.connected}">
                    <f:ajax />
                </h:commandButton>
            </p>
        </h:form>


        <!-- NOTE: having inline script in XHTML like below is bad practice. -->
        <!-- It's included directly in XHTML just for sake of demo. -->
        <!-- In real world code, put it in a JS file :) -->

        <script>
            function updateCounter(newvalue) {
                //$("#count").text(newvalue);
                document.getElementById("count").innerHTML = newvalue;
            }

            function onclosePush(code) {
                if (code == -1) {
                    alert("Oops! Your browser doesn't seem to support web sockets. The push functionality won't work.")
                }
                else if (code != 1000) {
                    alert("Oops! Push has stopped working with error code " + code + "! Reload the page.")
                }
            }
        </script>

        <!-- End of bad practice ;) -->


        <o:socket channel="counter" onmessage="updateCounter" onclose="onclosePush" connected="#{pushBean.connected}" />


    </body>
    </html>

<o:socket>应该转换为在Websphere 9服务器上没有使用的JavaScript。

2 个答案:

答案 0 :(得分:0)

对于WAS 9,我必须在StartupServletContextListener之前在web.xml中显式注册侦听器。

https://github.com/omnifaces/omnifaces/issues/502

<listener>
        <listener-class>org.omnifaces.ApplicationListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>

答案 1 :(得分:0)

您需要将omnifaces.jar放在通用服务器库中,而不必将其放置在项目库中。

通过该操作,上下文首先在全指后开始

For more information check here