Spring integration XMPP and Google Cloud Messaging

2019-07-04 00:21发布

I'm using the spring integration xmpp module to write a custom implementation of a 3rd party Server connecting to GCM cloud services, as in GCM Cloud Connection Server (XMPP).

So far I've successfully connected to the GCM server, however when I send a message to the server I end up with something like:

<message id="m-1366082849205" to="REGISTRATION_ID">
<body>{"hello":"world"}</body>
</message>

, but I need to send something like this:

  <message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",
      "message_id":"m-1366082849205"
      "data":
      {
          "hello":"world",
      }
  }
  </gcm>
</message>

I use the latest SI version, 4.0.4, this is my configuration in the xml:

<int-xmpp:outbound-channel-adapter
    id="gcmOutboundAdapter" channel="gcmOutboundNotificationChannel"
    xmpp-connection="gcmConnection" auto-startup="true"/>

I'm sending messages with the usual MessageBuilder like this:

Message<String> xmppOutboundMsg = MessageBuilder.withPayload(xmppPayload)
        .setHeader(XmppHeaders.TO, REGISTRATION_ID)
        .build();

where xmppPayload is a json string.

I need to configure/override the way the xmpp message is composed, what is the best practice to achieve the result? Should I override the class implementing int-xmpp:outbound-channel-adapter with a custom service activator, is there anyway to configure the way the xmpp message is composed?

Thanks for any help.

4条回答
再贱就再见
2楼-- · 2019-07-04 00:50

<gcm xmlns="google:mobile:data"> is a extended content element (see RFC 6120 8.4), which is modelled as PacketExtension in Smack. Do not subclass message, instead create a GCMPacketExtension class and add a instance of it to your message

message.addPacketExtension(gcmPackExtension)
查看更多
smile是对你的礼貌
3楼-- · 2019-07-04 00:55

Until we introduce the PackExtension injection, you can overcome it with custom <transformer ref="">, because the <int-xmpp:outbound-channel-adapter> can accept org.jivesoftware.smack.packet.Message as a Message payload:

<transformer ref="toGcmTransformer" output-channel="gcmOutboundNotificationChannel"/>

<int-xmpp:outbound-channel-adapter
    id="gcmOutboundAdapter" channel="gcmOutboundNotificationChannel"
    xmpp-connection="gcmConnection" auto-startup="true"/>

public class ToGcmTransformer extends AbstractTransformer {


   protected Object doTransform(Message<String> message) throws Exception {
        String to = message.getHeaders().get(XmppHeaders.TO, String.class);
        xmppMessage = new org.jivesoftware.smack.packet.Message(to);
        xmppMessage.setBody(message.getPayload());
        xmppMessage.addPacketExtension(gcmPackExtension);
        return xmppMessage;
   }

}

Please, raise an issue about PackExtension support.

查看更多
欢心
4楼-- · 2019-07-04 00:59

-->

<int:chain input-channel="gcmOutboundNotificationChannel">
    <!--<int:transformer ref="toGcmTransformer" output-channel="gcmOutboundNotificationChannel"/>-->
    <bean class="com.payumoney.cardhash.service.MyMessageSendingMessageHandler">
        <constructor-arg ref="gcmConnection" />
    </bean>
</int:chain>
<int:transformer id="testTransformer" ref="toGcmTransformer" input-channel="gcmInboundNotificationChannel"
         method="doTransform" output-channel="gcmOutboundNotificationChannel"/>
<!--<int:transformer ref="toGcmTransformer" output-channel="gcmOutboundNotificationChannel"/>-->

<int-xmpp:outbound-channel-adapter
    id="gcmOutboundAdapter" channel="gcmOutboundNotificationChannel"
    xmpp-connection="gcmConnection" auto-startup="true"/>

<int:chain input-channel="gcmInboundNotificationChannel">
    <bean class="com.payumoney.cardhash.service.PayumoneyNotificationListeningEndpoint">
        <constructor-arg ref="gcmConnection" />
        <property name="outputChannel" ref="gcmOutboundNotificationChannel" />
    </bean>
</int:chain>

<int-xmpp:inbound-channel-adapter 
    id="gcmInboundAdapter"  channel="gcmInboundNotificationChannel" 
    xmpp-connection="gcmConnection" extract-payload="true" auto-startup="true" />
查看更多
等我变得足够好
5楼-- · 2019-07-04 01:10

The format of the message is hard-coded in the Smack Message.toXML() method (we use the smack library underneath).

See @Flow's answer.

Then, subclass ChatMessageSendingMessageHandler, overriding handleMessageInternal() - pretty much copy the code and set the extension after the message is created.

The easiest way to configure your custom handler is probably to put it in a chain...

<chain input-channel="gcmOutboundNotificationChannel">
    <bean class="foo.MyChatMessageSendingMessageHandler">
        <constructor-arg ref="gcmConnection" />
    </bean>
</chain>

Or you can wire it up as a top level bean and inject it into a ConsumerEndpointFactoryBean.

Feel free to open a New Feature JIRA Issue and we'll consider adding an extension point to make this a bit easier.

查看更多
登录 后发表回答