WebSockets无法在Tomcat 7上运行

时间:2012-08-31 14:27:20

标签: tomcat websocket tomcat7

我在32位Windows XP以及64位Debian 6.0.5 Linux上安装了Apache Tomcat 7.0.29,并尝试使用websocket示例。但它们运行不正常。我甚至无法连接到服务器。

使用echo示例(选择消息API)并按下“连接”按钮没有任何反应。但是在20秒后,日志文本区域中出现“WebSocket connection closed”消息。但正如其他文章所述,这是一个众所周知的问题。

当使用自制的websocket应用程序并尝试连接到服务器时,我注意到打印了MessageInbound#onOpen方法的日志语句,因此调用了此方法。但是,浏览器Javascript部分中的onopen回调没有触发。但是在终止tomcat实例之后,会立即调用onopen客户端,然后紧跟onclose。

有没有人可以证实这个或类似的行为?或者有没有人在Tomcat 7上使用websocket示例?谢谢你的帮助。

更新:我为自己创建的示例应用程序添加了代码。

这是服务器部分,WebSocketTestServlet.java:

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;

@WebServlet(value = "/websocket", loadOnStartup = 1)
public class WebSocketTestServlet extends WebSocketServlet
{
    private static final long serialVersionUID = 1L;

    @Override
    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request)
    {
        return new WebSocketTestInbound();
    }

    public static final class WebSocketTestInbound extends MessageInbound
    {
        @Override
        protected void onOpen(WsOutbound outbound)
        {
            System.out.println("WebSocketTestServlet#onOpen");
        }

        @Override
        protected void onClose(int status)
        {
            System.out.println("WebSocketTestServlet#onClose");
        }

        @Override
        protected void onBinaryMessage(ByteBuffer message) throws IOException
        {
            System.out.println("WebSocketTestServlet#onBinaryMessage received: " + message);
        }

        @Override
        protected void onTextMessage(CharBuffer message) throws IOException
        {           
            System.out.println("WebSocketTestServlet#onTextMessage received: " + message);
        }
    }
}

这里是唯一的JSF facelet main.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <title>Test suite</title>
        <script type="text/javascript">

        var ws = null;

        function connect()
        {
            var wsUrl = $('#id_wsUrl');
            var wsMsg = $('#id_wsMsg');
            var wsSnd = $('#id_wsSnd');
            var wsCon = $('#id_wsCon');
            var url = wsUrl.val();

            // Connect
            if (ws == null)
            {
                if (window.WebSocket)
                    ws = new WebSocket(url);
                else if (window.MozWebSocket)
                    ws = new MozWebSocket(url);
                else
                {
                    alert('WebSocket not supported by this browser');
                    return;
                }

                ws.onopen = function()
                {
                    alert('Connection opened!');
                    wsMsg.removeAttr('disabled');
                    wsSnd.removeAttr('disabled');
                    wsUrl.attr('disabled', 'disabled');
                    wsCon.val('Disconnect');
                };

                ws.onclose = function()
                {
                    alert('Connection closed!');
                    wsMsg.attr('disabled', 'disabled');
                    wsSnd.attr('disabled', 'disabled');
                    wsUrl.removeAttr('disabled');
                    wsCon.val('Connect');
                };

                ws.onmessage = function(event)
                {
                    console.log('Inbound message: ' + event.data);
                    alert('Inbound message: ' + event.data);
                };

                ws.onerror = function()
                {
                    alert('Connection error!!!');
                };
            }
            // Disconnect
            else
            {
                ws.close();
                ws = null;
            }
        }

        function sendMessage()
        {
            if (ws)
            {
                var wsMsg = $('#id_wsMsg');
                var data = wsMsg.val();
                wsMsg.val('');

                if (data.length > 0)
                    ws.send(data);
            }
        }

        </script>
    </h:head>
    <h:outputScript target="head" library="js" name="jquery-1.8.0.js" />
    <h:body>
        <h1>WebSocket tests</h1>
        <h:panelGrid columns="2">
            <h:outputLabel for="id_wsUrl" value="WebSocket server URL:" />
            <h:panelGroup>
                <h:inputText id="id_wsUrl" style="width: 250px;" value="ws://localhost:8080/Testapp/websocket" />
                <h:commandButton type="button" id="id_wsCon" value="Connect" onclick="connect();" />
            </h:panelGroup>
            <h:outputLabel for="id_wsMsg" value="WebSocket outbound message" />
            <h:panelGroup>
                <h:inputText id="id_wsMsg" style="width: 250px;" value="" disabled="true" />
                <h:commandButton type="button" id="id_wsSnd" value="Send" disabled="true" onclick="sendMessage();" />
            </h:panelGroup>
        </h:panelGrid>
    </h:body>
</html>

我不知道怎么做,但我希望它有助于编写代码。

塞巴斯蒂安

4 个答案:

答案 0 :(得分:10)

现在不推荐使用WebSocketServlet,即使在Tomcat 7中也是如此。由于Tomcat 7.0.47 ,提供了标准javax.websocket-api,这意味着您可以使用以下方法轻松创建websocket端点你班上的@ServerEndpoint注释。 Make sure you set the dependency as provided

尝试直接命中Tomcat以在Apache或IIS后面运行作为代理也会导致问题。

答案 1 :(得分:1)

首先,确保您的tomcat版本支持websocket。我建议使用7.0.42或更高版本。

比秒,您可以参考 sample code for websocket 开始使用。它退出了简单。

答案 2 :(得分:1)

转到\ apache-tomcat- server-folder \ lib \,然后复制tomcat7-websocket.jar,websocket-api.jar并粘贴到项目的构建路径中,并删除所有以前的websocket jar。

答案 3 :(得分:0)

我没有使用Apache Tomcat WebSocket实现。但是,当我看到此类错误之前,它经常表明客户端正在尝试连接到未启用WebSocket升级的常规HTTP服务器端点。对于Tomcat配置(web.xml)而言,这可能需要比使用服务器代码本身做得更多。

换句话说,您的客户端正在尝试连接到ws://localhost:8080/Testapp/websocket,但您的服务器可能未配置为在该位置应答WebSocket升级。也许它实际上是ws://localhost:8080/websocketws://localhost:8080/Testapp/websocket.do