识别上游 GCM 消息的发送者

Posted

技术标签:

【中文标题】识别上游 GCM 消息的发送者【英文标题】:Identifying Sender of Upstream GCM Message 【发布时间】:2015-06-09 19:26:06 【问题描述】:

我将 Google Cloud Messaging 与 XMPP 一起使用,以便同时获得下游和上游消息。

只有客户端我通过在工作线程上执行此操作来获取令牌:

InstanceID instanceID = InstanceID.getInstance(this);

try 
    String token = instanceID.getToken(getString(R.string.gcm_senderID), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

    send_token(token, getString(R.string.gcm_senderID));
 catch (IOException e) 
    e.printStackTrace();

然后我将此令牌发送到接收它的服务器。我可以使用此令牌向客户端发送消息。

然后我可以在客户端发送一条上游消息:

new AsyncTask<Void, Void, String>() 
    @Override
    protected String doInBackground(Void... params) 
        String msg;

        Bundle data = new Bundle();

        data.putString("message", message);

        try 
            messenger.send(getString(R.string.gcm_senderID) + "@gcm.googleapis.com", messageId.addAndGet(1) + "", data);
         catch (IOException e) 
            e.printStackTrace();
        

        msg = "Sent message";

        return msg;
    
.execute(null, null, null);

在客户端发送的上游消息中,有一个from字段,这似乎也是一个令牌。如果我从服务器端向它发送消息,我的手机也会收到它。

让我困惑的是from字段中的令牌不等于InstanceID服务生成的令牌。

前 18 个字符左右相等,但之后它们就大不相同了。那么,有没有一种好的方法可以识别是什么设备发送了什么消息?

我可以将Instance ID每次生成的令牌存储在Bundle中,但是我想知道是否有任何方法可以使上游消息的from字段与生成的ID保持一致。

编辑:使用已弃用的 register 函数,我能够获得一致的注册 ID。

String token = GoogleCloudMessaging.getInstance().register(getString(R.string.gcm_senderID));

但是有没有办法用 InstanceID 做到这一点?

【问题讨论】:

上游消息传递仍然使用 GoogleCloudMessaging API 来发送消息,因此预计它使用 GoogleCloudMessaging 生成的注册 ID 作为其源(“来自”对象)。此时,如果您希望服务器以统一的方式处理消息传递,将 Instance ID 令牌添加到 Bundle 中似乎是最方便的操作。 是的,它有一个生成的注册 ID 作为其源是有道理的,但我不明白为什么它为每个发送的上游消息使用新生成的注册 ID,不应该使用应用生成的注册ID? developers.google.com/cloud-messaging/server-ref#upstream 的文档对上游 XMPP 消息的“发件人”字段进行了说明:“此参数指定发送消息的人。该值是客户端应用程序的注册令牌." 从这里我明白它应该与 instanceID.getToken(GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE); 相同。回来了,但不是。除前 18 个字符外,每条消息都有不同的“发件人” @Clark 另一种选择,而不是将令牌存储在消息本身中:如果您在应用程序中拥有自己的身份验证机制,则可以在服务器上找到您正在发送消息的用户的令牌通过在上游消息中添加您自己的标识符,然后在服务器上根据该标识符找到令牌。 (假设您之前已经将令牌发送到服务器并将其与标识符相关联并将其存储在某处) 我遇到了同样的问题。对我来说似乎是一个错误。你找到解决办法了吗? 【参考方案1】:

调用 GoogleCloudMessaging.getInstance(context).register(senderId) 而不是 getToken(senderId, "GCM") 似乎可以解决问题,然后 XMPP 服务器每次都会在“from”属性中接收正确的令牌上游消息。

我的设备正在运行 CyanogenMod,因此 Google Play 服务应用不会自动更新。由于旧的 register() 可以工作,因此此问题可能是由于与旧版本的 GMS 应用程序对话时 google-play-services_lib 中的错误引起的。

我已经回答而不是评论,因为谷歌开发人员看到了这一点。

【讨论】:

Google 已承认他们有一个未解决的问题并正在解决。

以上是关于识别上游 GCM 消息的发送者的主要内容,如果未能解决你的问题,请参考以下文章

如何使用谷歌云连接服务器发送上游 GCM 消息

GCM 中使用上游消息传递的消息流程图

GCM 云连接服务器中上游消息的主要用途是啥?

GCM如何使用Jaxl实现上游的服务器端

Android 应用上游消息传递是不是可靠?

如何使用 Android 代码中的 GCM CCS 进行上游消息传递服务?