Send message on successful login to the server

We are using Wildfire 2.4.0 server and smack API for client.

I have a question about the where incoming messages to the client are processed. Specifically, where is the "login

success" message processed at the client. We want to write an extension to the smack client to send out a new message

to the server after client has successfully logged in (that is, after the “login success” message has been received by

client).

We explicitly do not want to modify the “login success” message that is sent by the server, because up on examination of

the code in org.jivesoftware.wildfire.handler.IQHandler.java, we would have to change JIVE server’'s code. We would rather filter the “login success” message and listen to it, if this is possible.

what is the best solution around for this?

Hi Mahaveer,

Instead of having the client send a message to the server you might want to look into using a url=http://www.jivesoftware.org/builds/wildfire/docs/latest/documentation/javado cSessionEventListener[/url].

Hope that helps,

Ryan

Thanks for your reply…

Where do i register SessionEventListener? Client or server? I think its server.

Do I need to add a plugin to listener to this listener

Can you point me to some example for SessionEventListener?

Hi Mahaveer,

Yes, you’'d want to register the SessionEventListener via a plugin on the server. Below is expanded version of the example plugin that is part of the Wildfire Plugin Guide:

package org.example;

import java.io.File;

import org.jivesoftware.wildfire.Session;

import org.jivesoftware.wildfire.container.Plugin;

import org.jivesoftware.wildfire.container.PluginManager;

import org.jivesoftware.wildfire.event.SessionEventDispatcher;

import org.jivesoftware.wildfire.event.SessionEventListener;

public class ExamplePlugin implements Plugin {

private ExampleSessionEventListener listener = new ExampleSessionEventListener();

public void initializePlugin(PluginManager manager, File pluginDirectory) {

SessionEventDispatcher.addListener(listener);

}

public void destroyPlugin() {

SessionEventDispatcher.removeListener(listener);

}

private class ExampleSessionEventListener implements SessionEventListener {

public void sessionCreated(Session session) {

System.out.println(“ExampleSessionEventListener.sessionCreated()”);

}

public void sessionDestroyed(Session session) {

}

public void anonymousSessionCreated(Session session) {

}

public void anonymousSessionDestroyed(Session session) {

}

}

}

/code

Hope it helpos,

Ryan

Hi Ryan,

I think your idea will work. I tried implementing that.

Now I am into a new problem. I want to get the username in ExamplePlugin, but not successful. (I want to get the random number, which I store in a Vector which is associated with the username. This part is done in the my custom AuthProvider).

Also I am not able to get session in AuthProvider class, so that I can set the random number in the session and then extract it in ExamplePlugin

If I get session in AuthProvider or username in ExamplePlugin I am fine. I don’'t want to change the server code.

Thanks

Mahaveer

Hi Ryan,

I am stuck trying to implement a plugin and a provider.

We have written a custom Authorization Provider, and in it we want to access the JID. We are unable to access it …

without changing the server code. Is there any way of getting the JID?

We have also written a plugin like suggested above. Inside the plugin, we would like to access username … we are

unable to get it. Is there a way to get username inside a plugin?

Either would help to move ahead. Let me know if it is possible with out changes the server code.

Thanks

Mahaveer

Hi Mahaveer,

We have written a custom Authorization Provider, and

in it we want to access the JID. We are unable to

access it … without changing the server code. Is there

any way of getting the JID?

I’‘m sorry, I don’‘t understand what you’'re trying to do. Have you looked at some of the other classes, like DefaultAuthProvider, that implement the AuthProvider interface?

We have also written a plugin like suggested above.

Inside the plugin, we would like to access username

… we are unable to get it. Is there a way to get username

inside a plugin?

You can get the username for the session by doing the following:

String username = session.getAddress().getNode().toLowerCase();

/code

Hope that helps,

Ryan

Ryan,

I want to send a packet to the client. I have the client name, packet ready.

I don’‘t have from[/b] address, the server’'s address.

One more question, is it fine if I don’'t have a from info in my packet? The packet is sent from the server.

Thanks

Mahaveer

Hi Mahaveer,

I want to send a packet to the client. I have the

client name, packet ready.

Something like this should work:

private class ExampleSessionEventListener implements SessionEventListener {

public void sessionCreated(Session session) {

JID username = session.getAddress();

XMPPServer server = XMPPServer.getInstance();

String servername = server.getServerInfo().getName();

JID serverAddress = new JID(servername);

Message message = new Message();

message.setTo(username);

message.setFrom(serverAddress);

message.setBody(“Hello”);

server.getMessageRouter().route(message);

}

/code

One more question, is it fine if I don’'t have a from

info in my packet? The packet is sent from the

server.

No, it’'s not required but it is nice to supply.

Hope that helps,

Ryan

Hello Ryan,

Thanks again.

I was able to send out the message from server to the user through the plugin. I have an extension added to the message.

My message look something like this

The message is being sent from the server to the client, since I see the message in server’'s message audit file. But at

the client the message is not being processed. I have added a packet listener in the client’'s Application.java

immediately after the login is successful (I wait until session.connection() is available). Code looks like:

PacketListener listener = new PacketListener() {

public void processPacket(Packet packet) {

final Message message = (Message) packet;

RandomExtension insconfExt = (RandomExtension)message.getExtension(RandomExtension.elementname, RandomExtension.namespace);

System.out.println("Random = " + insconfExt.getRandomNum());

}

};

 PacketExtensionFilter filterExt2 = new PacketExtensionFilter("RandomExtension", "http://www.shareonweb.com/xmlns/sowim");

connection.addPacketListener(listener, filterExt2);

The message is not getting to the listener.

My question are:

  1. Is the listener in the right place?

  2. How do I debug to find out if the message was delivered to the client; if message was delivered, then how do I debug and find where the message was rejected?

Is there a way for me to send raw messages (XML format) to the client from the server through command prompt?

Can you point me to some good documentation or book?

Thanks

Mahaveer

Hello Ryan,

Thanks very much for all your help. Ignore the above message I have answers for them. Here are few new dobuts

We send a random number message to the client upon authentication from SessionEventListener plugin. Sometimes, I see the client receives this message even before the client receives the authenticated message. So the random number message is not processed at the client end.

Is there a way to send this message after an interval from the server? (Right now I have added Java timer to send after 3.5 sec)

Or can we introduce a delay in the client before it can process this message?

Thanks

Mahaveer

Hi Mahaveer,

Is there a way to send this message after an interval

from the server? (Right now I have added Java timer

to send after 3.5 sec)

If the timer solution is working for you I might just stick with that. The only other solution I could think of would be to look up the clients presence and not send the message until they’'ve become available.

Hope that helps,

Ryan

Hi Ryan,

The timer works fine sometimes. How do I check for client presence in the server?

I was thinking of sending IQ packet from client after login and then have a plugin at the server to handle it.

Mahaveer

Hello Ryan,

After a lot of research I have found that the client status is set to authenticated only after the plugin have sent the message to the client. Isn’'t any plugin which listens when the authentication is complete?

Thanks

Hi Mahaveer,

Since I haven’‘t been able to reproduce the problem you’‘re seeing I’'m not able to provide the best possible solution, but you could try using the following in your sessionCreated() method:

int count = 0;

while ((session.getStatus() != Session.STATUS_CONNECTED) && (count < 5)) {

Thread.sleep(1000);

count++;

}

/code

Hope that helps,

Ryan