繁体   English   中英

Ping 未从 Tomcat WebSocket 发送

Ping not being sent from Tomcat WebSocket

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

现在,我在 Tomcat 7 上运行了一个非常简单的 WebSocket ,只有一个心跳。 它每 30 秒向每个 session 发送一个 ping,并在 3 个错过的乒乓球后关闭 session。 我遇到的问题是服务器正确发送了第一个 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);
    }

}
问题暂未有回复.您可以查看右边的相关问题.
1 从AspNetCore中的websocket无法ping

我正在尝试实现asp.net core的websocket,但发现我无法使服务器ping客户端以任何时间间隔进行确认。 浏览器从不注册任何ping帧。 出于测试目的,我基本上是在复制Microsoft的代码,因此我的代码类似于此演示: https : //docs.microsoft.c ...

3 Websocket-客户端应该发送ping帧吗?

顾名思义,应该仅从服务器发送Ping帧,还是最好由两个端点发送它们? 如Websocket RFC中所述: 注意:Ping帧可以用作保持活动状态... 因此,通过让一个端点发送ping请求,它应该保持连接打开,对不对? 上一行的第二部分是: 或作为一种方法来验 ...

5 无法通过 websocket 发送对象

所以我正在尝试使用 WebSocket 从客户端-&gt; 服务器和服务器-&gt; 客户端发送一个对象。 从客户端发送对象-&gt;服务器工作正常,同时服务器-&gt;客户端抛出异常 org.springframework.messaging.converter.MessageConvers ...

10 无法在tomcat 8上使用websocket打开连接

我有以下ServerEndpoint,无非就是测试: 现在,我正尝试使用Simple Websocket Client Chrome Extension与其连接,但它始终无法连接。 我认为这可能与我将Tomcat 8用作servlet容器有关。 我将此依赖项添加到了pom.xml ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM