使用XMPP处理传入消息的最佳方法

时间:2015-07-03 22:57:38

标签: xmpp spring-integration

是否有办法让Spring处理来自XMPP的传入消息?我已经尝试了许多不同的配置来获取入站通道适配器来响应传入的XMPP消息并且没有任何反应。我知道它们出现在Spring Integration层(我可以在日志中看到),但它们会被忽略。有没有办法让他们进入我的应用程序层?如果可以的话,我希望避免需要对Spring Integration本身进行更改。

这是我的集成配置:

<int-xmpp:inbound-channel-adapter id="gcmIn" 
                                      channel="gcmInChannel"
                                      xmpp-connection="gcmConnection"
                                      auto-startup="true"
    />
    <bean id="inboundBean" class="example.integration.GcmInputHandler"/>

    <int:service-activator input-channel="gcmInChannel" output-channel="nullChannel" ref="inboundBean" method="handle"/>

使用出站通道适配器工作正常。我可以轻松地通过GCM 100%发送消息。但即使我知道消息正在传入,入站也没有做任何事情。

由于

1 个答案:

答案 0 :(得分:1)

不是很干净,你需要覆盖ChatMessageListeningEndpoint,它会丢弃所有空体消息。 然后,这个需要在配置中用作入站通道适配器。

此外,您需要在Smack Provider Manager上注册GCM包扩展,否则您将丢失JSON消息。

处理示例项目 - 如果您需要更多帮助,请告诉我,我会尽快以可理解的方式发布链接。

此处为GCM输入适配器示例

    public class GcmMessageListeningEndpoint extends ChatMessageListeningEndpoint {
    private static final Logger LOG = LoggerFactory.getLogger(GcmMessageListeningEndpoint.class);
    @Setter
    protected PacketListener packetListener = new GcmPacketListener();
    protected XmppHeaderMapper headerMapper = new DefaultXmppHeaderMapper();

    public GcmMessageListeningEndpoint(XMPPConnection connection) {
        super(connection);


        ProviderManager.addExtensionProvider(GcmPacketExtension.GCM_ELEMENT_NAME, GcmPacketExtension.GCM_NAMESPACE,
                new PacketExtensionProvider() {
                    @Override
                    public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
                        String json = parser.nextText();
                        return new GcmPacketExtension(json);
                    }
                });
    }

    @Override
    public void setHeaderMapper(XmppHeaderMapper headerMapper) {
        super.setHeaderMapper(headerMapper);
        this.headerMapper = headerMapper;
        if (this.headerMapper == null) throw new IllegalArgumentException("Null XmppHeaderMapper isn't supported!");
    }

    public String getComponentType() {
        return "xmpp:inbound-channel-adapter-gcm";
    }

    @Override
    protected void doStart() {
        Assert.isTrue(this.initialized, this.getComponentName() + " [" + this.getComponentType() + "] must be initialized");
        this.xmppConnection.addPacketListener(this.packetListener, null);
    }

    @Override
    protected void doStop() {
        if (this.xmppConnection != null) {
            this.xmppConnection.removePacketListener(this.packetListener);
        }
    }

    class GcmPacketListener implements PacketListener {

        @Override
        public void processPacket(Packet packet) throws NotConnectedException {
            if (packet instanceof org.jivesoftware.smack.packet.Message) {
                org.jivesoftware.smack.packet.Message xmppMessage = (org.jivesoftware.smack.packet.Message) packet;
                Map<String, ?> mappedHeaders = headerMapper.toHeadersFromRequest(xmppMessage);
                sendMessage(MessageBuilder.withPayload(xmppMessage).copyHeaders(mappedHeaders).build());
            } else {
                LOG.warn("Unsuported Packet {}", packet);
            }
        }
    }
}

此处入站通道适配器的新配置会删除XML中的配置:

@Bean 
public GcmMessageListeningEndpoint inboundAdpater(XMPPConnection connection, MessageChannel gcmInChannel) {
    GcmMessageListeningEndpoint endpoint = new GcmMessageListeningEndpoint(connection);
    endpoint.setOutputChannel(gcmInChannel);
    return endpoint;
}