Android 和 Java Ping/Pong Web 套接字功能
Android and Java Ping/Pong Web Socket functionality
我开发了 Android 应用程序,它正在连接到 JAVA Web Socket,基本上它运行良好。
问题是,有时客户端会断开连接,但服务器端的连接似乎已连接。
我尝试调查它发生的时间和原因,但遗憾的是我找不到导致此问题的具体情况。
我想在服务器和所有客户端之间实现 Ping/Pong 消息传递,如果客户端没有应答,则关闭服务器端的连接。
我可以很容易地实现这样的私有机制,但我已经阅读过,我知道 Java 和 Android 有一个内置的 Ping/Pong 消息传递机制,但我无法找到任何例子。
无论如何,能否提供一个简单示例,说明如何使用内置工具实现 Ping/Pong 消息传递功能?
我已成功在 EE JAVA WebSocket 和 android 应用程序之间实现 Ping/Pong 功能。服务器每 5 分钟向客户端发送一次 Ping 消息。如果服务器在 5 秒内没有收到 Pong 消息,服务器将关闭客户端连接。
如果有人需要,这是我的解决方案:
WebSocket 端:
public class User {
public ScheduledExecutorService pingExecutorService;
public Timer disconnectTimer;
private Session userSession;
private String userName;
public User(Session userSession) {
this.userSession = userSession;
}
public Session getUserSession() {
return userSession;
}
public void setUserSession(Session userSession) {
this.userSession = userSession;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@OnOpen
public void onOpen(Session session) {
User newUserConnection = new User(session);
connections.getConnections().put(session.getId(), newUserConnection);
schedulePingMessages(newUserConnection);
}
@OnClose
public void onClose(Session session) {
handleOnClose(session);
}
@OnMessage
public void onMessage(String message, Session session) {
messageHandler.handleMessage(message, session);
}
@OnMessage
public void onPong(PongMessage pongMessage, Session session) {
String sourceSessionId = session.getId();
User user = connections.getConnections().get(sourceSessionId);
user.disconnectTimer.cancel();
user.disconnectTimer.purge();
}
@OnError
public void onError(Throwable t) {
System.out.println(new Date() + "onError::" + t.getMessage());
t.printStackTrace();
}
private void schedulePingMessages(User newUserConnection) {
newUserConnection.pingExecutorService = Executors.newScheduledThreadPool(1);
newUserConnection.pingExecutorService.scheduleAtFixedRate(() -> {
scheduleDiconnection(newUserConnection);
try {
String data = "Ping";
ByteBuffer payload = ByteBuffer.wrap(data.getBytes());
newUserConnection.getUserSession().getBasicRemote().sendPing(payload);
} catch (IOException e) {
e.printStackTrace();
}
}, 300, 300, TimeUnit.SECONDS);
}
private void scheduleDiconnection(User user) {
user.disconnectTimer = new Timer();
user.disconnectTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
user.getUserSession().close(new CloseReason(CloseCodes.UNEXPECTED_CONDITION," Client does not response"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
}
android端只需要添加如下覆盖方法:
@Override
public void onWebsocketPing(WebSocket conn, Framedata f) {
Log.i("ZCF","got Ping !");
super.onWebsocketPing(conn, f);
}
我开发了 Android 应用程序,它正在连接到 JAVA Web Socket,基本上它运行良好。 问题是,有时客户端会断开连接,但服务器端的连接似乎已连接。
我尝试调查它发生的时间和原因,但遗憾的是我找不到导致此问题的具体情况。
我想在服务器和所有客户端之间实现 Ping/Pong 消息传递,如果客户端没有应答,则关闭服务器端的连接。
我可以很容易地实现这样的私有机制,但我已经阅读过,我知道 Java 和 Android 有一个内置的 Ping/Pong 消息传递机制,但我无法找到任何例子。
无论如何,能否提供一个简单示例,说明如何使用内置工具实现 Ping/Pong 消息传递功能?
我已成功在 EE JAVA WebSocket 和 android 应用程序之间实现 Ping/Pong 功能。服务器每 5 分钟向客户端发送一次 Ping 消息。如果服务器在 5 秒内没有收到 Pong 消息,服务器将关闭客户端连接。
如果有人需要,这是我的解决方案:
WebSocket 端:
public class User {
public ScheduledExecutorService pingExecutorService;
public Timer disconnectTimer;
private Session userSession;
private String userName;
public User(Session userSession) {
this.userSession = userSession;
}
public Session getUserSession() {
return userSession;
}
public void setUserSession(Session userSession) {
this.userSession = userSession;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
@OnOpen
public void onOpen(Session session) {
User newUserConnection = new User(session);
connections.getConnections().put(session.getId(), newUserConnection);
schedulePingMessages(newUserConnection);
}
@OnClose
public void onClose(Session session) {
handleOnClose(session);
}
@OnMessage
public void onMessage(String message, Session session) {
messageHandler.handleMessage(message, session);
}
@OnMessage
public void onPong(PongMessage pongMessage, Session session) {
String sourceSessionId = session.getId();
User user = connections.getConnections().get(sourceSessionId);
user.disconnectTimer.cancel();
user.disconnectTimer.purge();
}
@OnError
public void onError(Throwable t) {
System.out.println(new Date() + "onError::" + t.getMessage());
t.printStackTrace();
}
private void schedulePingMessages(User newUserConnection) {
newUserConnection.pingExecutorService = Executors.newScheduledThreadPool(1);
newUserConnection.pingExecutorService.scheduleAtFixedRate(() -> {
scheduleDiconnection(newUserConnection);
try {
String data = "Ping";
ByteBuffer payload = ByteBuffer.wrap(data.getBytes());
newUserConnection.getUserSession().getBasicRemote().sendPing(payload);
} catch (IOException e) {
e.printStackTrace();
}
}, 300, 300, TimeUnit.SECONDS);
}
private void scheduleDiconnection(User user) {
user.disconnectTimer = new Timer();
user.disconnectTimer.schedule(new TimerTask() {
@Override
public void run() {
try {
user.getUserSession().close(new CloseReason(CloseCodes.UNEXPECTED_CONDITION," Client does not response"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 5000);
}
android端只需要添加如下覆盖方法:
@Override
public void onWebsocketPing(WebSocket conn, Framedata f) {
Log.i("ZCF","got Ping !");
super.onWebsocketPing(conn, f);
}