WebSockets 在 Tomcat 7 上不起作用
Posted
技术标签:
【中文标题】WebSockets 在 Tomcat 7 上不起作用【英文标题】:WebSockets not working on Tomcat 7 【发布时间】:2012-08-31 14:27:19 【问题描述】:我在 32 位 Windows XP 和 64 位 Debian 6.0.5 Linux 上安装了 Apache Tomcat 7.0.29,并尝试使用 websocket 示例。但它们运行不正确。我什至无法连接到服务器。
使用 echo 示例(选择消息 API)并按下连接按钮没有任何反应。但 20 秒后,日志文本区域中出现“WebSocket 连接关闭”消息。但正如其他文章所述,这是一个已知问题。
在使用自制的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>
我不知道怎么做,但我希望对代码有所帮助。
塞巴斯蒂安
【问题讨论】:
请出示相关代码。听起来您的代码中某处可能存在阻塞读取。 代码主要是Tomcat 7附带的websocket示例的客户端部分。但是我为自己创建的测试应用程序添加了代码。希望这会有所帮助。 我的代码没有着色,我做错了什么? 您测试过哪些浏览器(供应商、版本和操作系统)? 我在 Mozilla Firefox 15.0.1、SRWare Iron 21.0.1200.0 (Chromium derivate) 和 Opera 12.02 上在 32 位 Win XP Pro SP3 上对其进行了测试。在 websocket 聊天示例中单击“连接”时,Opera 会立即打印“信息:WebSocket 连接已关闭”,而 Firefox 在 20 秒空闲超时后打印相同的消息。在终止服务器之前,Chrome 不会打印任何内容。 【参考方案1】:扩展 WebSocketServlet
现在已弃用,即使在 Tomcat 7 中也是如此。由于 Tomcat 7.0.47 提供了标准 javax.websocket-api
,这意味着您可以使用 @ServerEndpoint
轻松创建 websocket 端点在你的课上注释。 Make sure you set the dependency as provided.
尝试直接使用 Tomcat 启动,因为在 Apache 或 IIS 之后作为代理运行也会导致问题。
【讨论】:
你的答案是很久以前的......如今,他们甚至可以使用代理。 我稍微改写了一下。在尝试缩小问题原因时,仍然值得尝试直接连接。 直到今天我还没有遇到代理问题。即使在 docker 中,也没有问题。我不能说永远不会有问题,但现在,我没有。我正在使用这个 websockets 在后端离线时立即做出反应:)【参考方案2】:第一点,确保你的tomcat版本支持websocket。我建议使用 7.0.42 或更高版本。
第二个,你可以参考这个 sample code for websocket 开始。它的退出很简单。
【讨论】:
我认为 7.0.42 不支持 websockets。 tomcat7\lib\ 文件夹没有您在 7.0.52+ 中看到的任何 websocket jar。 tomcat-websocket.jar, websocket-api.jar【参考方案3】:到 \apache-tomcat-server-folder\lib\ 并复制 tomcat7-websocket.jar、websocket-api.jar 并粘贴到项目的构建路径中并删除所有以前的 websocket jar。
【讨论】:
【参考方案4】:我没有使用过 Apache Tomcat WebSocket 实现。但是,当我之前看到此类错误时,它通常表明客户端正在尝试连接到未启用 WebSocket 升级的常规 HTTP 服务器端点。这可能与您的 Tomcat 配置(web.xml)有关,而不是与服务器代码本身有关。
换句话说,您的客户端正在尝试连接到ws://localhost:8080/Testapp/websocket
,但您的服务器可能未配置为在该位置响应 WebSocket 升级。也许它实际上是ws://localhost:8080/websocket
或ws://localhost:8080/Testapp/websocket.do
。
【讨论】:
好的,我明白了。但它是 tomcat 下载附带的未更改的官方示例。查看此示例的 web.xml,EchoMessage 类(扩展 org.apache.catalina.websocket.WebSocketServlet)映射到 URL 模式“/websocket/echoMessage”。整个示例应用程序托管在上下文根“/examples”下。所以我认为这并没有什么问题。再说一次,到目前为止,有没有人运行过 tomcat websocket 示例?以上是关于WebSockets 在 Tomcat 7 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章
依赖注入在使用 Jersey 和 OpenWebBeans 的 Tomcat 7 上不起作用
带有cordova的Websockets在ipad上不起作用
Websockets 在 iOS 和 Safari 上不起作用 - OSStatus 错误 9837
在 Tomcat 7 中运行 Java EE 7 WebSockets
Zuul 代理在 Tomcat vai SpringBootServlet 上不起作用
使用 configureApplicationServer ANT 任务安装 WAR 文件在 Tomcat 上不起作用?