现在,我在Tomcat 7上运行了一个非常简单的WebSocket,仅发出了心跳信号。 它每30秒向每个会话发送一次ping,并在3次未击中后关闭会话。 我遇到的问题是服务器正确发送了第一个ping但之后没有发送任何ping。 用于发送实际ping的代码正在执行,但是从分析网络来看,没有发送ping。 它也不会抛出任何异常。 另外,我以前在Tomcat 9上运行它,但没有这个问题。

这是心跳的代码

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.websocket.PongMessage;
import javax.websocket.Session;

public class HeartbeatManager {

    private static final ByteBuffer DATA = ByteBuffer.wrap("heartbeat".getBytes());
    private static final long HEARTBEAT_DELAY_MS = 30 * 1000;
    private static final long MISSED_PONG_LIMIT = 3;

    private ScheduledExecutorService executor = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors());
    private Map<String, Heartbeat> sessionHeartbeats = new HashMap<String, Heartbeat>();

    public void start(Session session) {
        Heartbeat heartbeat = new Heartbeat(session);
        heartbeat.future = executor.scheduleAtFixedRate(heartbeat, HEARTBEAT_DELAY_MS, HEARTBEAT_DELAY_MS, TimeUnit.MILLISECONDS);
        Heartbeat oldHeartbeat = sessionHeartbeats.put(session.getId(), heartbeat);
        if (oldHeartbeat != null) {
            oldHeartbeat.future.cancel(true);
        }
    }

    public void stop(Session session) {
        Heartbeat heartbeat = sessionHeartbeats.remove(session.getId());
        if (heartbeat != null) {
            heartbeat.future.cancel(true);
        }
    }

    public void onPong(Session session, PongMessage message) {
        Heartbeat heartbeat = sessionHeartbeats.get(session.getId());
        if (heartbeat != null) {
            heartbeat.onPong(message);
        }
    }

    private class Heartbeat implements Runnable {

        private final Object LOCK = new Object();

        private ScheduledFuture<?> future;
        private Session session;
        private int missedPongs;
        private boolean pong = true;

        public Heartbeat(Session session) {
            this.session = session;
        }

        public void onPong(PongMessage message) {
            if (Arrays.equals(DATA.array(), message.getApplicationData().array())) {
                synchronized (LOCK) {
                    pong = true;
                    missedPongs = 0;
                }
            }
        }

        @Override
        public void run() {
            synchronized (LOCK) {
                if (!pong && ++missedPongs >= MISSED_PONG_LIMIT) {
                    try {
                        session.close();
                    } catch (IOException e) {
                    }
                } else {
                    pong = false;
                    try {
                        session.getBasicRemote().sendPing(DATA);
                    } catch (IOException e) {
                    }
                }
            }
        }

    }

}

如果有帮助,这里是ServerEndpoint

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

@ServerEndpoint(value = "/test")
public class Test {

    private static HeartbeatManager m = new HeartbeatManager();

    @OnOpen
    public void onOpen(Session session) {
        m.start(session);
    }

    @OnMessage
    public void onMessage(Session session, PongMessage message) {
        m.onPong(session, message);
    }

    @OnClose
    public void onClose(Session session) {
        m.stop(session);
    }

}

  ask by stripies translate from so

本文未有回复,本站智能推荐:

1回复

无法使用Tomcat和Maven的tomcat7-websocket插件启动WebSocket容器

我试图获得一个Tomcat服务器(7.0.54)来支持WebSocket并且很难部署它。 我有一个简单的终点: @ServerEndpoint(value = "/test") public class TestEndpoint { 为了处理这个端点,我需要包含一个容器(使用Ser
1回复

尝试访问WebSocket时收到错误404

我正在尝试为我的站点中的Web套接字设置一个简单的示例,但是尽管我阅读了很多类似的案例和教程,但我还是没有运气。 这是我在服务器上的配置 Java版本“ 1.8.0_191” 服务器版本:Apache Tomcat / 7.0.52(Ubuntu) 我在本地使用Net
1回复

在tomcat Websocket中向单个客户端发送消息

在tomcat-8示例中,我看到了使用HTML5 Web套接字进行聊天的示例。 代码如下所示 此代码向连接到服务器的所有客户端发送消息。 但是我只想向“ Guest1”发送消息。 我认为for循环必须更改。 如何仅向“ Guest1”发送消息。
2回复

如何部署Tomcat的示例websocket应用程序?

我正在尝试了解如何部署Apache Tomcat 7 WebSocket方法页面中引用的示例。 Application Development部分建议在WebSocketServlet类上读取javadoc。 但是看一下示例的服务器端代码,三个示例中的所有类都没有extend WebSo
4回复

WebSockets无法在Tomcat 7上运行

我在32位Windows XP以及64位Debian 6.0.5 Linux上安装了Apache Tomcat 7.0.29,并尝试使用websocket示例。 但它们运行不正常。 我甚至无法连接到服务器。 使用echo示例(选择消息API)并按下Connect按钮没有任何反应。 但
1回复

如何在Tomcat 7上实现Socket.io

我们有现有的应用程序托管在tomcat 6上,我们正在转向提供websockets支持的tomcat 7。 我想在我们的应用程序中尝试socket.io,以获得基于websockets的一些功能,因为它具有非常好的跨浏览器支持。 我在这个组合socket.io + tomcat上找不
1回复

无法远程运行tomcat Websocket示例

只要我的浏览器运行在与tomcat相同的计算机上,我就可以运行所有的websocket示例。 但是,一旦我尝试从远程计算机进行连接,连接总是会失败,并在Firebug控制台中显示以下错误。 要运行此功能是否需要额外的安全配置? 我正在使用7.052
1回复

Tomcat 7 Websocket未绑定

我有一个Java应用程式在本地(使用Tomcat 7.0.57和Intellij)上运作良好。 今天,我尝试在debian服务器上使用jenkins构建我的应用程序,除了websocket之外,我所有的应用程序都可以正常工作。 执行时出现404错误:new WebSocket(url)