Java Smack 4.1.0 GCM CCS在一段时间后停止响应
已经为聊天模块实现了gcm ccs,我能够发送和接收消息。下面是主连接模块Java Smack 4.1.0 GCM CCS在一段时间后停止响应,java,google-cloud-messaging,smack,Java,Google Cloud Messaging,Smack,已经为聊天模块实现了gcm ccs,我能够发送和接收消息。下面是主连接模块 config = XMPPTCPConnectionConfiguration.builder() .setServiceName("gcm-pesu.googleapis.com") .setPort(GCM_PORT) .setHost(GCM_SERVER) .setCom
config = XMPPTCPConnectionConfiguration.builder()
.setServiceName("gcm-pesu.googleapis.com")
.setPort(GCM_PORT)
.setHost(GCM_SERVER)
.setCompressionEnabled(false)
.setConnectTimeout(30000)
.setSecurityMode(SecurityMode.ifpossible)
.setSendPresence(false)
.setSocketFactory(SSLSocketFactory.getDefault())
.build();
connection = new XMPPTCPConnection(config);
connection.connect();
Roster roster = Roster.getInstanceFor(connection);
roster.setRosterLoadedAtLogin(false);
connection.addConnectionListener(new LoggingConnectionListener());
// Handle incoming packets
connection.addAsyncStanzaListener(new MyStanzaListener(), new MyStanzaFilter());
// Log all outgoing packets
connection.addPacketInterceptor(new MyStanzaInterceptor(), new MyStanzaFilter());
connection.login(mProjectId + "@gcm.googleapis.com", mApiKey);
logger.info("logged in: " + mProjectId);
PingManager pm = PingManager.getInstanceFor(connection);
pm.setPingInterval(300);
pm.pingMyServer();
pm.registerPingFailedListener(new PingFailedListener() {
@Override
public void pingFailed() {
connection.disconnect();
logger.error("GCM CCS, Ping failed !!");
}
});
我遇到的问题是没有收到来自GCM的任何消息,这些消息是客户端设备在一段时间后发送的。不过,心跳看起来很正常,即使在这种情况下,我也会从GCM那里听到乒乓球。这与SSL有关吗
已按如下方式处理连接排水情况
String controlType = (String) jsonObject.get("control_type");
volatile boolean connectionDraining = false;
if ("CONNECTION_DRAINING".equals(controlType)) {
connectionDraining = true;
try {
connection.disconnect();
connect();
connectionDraining = false;
} catch (Exception e) {
logger.error("Error establishing new connection after draining ", e);
}
}
我相信您正面临一个使用gcm css的常见情况,而这在文档中不是很明显。 如果您查看文档,您将看到:
CCS需要定期关闭连接以执行负载平衡。在关闭连接之前,CCS发送一条连接排水消息,指示连接正在排水,并将很快关闭。“排放”指的是关闭进入连接的消息流,但允许管道中已有的任何内容继续。当您收到连接消息时,应立即开始向另一个CCS连接发送消息,必要时打开新连接。但是,您应该保持原始连接处于打开状态,并继续接收可能通过连接发送的消息(并确认消息)——CCS处理在连接准备就绪时启动关闭连接
其中一个正在排空时实现的通道队列
private Deque<Channel> channels;
protected void handleControlMessage(Map<String, Object> jsonObject) {
logger.info("Control message : " + jsonObject);
String controlType = (String) jsonObject.get("control_type");
if ("CONNECTION_DRAINING".equals(controlType)) {
connectionDraining = true;
}
}
GCM将负责关闭另一个。这解决了问题。也实现了连接排空逻辑。在上面的帖子中添加了这一点,请检查是否正确。当您收到连接排空消息时,应立即开始向另一个CCS连接发送消息,必要时打开新连接。但是,您应该保持原始连接处于打开状态。。。不要关闭连接,启动一个新连接,等待谷歌关闭旧连接。
public void sendDownstreamMessage(String jsonRequest) {
Channel channel = channels.peekFirst();
try {
if (channel.connectionDraining) {
synchronized (channels) {
channel = channels.peekFirst();
if (channel.connectionDraining) {
channels.addFirst(connect());
channel = channels.peekFirst();
}
}
}
channel.send(jsonRequest);
} catch (Exception e) {
logger.error("Message not sent. Error in connecting :", e);
}
}