xmpp-connection (spring integration) 的正确参数是啥,以使其与 google gcm 一起使用?

Posted

技术标签:

【中文标题】xmpp-connection (spring integration) 的正确参数是啥,以使其与 google gcm 一起使用?【英文标题】:What are the right parameters for xmpp-connection (spring integration) to make it work with google gcm?xmpp-connection (spring integration) 的正确参数是什么,以使其与 google gcm 一起使用? 【发布时间】:2015-03-04 12:43:30 【问题描述】:

我想在我的 spring 应用程序上设置 spring-integration-xmpp 以使其接收来自 android 设备的上游消息。我已经可以使用 http 向 android 设备发送消息,但我无法设置 xmpp-connection bean,所以它给了我:

failed to connect to gcm-preprod.googleapis.com; nested exception is Connection failed. No response from server.:

这是我的spring集成配置:

  <int:channel id="gcmOutboundNotificationChannel"/>

  <int-xmpp:xmpp-connection
    id="xmppConnection"
    user="$tracker.server.app.id@gcm.googleapis.com"
    password="$tracker.auth.key"
    host="gcm-preprod.googleapis.com"
    port="5236"
    subscription-mode="accept_all"/>

  <int-xmpp:outbound-channel-adapter
    id="gcmOutboundAdapter"
    xmpp-connection="xmppConnection"
    channel="gcmOutboundNotificationChannel"/>

tracker.server.app.id 是一个 12 位数字 和tracker.auth.key 就像AIzaSyBdfZ4oBaVuu07sjW5e9DnogeUF6NV****(我把星号放在里面)。

我错过了什么?

【问题讨论】:

以防万一:如果没有 Spring Integration,你能做到吗?我的意思是直接使用 Smack 库 查看this question 及其答案。 @GaryRussell,您的链接和 AniV 指向同一个问题,但在不同的网站上。这是一个完全不同的问题,处理一个完全不同的问题。我相信我的问题是***中唯一对spring-integration和gcm有疑问的问题。这个问题和github.com/spring-projects/spring-integration-samples 中的几个例子是我用来配置xmpp-connection 的。看那个问题有帮助,但那个人没有说他是如何配置他的东西的。 @ArtemBilan,我照你说的做了。我使用了code snippet in the android documentation。连接已建立,我什至可以向设备发送消息。我确实从设备向服务器发送了一条消息,但我还不知道如何接收它。那是另一个问题。现在知道堆栈库自己工作了,这对解决我的问题有帮助吗? 您为什么认为这是一个不同的问题?正如我们从GCM Cloud Connection Server 样本中看到的那样,它们提供GcmPacketExtension。这正是我们谈到的。 Spring Integration 还不支持任何PacketExtensions。您还必须为ConnectionConfiguration 添加这些选项。直接使用XmppConnectionFactoryBean 而不是&lt;int-xmpp:xmpp-connection&gt; 【参考方案1】:

我已将 xmpp 连接配置为这样的 bean:

@Configuration
public class GcmXmppConnection 

@Value("$gcm.senderID")
private String username;

@Value("$gcm.apiKey")
private String password;

@Value("$gcm.host")
private String host;

@Value("$gcm.port")
private int port;

@Bean(name="gcmConnection")
public XmppConnectionFactoryBean xmppConnectionFactoryBean()

    ConnectionConfiguration configuration = new    ConnectionConfiguration(host, port);
    configuration.setSecurityMode(SecurityMode.enabled);
    configuration.setReconnectionAllowed(true);
    configuration.setRosterLoadedAtLogin(false);
    configuration.setSendPresence(false);
    configuration.setSocketFactory(SSLSocketFactory.getDefault());

//      configuration.setDebuggerEnabled(true);
    XmppConnectionFactoryBean connectionFactoryBean = new XmppConnectionFactoryBean(configuration);

    connectionFactoryBean.setUser(username);
    connectionFactoryBean.setPassword(password);

    return connectionFactoryBean;


配置在 xml 配置中自动装配,如下所示:

<!-- Outbound messages to gcm -->
    <int:chain input-channel="androidNotificationOutputChannel">
    <int:transformer ref="androidMessageTransformer"></int:transformer>
    <int-xmpp:outbound-channel-adapter xmpp-connection="gcmConnection"/>
</int:chain>

<!-- Inbound messages from gcm -->
<int:channel id="gcmInboundNotificationChannel"/>
<int-xmpp:inbound-channel-adapter id="gcmInboundAdapter"
    channel="gcmInboundNotificationChannel" xmpp-connection="gcmConnection"
    extract-payload="true" auto-startup="true" />

最后一部分是 androidMessageTransformer,它非常简单,就像在 google 文档中的示例中编写的 gcmXmppConnection bean 一样。

@MessageEndpoint
public class AndroidMessageTransformer extends AbstractTransformer 

public final static String DESTINATION_HEADER_KEY="push.destinationID";

private final static String MESSAGE_ID_FORMAT = "%s-%s";

@Value("$gcm.senderID")
private String senderId;

@Autowired
ObjectMapper om;

@SuppressWarnings("unchecked")
@Override
protected Object doTransform(Message<?> msgIn) throws Exception 
    Map<String,String> data = (Map<String, String>) msgIn.getPayload();
    String registrationID = msgIn.getHeaders().get(DESTINATION_HEADER_KEY,String.class);
    Map<String, Object> gcmPayload = new HashMap<>();

    gcmPayload.put("to", registrationID);
    gcmPayload.put("message_id", String.format(Locale.ENGLISH, MESSAGE_ID_FORMAT, senderId, UUID.randomUUID().toString()));
    gcmPayload.put("data", data);

    String gcmJsonPayload = om.writeValueAsString(gcmPayload);

    org.jivesoftware.smack.packet.Message xmppMessage = new org.jivesoftware.smack.packet.Message();
    xmppMessage.addExtension(new GcmPacketExtension(gcmJsonPayload));

    return xmppMessage;


这对我来说很可靠,尽管我主要处理出站方向,并且从未检查过入站方向。

【讨论】:

如果你能编辑你的答案并分享androidMessageTransformer的样子,那就太棒了。【参考方案2】:

我认为您在&lt;int-xmpp:outbound-channel-adapter 标记中缺少auto-startup="true"。请参阅以下answer 可能对您有用。

【讨论】:

我认为auto-startup 的默认值是true,但可以肯定的是,我按照您所说的进行了编译和部署,并没有改变任何事情。仍然得到相同的结果。

以上是关于xmpp-connection (spring integration) 的正确参数是啥,以使其与 google gcm 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA

spring 事物中遇到try catch 事物不会滚

[bzoj3198] [Sdoi2013]spring

BZOJ3198 SDOI2013 spring HASH+容斥原理

Spring WebFlux性能测试——响应式Spring的道法术器

Spring五2班