Announcement Announcement Module
Collapse
No announcement yet.
Send Message to Offline User in XMPP outbond adapter not result in error Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Send Message to Offline User in XMPP outbond adapter not result in error

    Hi everyone,
    I have some problem with xmpp adapter. I want to make xmpp outbond adapter raise error whenever it send message to offline user. I have try it and no error was raise when sending message to offline user.
    Is there a way to achieve this?
    Thanks & Regards.

  • #2
    Hello,
    Is there anyone can help me? Please I need some guidance here.
    Thanks.

    Comment


    • #3
      Up..
      Please someone respond my thread..

      If this can't be achieved, is there any way to send message only to online user?
      Thanks & Regards.

      Comment


      • #4
        Hi!

        I'm not well with XMPP, but I dug Google and read Smack source code and now try to help you .

        1. XMPP protocol allows to send massages to offline users. Messages will be stored on the server before user will become online. That's why you don't get an error.
        2. To check user status you can use Roster.getPresence(user).isAvailable().
        3. So, what you need it is getting the user's status before sending message to our chat.

        Only one place I see just to intercept the Packet before it will be placed to the internal PacketWriter's queue.

        What I suggest to implement your own org.jivesoftware.smack.PacketInterceptor:
        Code:
        public class UserStatusPacketInterceptor implements PacketInterceptor, BeanFactoryAware, InitializingBean {
        
        	private BeanFactory beanFactory;
        
        	private Connection connection;
        
        	@Override
        	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        		this.beanFactory = beanFactory;
        	}
        
        	@Override
        	public void afterPropertiesSet() throws Exception {
        		this.connection = this.beanFactory.getBean(XmppContextUtils.XMPP_CONNECTION_BEAN_NAME, Connection.class);
        	}
        
        	@Override
        	public void interceptPacket(Packet packet) {
        		if (packet.getTo() != null
        				&& packet instanceof Message
        				&& !this.connection.getRoster().getPresence(packet.getTo()).isAvailable()) {
        			throw new IllegalStateException("The user '" + packet.getTo() + "' is not available.");
        		}
        	}
        
        }
        But it isn't all.
        Next step: extend XmppConnectionFactoryBean to get ability to provide interceptors for XMPPConnection:
        Code:
        public class InterceptableXmppConnectionFactoryBean extends XmppConnectionFactoryBean {
        
        	private PacketInterceptor[] packetInterceptors;
        
        	public InterceptableXmppConnectionFactoryBean(ConnectionConfiguration connectionConfiguration) {
        		super(connectionConfiguration);
        	}
        
        	public void setPacketInterceptors(PacketInterceptor... packetInterceptors) {
        		this.packetInterceptors = packetInterceptors;
        	}
        
        	@Override
        	protected XMPPConnection createInstance() throws Exception {
        		XMPPConnection connection = super.createInstance();
        		for (PacketInterceptor packetInterceptor : packetInterceptors) {
        			connection.addPacketInterceptor(packetInterceptor, null);
        		}
        		return connection;
        	}
        }
        And in the end you should configure a bean "xmppConnection" and remove similar declaration via custom tag <int-xmpp:xmpp-connection>:
        HTML Code:
        <bean id="xmppConnection" class="com.my.proj.xmpp.InterceptableXmppConnectionFactoryBean">
        		<constructor-arg>
        			<bean class="org.jivesoftware.smack.ConnectionConfiguration">
        				<constructor-arg value="myServiceName"/>
        			</bean>
        		</constructor-arg>
        		<property name="packetInterceptors">
        			<bean class="com.my.proj.xmpp.UserStatusPacketInterceptor"/>
        		</property>
        	</bean>
        Let me know how it is.

        Take care,
        Artem

        Comment


        • #5
          Hi! It's me again

          I looked at this one more time and found more elegant solution:
          HTML Code:
          <int:chain input-channel="sendChatMessageChannel">
          	<int:filter expression="@xmppConnection.roster.getPresence(headers.xmpp_to).available"
          			throw-exception-on-rejection="true"/>
          	<int-xmpp:outbound-channel-adapter xmpp-connection="xmppConnection"/>
          </int:chain>

          Comment


          • #6
            Hi Cleric,
            Thank you for responding to my thread, really appreciate it. I will give it a try, and will let you know the result.
            Thanks & Regards.

            Comment

            Working...
            X