犯罪嫌疑人X
如果有人来这里从Java角度寻找解决方案:@Componentpublic class SocketHandler extends TextWebSocketHandler { public static Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { String userName = (String) session.getAttributes().get("userName"); sessions.put(userName, session); super.afterConnectionEstablished(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { String userName = (String) session.getAttributes().get("userName"); sessions.remove(userName); super.afterConnectionClosed(session, status); }}@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new SocketHandler(), "/webSocket/AppName/*").addInterceptors(auctionInterceptor());; } @Bean public HandshakeInterceptor auctionInterceptor() { return new HandshakeInterceptor() { public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // Get the URI segment corresponding to the auction id during handshake String path = request.getURI().getPath(); String userName = path.substring(path.lastIndexOf('/') + 1); // This will be added to the websocket session attributes.put("userName", userName); return true; } public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { // Nothing to do after handshake } }; }}以上是我在 Spring boot 中的 WebSocket 配置,因为我只想创建连接并将其保存在map用户名和会话详细信息中。之后在 Springboot main 方法中每 30 秒添加一次 ping,如下所示:public static void main(String[] args) { SpringApplication.run(MayAppName.class, args); ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); Runnable r = () -> { if(SocketHandler.sessions != null && !SocketHandler.sessions.isEmpty()) { for (Map.Entry<String, WebSocketSession> stringWebSocketSessionEntry : SocketHandler.sessions.entrySet()) { try { // Dummy ping to keep connection alive. stringWebSocketSessionEntry.getValue().sendMessage(new TextMessage("Dummy Ping")); } catch (IOException e) { e.printStackTrace(); } } } }; scheduler.scheduleAtFixedRate(r, 0, 30, TimeUnit.SECONDS);}这样做的作用是,它每 30 秒不断 ping 订阅者,以便默认55秒数不会影响 websocket 连接,如 Heroku 文档中所建议的那样。TimeoutsThe normal Heroku HTTP routing timeout rules apply to WebSocket connections. Either client or server can prevent the connection from idling by sending an occasional ping packet over the connection.