Websocket总是抛出异常并在端口8080上关闭Tomcat

时间:2017-04-27 08:58:46

标签: java eclipse tomcat websocket

我想在webapp中使用WebSocket。我正在使用Eclipse(Mars.2版本4.5.2)来运行Tomcat 7.0.77实例。它在部署到独立的Tomcat实例时有效,但在Tomcat在Eclipse中运行时则无效。

我也尝试过Tomcat 8.0.43,结果相同。

在Eclipse中,当onMessage方法调用sendText方法时,总是抛出java.net.SocketException,并显示消息“Connection reset by peer:socket write error”,并且调用浏览器的onclose函数。

我有一个基本的终点:

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/echo")
public class EchoServer {

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("onOpen: " + session.getId());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("onMessage: " + session.getId() + ", " + message);
        try {
            session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("onClose: " + session.getId());
    }
}

和一个简单的测试用户界面:

<!DOCTYPE html>
<html>
    <head>
        <title>WebSocket test</title>
        <script type="text/javascript">

            var Example = {

                socket: undefined,

                open: function() {

                    this.socket = new WebSocket("ws://" + window.location.host + "/echo/echo");

                    this.socket.onopen = function() {
                        console.log("onopen");
                    };

                    this.socket.onmessage = function(e) {
                        document.getElementById("message").innerText = e.data;
                    };

                    this.socket.onclose = function() {
                        console.log("onclose");
                    };

                },

                send: function(message) {
                    this.socket.send(message);
                }
            }

            Example.open();

        </script>
    </head>
    <body>
        <div id="message"></div>
        <button onclick="Example.send('Hello world')">Send</button>
    </body>
</html>

单击UI按钮时,消息将发送到端点。然后,端点使用getBasicRemote().sendText(message)将消息发送回UI。

在Eclipse中,Tomcat会抛出以下异常:

java.io.IOException: java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset by peer: socket write error
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:286)
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:572)
at org.apache.tomcat.websocket.WsSession.doClose(WsSession.java:466)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.onError(WsHttpUpgradeHandler.java:161)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.access$300(WsHttpUpgradeHandler.java:47)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onError(WsHttpUpgradeHandler.java:225)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:208)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:203)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:93)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:635)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset by peer: socket write error
at org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:120)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:281)
... 14 more
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
at org.apache.coyote.http11.upgrade.BioServletOutputStream.doWrite(BioServletOutputStream.java:38)
at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.writeInternal(AbstractServletOutputStream.java:153)
at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.write(AbstractServletOutputStream.java:121)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:94)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:456)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:344)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:276)
... 14 more

然后立即关闭WebSocket,并触发onClose。我使用的是Chrome 57和MS Edge 38。

这是一个已知的Eclipse问题,还是我的测试代码做了一些愚蠢的事情?感谢。

更新

这不是Eclipse问题。当它们在端口8080上运行时,它发生在包含Eclipse的Tomcat和独立的Tomcat中。如果我更改端口(我使用7777),那么它可以工作。我已经改变了这个问题的标题以反映这一点。

更新

看起来这是一个阻止端口80和8080上的WebSockets的防火墙/代理问题。抱歉,这不是问题。

0 个答案:

没有答案