java 中的 XMPP 服务器未收到来自 GCM 服务器的所有消息
XMPP server in java does not receive all messages from GCM server
我已经使用 Smack 库实现了 XMPP 服务器,我的服务器从 Google 云消息服务器(现在是 Firebase)获取消息,但问题是当我从 [=19 一条一条地发送消息时=] 到 gcm 服务器,我的 XMPP 服务器只收到第一条消息,第二条被拦截,(我只能看到有一条消息的通知
<message id="gQaM0-6"><gcm xmlns="google:mobile:data">{"message_type":"ack","message_id":"0","to":"eVtypIWW7Q8:APA91bH5oU0AC3zyuCAWVYkMzoGQeIiGe71c2BL4lE5uFHRfB3iPXtD-qIJDmJZ3ySsPDi0VhkKl0Cz3XZG7rWa1Ca7pX9yQqzWSMXBiGK4SEO4Q-Owfr45E_VBJMrXqsSziuJhek"}</gcm></message>
但我没有这方面的数据
我在方法 void processPacket(Packet packet) 中得到的第一条消息
这是 XMPP 服务器的完整代码:
public class XMPPServer implements PacketListener {
private static XMPPServer sInstance = null;
private XMPPConnection connection;
private ConnectionConfiguration config;
private String mApiKey = null;
private String mProjectId = null;
private boolean mDebuggable = false;
private String fcmServerUsername = null;
public static XMPPServer getInstance() {
if (sInstance == null) {
throw new IllegalStateException("You have to prepare the client first");
}
return sInstance;
}
public static XMPPServer prepareClient(String projectId, String apiKey, boolean debuggable) {
synchronized (XMPPServer.class) {
if (sInstance == null) {
sInstance = new XMPPServer(projectId, apiKey, debuggable);
}
}
return sInstance;
}
private XMPPServer(String projectId, String apiKey, boolean debuggable) {
this();
mApiKey = apiKey;
mProjectId = projectId;
mDebuggable = debuggable;
fcmServerUsername = mProjectId + "@" + Util.FCM_SERVER_CONNECTION;
}
private XMPPServer() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(Util.FCM_ELEMENT_NAME, Util.FCM_NAMESPACE,
new PacketExtensionProvider() {
@Override
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Connects to FCM Cloud Connection Server using the supplied credentials
*/
public void connect() throws XMPPException {
config = new ConnectionConfiguration(Util.FCM_SERVER, Util.FCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setSocketFactory(SSLSocketFactory.getDefault());
// Launch a window with info about packets sent and received
config.setDebuggerEnabled(mDebuggable);
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
//a few overrided methods
});
// Handle incoming packets (the class implements the PacketListener)
connection.addPacketListener(this, new PacketTypeFilter(Message.class));
// Second message without data I get in this method (1)
connection.addPacketWriterInterceptor(new PacketInterceptor() {
@Override
public void interceptPacket(Packet packet) {
System.out.println("INTERCEPT PACKAGE: " + packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(fcmServerUsername, mApiKey);
}
/**
* Normal message with my data I get in this method (2)
*/
@SuppressWarnings("unchecked")
@Override
public void processPacket(Packet packet) {
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(Util.FCM_NAMESPACE);
String json = gcmPacket.getJson();
System.out.println("Message : " + json);
}
差不多全代码了,最重要的部分我用(1)和(2)标出来了,(用搜索快速找到)
为什么我的数据只能收到第一条消息?
为什么第二条消息会转到 PacketInterceptor(标记 (1) )?
如果您使用的是 Firebase Cloud Messaging(FCM),请检查您的应用服务器是否连接到以下端点:
// Production
fcm-xmpp.googleapis.com:5235
// Testing
fcm-xmpp.googleapis.com:5236
除此之外,您可能还想检查 Downstream messages 其中提到一旦 XMPP 连接建立,CCS 和您的服务器使用正常的 XMPP <message>
节发送 JSON-来回编码的消息。 <message>
的正文必须是:
<gcm xmlns:google:mobile:data>
JSON payload
</gcm>
此外,请注意 JSON 常规 FCM 消息有效负载中的例外情况。访问给定的链接以获取更多信息。
这些相关的 SO 帖子也可能有帮助:
- Send FCM messages from server side to android device
我已经使用 Smack 库实现了 XMPP 服务器,我的服务器从 Google 云消息服务器(现在是 Firebase)获取消息,但问题是当我从 [=19 一条一条地发送消息时=] 到 gcm 服务器,我的 XMPP 服务器只收到第一条消息,第二条被拦截,(我只能看到有一条消息的通知
<message id="gQaM0-6"><gcm xmlns="google:mobile:data">{"message_type":"ack","message_id":"0","to":"eVtypIWW7Q8:APA91bH5oU0AC3zyuCAWVYkMzoGQeIiGe71c2BL4lE5uFHRfB3iPXtD-qIJDmJZ3ySsPDi0VhkKl0Cz3XZG7rWa1Ca7pX9yQqzWSMXBiGK4SEO4Q-Owfr45E_VBJMrXqsSziuJhek"}</gcm></message>
但我没有这方面的数据 我在方法 void processPacket(Packet packet) 中得到的第一条消息 这是 XMPP 服务器的完整代码:
public class XMPPServer implements PacketListener {
private static XMPPServer sInstance = null;
private XMPPConnection connection;
private ConnectionConfiguration config;
private String mApiKey = null;
private String mProjectId = null;
private boolean mDebuggable = false;
private String fcmServerUsername = null;
public static XMPPServer getInstance() {
if (sInstance == null) {
throw new IllegalStateException("You have to prepare the client first");
}
return sInstance;
}
public static XMPPServer prepareClient(String projectId, String apiKey, boolean debuggable) {
synchronized (XMPPServer.class) {
if (sInstance == null) {
sInstance = new XMPPServer(projectId, apiKey, debuggable);
}
}
return sInstance;
}
private XMPPServer(String projectId, String apiKey, boolean debuggable) {
this();
mApiKey = apiKey;
mProjectId = projectId;
mDebuggable = debuggable;
fcmServerUsername = mProjectId + "@" + Util.FCM_SERVER_CONNECTION;
}
private XMPPServer() {
// Add GcmPacketExtension
ProviderManager.getInstance().addExtensionProvider(Util.FCM_ELEMENT_NAME, Util.FCM_NAMESPACE,
new PacketExtensionProvider() {
@Override
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
String json = parser.nextText();
GcmPacketExtension packet = new GcmPacketExtension(json);
return packet;
}
});
}
/**
* Connects to FCM Cloud Connection Server using the supplied credentials
*/
public void connect() throws XMPPException {
config = new ConnectionConfiguration(Util.FCM_SERVER, Util.FCM_PORT);
config.setSecurityMode(SecurityMode.enabled);
config.setReconnectionAllowed(true);
config.setSocketFactory(SSLSocketFactory.getDefault());
// Launch a window with info about packets sent and received
config.setDebuggerEnabled(mDebuggable);
connection = new XMPPConnection(config);
connection.connect();
connection.addConnectionListener(new ConnectionListener() {
//a few overrided methods
});
// Handle incoming packets (the class implements the PacketListener)
connection.addPacketListener(this, new PacketTypeFilter(Message.class));
// Second message without data I get in this method (1)
connection.addPacketWriterInterceptor(new PacketInterceptor() {
@Override
public void interceptPacket(Packet packet) {
System.out.println("INTERCEPT PACKAGE: " + packet.toXML());
}
}, new PacketTypeFilter(Message.class));
connection.login(fcmServerUsername, mApiKey);
}
/**
* Normal message with my data I get in this method (2)
*/
@SuppressWarnings("unchecked")
@Override
public void processPacket(Packet packet) {
Message incomingMessage = (Message) packet;
GcmPacketExtension gcmPacket = (GcmPacketExtension) incomingMessage.getExtension(Util.FCM_NAMESPACE);
String json = gcmPacket.getJson();
System.out.println("Message : " + json);
}
差不多全代码了,最重要的部分我用(1)和(2)标出来了,(用搜索快速找到) 为什么我的数据只能收到第一条消息? 为什么第二条消息会转到 PacketInterceptor(标记 (1) )?
如果您使用的是 Firebase Cloud Messaging(FCM),请检查您的应用服务器是否连接到以下端点:
// Production
fcm-xmpp.googleapis.com:5235
// Testing
fcm-xmpp.googleapis.com:5236
除此之外,您可能还想检查 Downstream messages 其中提到一旦 XMPP 连接建立,CCS 和您的服务器使用正常的 XMPP <message>
节发送 JSON-来回编码的消息。 <message>
的正文必须是:
<gcm xmlns:google:mobile:data>
JSON payload
</gcm>
此外,请注意 JSON 常规 FCM 消息有效负载中的例外情况。访问给定的链接以获取更多信息。
这些相关的 SO 帖子也可能有帮助:
- Send FCM messages from server side to android device