Search code examples
spring-bootxmppspring-integrationsmack

XMPP Spring integration - Chat


I am new to XMPP, trying to create a server in spring-boot to listen and send message using XMPP, this is what I tried

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:int-xmpp="http://www.springframework.org/schema/integration/xmpp"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration/xmpp
    http://www.springframework.org/schema/integration/xmpp/spring-integration-xmpp.xsd">

    <int-xmpp:xmpp-connection
        id="xmppConnection" 
        user="admin@192.168.1.201" 
        password="finatel123" 
        host="192.168.1.201"
        port="5222"/>

    <int-xmpp:inbound-channel-adapter 
        id="xmppInboundAdapter"
        channel="chatMessageListening" 
        xmpp-connection="xmppConnection"
        auto-startup="true"/>

    <int-xmpp:outbound-channel-adapter 
        id="outboundEventAdapter"
        channel="chatMessageSending"
        xmpp-connection="xmppConnection" 
        auto-startup="false">
        <poller fixed-rate="5000" max-messages-per-poll="1"/>
    </int-xmpp:outbound-channel-adapter>

</beans:beans>

ChatMessageListening.java

public class ChatMessageListening implements MessageChannel {

    @Override
    public boolean send(Message<?> message) {

        MessageHeaders headers = message.getHeaders();

        System.out.println("FROM    : "+headers.get(XmppHeaders.FROM));
        System.out.println("TO      : "+headers.get(XmppHeaders.TO));
        System.out.println("Time    : "+new Date((Long)headers.get("timestamp")));

        return true;
    }

    @Override
    public boolean send(Message<?> message, long timeout) {
        return true;
    }
}

ChatMessageSending.java

public class ChatMessageSending implements PollableChannel {

    @Override
    public boolean send(Message<?> message) {
        return true;
    }

    @Override
    public boolean send(Message<?> message, long timeout) {
        return true;
    }

    @Override
    public Message<?> receive() {
        return null;
    }

    @Override
    public Message<?> receive(long timeout) {
            return null;
    }
}

Doing this configurations I'm able to receive the message at ChatMessageListening.send() method.

I tried to send message using,

MessagingTemplate template = new MessagingTemplate();
template.setSendTimeout(5000L);

Message<String> xmppOutboundMsg = MessageBuilder.withPayload("Hello, XMPP!" )
    .setHeader(XmppHeaders.FROM, "admin@192.168.1.201")
    .setHeader(XmppHeaders.TO, "adminone@192.168.1.201")
    .setHeader(XmppHeaders.TYPE, "chat")
    .build();
template.setDefaultChannel(new ChatMessageSending());
template.send(xmppOutboundMsg);

But it is not sending to client but it receiving to the ChatMessageSending. Please guide me what I am doing wrong. What I have to use.


Solution

  • You use MessageChannel strange way.

    Please, consider to revise your vision on the matter: EIP definition and Spring Integration implementation:

    Producers send Messages to a channel, and consumers receive Messages from a channel.

    So, message channel can't be a listener and can't be something like sending.

    You have to just declare a couple <channel> in your configuration and use an appropriate <service-activator> to process messages from the XMPP and some other to produce messages.

    Yes, MessagingTemplate can be use for sending, but you have to point out to the proper MessageChannel bean where your <int-xmpp:outbound-channel-adapter> will be subscriber.

    Right now your ChatMessageSending has a void implementation and there is no any wiring with the target channel adapter.

    There is an XMPP sample for you by the way.