WebSockets 不适用于 Tomcat 7 [英] WebSockets not working on Tomcat 7

查看:23
本文介绍了WebSockets 不适用于 Tomcat 7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 32 位 Windows XP 和 64 位 Debian 6.0.5 Linux 上安装了 Apache Tomcat 7.0.29,并尝试使用 websocket 示例.但是它们没有正确运行.我什至无法连接到服务器.

I installed Apache Tomcat 7.0.29 on 32bit Windows XP as well as on 64bit Debian 6.0.5 Linux and tried using the websocket examples. But they are not running correctly. I'm not even able to connect to the server.

使用 echo 示例(选择消息 API)并按下连接按钮没有任何反应.但是 20 秒后,日志文本区域中会出现消息WebSocket 连接已关闭".但正如其他文章所述,这是一个已知问题.

Using the echo example (choosing messages API) and pressing the Connect button nothing happens. But after 20sec the message "WebSocket connection closed" appears in the log textarea. But as other articles state, this is a known issue.

在使用自制的websocket应用并尝试连接服务器时,我注意到MessageInbound#onOpen方法的日志语句被打印出来,因此调用了该方法.但是,浏览器 Javascript 部分中的 onopen 回调没有触发.但是在终止 tomcat 实例之后,客户端直接调用 onopen,紧接着是 onclose.

When using a self-made websocket application and trying to connect to the server, I noticed that the log statements of the MessageInbound#onOpen method are printed, hence this method is called. However, the onopen callback in the browsers Javascript part is not firing. But directly after terminating the tomcat instance, the clients onopen is called, immediately followed by an onclose.

有没有人可以证实这一点或类似的行为?或者有没有人在 Tomcat 7 上使用过 websocket 示例?感谢您的帮助.

Is there anybody who can confirm this or a similar behavior? Or has anyone got the websocket examples working on Tomcat 7? Thanks for any help.

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

Update: I added the code for my self created sample application.

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

Here is the server part, the 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:

And here the one and only 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>

我不知道怎么做,但我希望它有助于获得代码.

I don't know how, but I hope it helps having the code.

塞巴斯蒂安

推荐答案

extending WebSocketServlet 现在已弃用,即使在 Tomcat 7 中也是如此.由于 Tomcat 7.0.47 标准 <提供了 code>javax.websocket-api 这意味着您可以通过在类上使用 @ServerEndpoint 注释轻松创建 websocket 端点.确保按照提供的方式设置依赖项.

extending WebSocketServlet is now deprecated, even in Tomcat 7. Since Tomcat 7.0.47 the standard javax.websocket-api is provided which means you can easily create a websocket endpoint by using the @ServerEndpoint annotation on your class. Make sure you set the dependency as provided.

尝试直接使用 Tomcat 开始,因为在 Apache 或 IIS 后面作为代理运行也会导致问题.

Try hitting Tomcat directly to start with as running behind Apache or IIS as a proxy can also cause problems.

这篇关于WebSockets 不适用于 Tomcat 7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆