Android Websockets onMessage() never being called even on connection - java

I'm using websockets to make a multiplayer game and I need to send multiple types of data across the server but when I connect to the server it's supposed to send back a name and number ("type") and ("data") respectively from the websocket library on connection. I don't need the type but ("data") is vital for the game logic to actually work.
Below is the code I have in my websockets onMessage() function:
#Override
public void onMessage(String message)
{
try
{
JSONObject json = new JSONObject(message);
if(json.has("type") && json.has("data"))
{
Log.d(TAG, json.getString("type"));
Log.d(TAG, json.getString("data"));
playerNum = Integer.parseInt(json.getString("data"));
Log.d(TAG,"Received... Type : " +json.getString("type")+" Data : "+json.getString("data"));
}
if(json.has("Player1TurnOver"))
{
player1TurnOver = json.getBoolean("Player1TurnOver");
}
if(json.has("Word"))
{
String b = json.getString("Word");
bWord = new char[b.length()];
for(int i = 0; i < b.length(); i++)
{
bWord[i] = b.charAt(i);
}
wordLength = bWord.length;
}
}
catch(JSONException e)
{
}
}
But this is never called from the server even though the client has a listener as such:
mClient = new WebSocketClient(URI.create("ws://some_ip:8080/wstest"), new WebSocketClient.Listener()){
And the listener is initialised within the websocket library class
public interface Listener {
public void onConnect();
public void onMessage(String message);
public void onMessage(byte[] data);
public void onDisconnect(int code, String reason);
public void onError(Exception error);
}
I can't seem to figure out why this isn't working properly. As it has worked before...

Sometimes it is not correctly detected when a device looses internet connection (Java is not that smart in this case ;) )
Apart from this. Could you maybe activate the debug printouts with WebSocketImpl.DEBUG = true;
The lib will automatically send pings to the endpoints at specific interval and if no ping was received it assumes that the endpoint got disconnected!

Related

Angular 8 socket.io-client 2.2.0 and Java netty-socket.io message not being received?

I am using netty-socket.io and I implemented the server like the demo.
I receive onConnect event both on server and client, but when I sent a message {message: message} I don't get anything on the server event though I see the message being sent in the network tab.
Configuration config = new Configuration();
config.setHostname("localhost");
config.setPort(9092);
final SocketIOServer server = new SocketIOServer(config);
server.addConnectListener(socketIOClient -> System.out.println("Connection test"));
server.addEventListener("messageevent", MessageEventObject.class, new DataListener<MessageEventObject>() {
#Override
public void onData(SocketIOClient socketIOClient, MessageEventObject messageEventObject, AckRequest ackRequest) throws Exception {
System.out.println("message received!");
}
});
server.start();
My MessageEventObject has String message property, constructor getters and setters, looking the same as client-sided.
And this is my websocket service client-sided:
export class WebsocketService {
private socket;
private subject = new Subject < any > ();
constructor() {
console.log('test!');
}
public connect(host: string, port: number) {
this.socket = io(`http://${host}:${port}`, {
'reconnection': false
});
this.socket.on('connect', this.onConnected);
this.socket.on('connect_error', this.onConnectionFailure);
}
public getConnectionStateUpdate(): Observable < any > {
return this.subject.asObservable();
}
public sendMessage(message: string) {
console.log('test');
this.socket.emit('messageevent', {
message: message
});
}
private onConnected = () => {
this.subject.next({
connected: true
});
}
private onConnectionFailure = () => {
this.subject.next({
connected: false
});
}
}
Is there anything that I did wrong?
I would love to answer my own question after tons of debugging and breaking my head, my laziness to use Engine IO with tomcat or jetty, and just wanting to use that awesome netty package which does not require any servlets, I tried to fix it and figure out.
At first I thought it was the client's protocol version, so I used the exact same client as the demo shows on their github page here but that didn't work so the problem is server-sided.
It appears that your object (MessageEventObject) must have a default empty constructor aswell in addition to your other constructors, probably because netty tries to build an empty object and it fails which causes an exception that you don't see.

Cometd Java Client won't publish to Cometd server

I followed the examples that I could find for making a Cometd java client application. I am trying to make it so when the user presses a button on the screen, cometd publishes a message to the server. Right now the publish gets called but the server never receives message to its listener. I have this server listener working with javascript but not java code.
Client side setup is as follows:
// Prepare the transport
Map<String, Object> options = new HashMap<String, Object>();
ClientTransport transport = LongPollingTransport.create(options, httpClient);
_client = new BayeuxClient("http://10.100.97.168:8888/slideshow/slideshow/", transport);
_client.getChannel(Channel.META_HANDSHAKE).addListener(new InitializerListener());
_client.getChannel(Channel.META_CONNECT).addListener(new ConnectionListener());
My handshake and connection listeners:
private class InitializerListener implements ClientSessionChannel.MessageListener
{
public void onMessage(ClientSessionChannel channel, Message message)
{
if (message.isSuccessful())
{
_handshaked = true;
}
else
{
_handshaked = false;
}
}
}
private class ConnectionListener implements ClientSessionChannel.MessageListener
{
private boolean wasConnected;
private boolean connected;
public void onMessage(ClientSessionChannel channel, Message message)
{
if (_client.isDisconnected())
{
connected = false;
connectionClosed();
return;
}
wasConnected = connected;
connected = message.isSuccessful();
if (!wasConnected && connected)
{
connectionEstablished();
}
else if (wasConnected && !connected)
{
connectionBroken();
}
}
}
Button press that tries to publish:
_btnPlay.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(_connection_established == true)
{
Map<String, Object> data = new HashMap<String, Object>();
_clientSessionChannel.publish(data);
}
}
});
Just in case here is my server Listener too:
#Listener("/service/slide/play")
public void processServiceSlidePlay(ServerSession client, ServerMessage message)
{
synchronized(imagelock)
{
if(slideShowRunning == false && imageIDList != null && imageIDList.size() > 0)
{
slideShowRunning = true;
if(imageIDList != null && imageIDList.size() > 0)
{
deliverChangeMessage(client, message);
}
}
}
}
So I can establish a connection and my publish gets called, but the server never picks it up. Also I noticed if I do the same exact publish but in my handshake or connect callback, the server will pick it up. Seems like I just can't do a publish outside of the callbacks.
Thanks in Advance for the Help.
It turned out that I was running the network, cometD code, on Androids Main UI Thread and that is not allowed. Once I moved all the cometd code over to an AsyncTask it all started working all the time.

issue with reliable service discovery

I am banging my head on the wall. It works, but it doesn't work.
Let me clarify, testing is on a LG Optimus G, A Galaxy S4, and a Lenovo Tablet all running 4.1+
I am launching a server on each device, each device is broadcasting itself on a port, and when the user hits send, all devices that have had their service resolved, and their service has not been lost, a thread will loop launching other threads to connect to the servers broadcasting themselves, and send the data. The servers accept the incoming connection, hand it off to a thread, and then re-open themselves.
So recap, every device has is broadcasting a server, every device is supposed to know and keep track of other servers, when data is sent all known servers get hit.
My issue is that in 2/3 devices connections can consistently be established with the device's self.
Either phone, but only 1 of them at a time, seems to know about the other phone and is able to connect to the other phone. i.e. Galaxy S4 can say hi to Optimus G, but Optimus G cannot say hi except only to itself, or vice-verse.
So the discovering portion seems unreliable, and I do not know if it is me, Android, or the devices. I need outside eyes. I have tried to lay this out in a understandable and thought out manner, and I appreciate any help from any one who has knowledge on this issue as I am just making humble beginnings into the world of networks, and am more then willing to learn from someone.
I need a more reliable way of keeping track of services, or discovering them, as my implementation at least seems flawed.
I thank any help in advanced. (I do not believe this is a area that is trodden as heavily as most other android areas.)
Here is where the initialization is done.
/**initilize everything*/
private void buildNetwork()
{
Log.d(TAG, "buildNetwork");
networkHelper = new NetworkServiceDiscoveryHelper(this);
networkHelper.initializeNsd(this);
networkHelper.discoverServices();
connectionReceiver = new ConnectionReceiver(this, this);
// this next line launches the server thread which will obtain a socket
// to be used in the finishBuildingNetwork()
new Thread(connectionReceiver).start();
}
/** after the serversocket has been given a port we need to broadcast it*/
private void finishBuildingNetwork(int port)
{
Log.d(TAG, "finishBuildingNetwork");
networkHelper.registerService(port);
}
This is my somewhat changed implementation of a common NSDManager helper class.
public class NetworkServiceDiscoveryHelper
{
public static final String TAG = "NetworkServiceDiscoveryHelper";
public static final String KEY_DEVICE = "device";
Context mContext;
NsdManager mNsdManager;
NsdManager.ResolveListener mResolveListener;
NsdManager.DiscoveryListener mDiscoveryListener;
NsdManager.RegistrationListener mRegistrationListener;
public static final String SERVICE_TYPE = "_http._tcp.";
public String mServiceName = "BlurbChat";
NsdServiceInfo mService;
private DiscoveredDevicesManager deviceManager;
private NetworkDiscoveryHelperListener helperListener;
/**
*
* #param context
* - the activity context the service is to be attached to
*/
public NetworkServiceDiscoveryHelper(Context context)
{
mContext = context;
mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
deviceManager = new DiscoveredDevicesManager();
}
/**
* initialize the NetworkServiceDiscovery
*/
public void initializeNsd(NetworkDiscoveryHelperListener helperListener)
{
this.helperListener = helperListener;
initializeResolveListener();
initializeDiscoveryListener();
initializeRegistrationListener();
// mNsdManager.init(mContext.getMainLooper(), this);
}
private void initializeDiscoveryListener()
{
mDiscoveryListener = new NsdManager.DiscoveryListener()
{
#Override
public void onDiscoveryStarted(String regType)
{
Log.d(TAG, "Service discovery started");
helperListener.SERVICE_STARTED(regType);
}
#Override
public void onServiceFound(NsdServiceInfo service)
{
// A service was found! Do something with it.
Log.d(TAG, "Service discovery success" + service);
if (!service.getServiceType().equals(SERVICE_TYPE))
{
// Service type is the string containing the protocol and
// transport layer for this service.
Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
}
else if (service.getServiceName().contains(mServiceName))
{
// we have found our service! we use .contains because if
// there are multiple device with the same service being
// broadcast they will appear with name + (index)
// Resolve a discovered service. An application can resolve
// a service right before establishing a connection to fetch
// the IP and port details on which to setup the connection.
Log.d(TAG, "Found My Service Type: " + service.getServiceType() + service.getServiceName());
helperListener.SERVICE_FOUND(service);
mNsdManager.resolveService(service, mResolveListener);
}
/***************************************************************
* Checking the service name isn't always necessary, and is only relevant if you want to connect to a specific application.
* For instance, the application might only want to connect to instances of itself running on other devices. However, if the
* application wants to connect to a network printer, it's enough to see that the service type is "_ipp._tcp".
******************************************************/
}
/**
* when we lose our service
*/
#Override
public void onServiceLost(NsdServiceInfo service)
{
// When the network service is no longer available.
Log.e(TAG, "service lost" + service);
// remove the service
if (deviceManager.removeDevice(service) != null)
{
helperListener.SERVIVCE_LOST(service);
}
}
/**
* when our service is stopped
*/
#Override
public void onDiscoveryStopped(String serviceType)
{
Log.i(TAG, "Discovery stopped: " + serviceType);
helperListener.DISCOVERY_STOPPED(serviceType);
}
#Override
public void onStartDiscoveryFailed(String serviceType, int errorCode)
{
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
helperListener.DISCOVERY_START_FAILED(serviceType, errorCode);
mNsdManager.stopServiceDiscovery(this);
}
#Override
public void onStopDiscoveryFailed(String serviceType, int errorCode)
{
helperListener.DISCOVERY_STOP_FAILED(serviceType, errorCode);
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
mNsdManager.stopServiceDiscovery(this);
}
};
}
private void initializeResolveListener()
{
mResolveListener = new NsdManager.ResolveListener()
{
#Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode)
{
// Called when the resolve fails. Use the error code to debug.
Log.e(TAG, "Resolve failed" + errorCode);
helperListener.RESOLVE_FAILED(serviceInfo, errorCode);
}
#Override
public void onServiceResolved(NsdServiceInfo serviceInfo)
{
Log.e(TAG, "Resolve Succeeded. " + serviceInfo);
if (serviceInfo.getServiceName().equals(mServiceName))
{
Log.d(TAG, "Same IP.");
return;
}
mService = serviceInfo;
DiscoveredDevice device = new DiscoveredDevice(mService.getPort(), mService.getHost(), mService.getServiceName(), mService.getServiceType());
deviceManager.addDevice(device);
helperListener.RESOLVE_SUCCESS(serviceInfo);
}
};
}
private void initializeRegistrationListener()
{
mRegistrationListener = new NsdManager.RegistrationListener()
{
#Override
public void onServiceRegistered(NsdServiceInfo serviceInfo)
{
mServiceName = serviceInfo.getServiceName();
helperListener.SERVICE_REGISTERED(serviceInfo);
}
#Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
{
helperListener.SERVICE_REGISTRATION_FAILED(serviceInfo, errorCode);
}
#Override
public void onServiceUnregistered(NsdServiceInfo serviceInfo)
{
helperListener.SERVICE_UNREGISTERED(serviceInfo);
}
#Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
{
helperListener.SERVICE_UNREGISTRATION_FAILED(serviceInfo, errorCode);
}
};
}
/**
* To be called after initialize()
*
* #param port
* - the port you would like to register/broadcast the service through.
*/
public void registerService(int port)
{
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setPort(port);
serviceInfo.setServiceName(mServiceName);
serviceInfo.setServiceType(SERVICE_TYPE);
mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
}
/**
* Initiate service discovery to browse for instances of a service type. Service discovery consumes network bandwidth and will continue
* until the application calls stopServiceDiscovery(NsdManager.DiscoveryListener).
*/
public void discoverServices()
{
mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
/**
* Stop service discovery initiated with discoverServices(String, int, NsdManager.DiscoveryListener). An active service discovery is
* notified to the application with onDiscoveryStarted(String) and it stays active until the application invokes a stop service
* discovery. A successful stop is notified to with a call to onDiscoveryStopped(String).
*/
public void stopDiscovery()
{
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
/**
*
* #return - A class representing service information for network service discovery
*/
public NsdServiceInfo getChosenServiceInfo()
{
return mService;
}
/**
* Unregister a service registered through registerService(NsdServiceInfo, int, NsdManager.RegistrationListener). A successful
* unregister is notified to the application with a call to onServiceUnregistered(NsdServiceInfo).
*/
public void tearDown()
{
if (mNsdManager != null)
{
try
{
mNsdManager.unregisterService(mRegistrationListener);
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
*
* #return - the DiscoveredDevicesManager that contains all valid devices which have the appropriate service susally will call this
* after a msg of RESOLVE_SUCCESS
*/
public DiscoveredDevicesManager getDeviceManager()
{
return deviceManager;
}
}
and finally this is the basis of the server
#Override
public void run()
{
try
{
receiverSocket = new ServerSocket(0);
onPortObtained(receiverSocket.getLocalPort());
Log.d(TAG, "run");
while (broadcastConnection)
{
try
{
Socket newConnectionSocket = receiverSocket.accept();
onNewConnection(newConnectionSocket.getRemoteSocketAddress(), newConnectionSocket.getLocalSocketAddress());
// to clarify this line launches a function that starts threads to handle the socket.
recieveConnection(newConnectionSocket);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
Edit: one more thing, sometimes while running the devices will randomly restart. No common thing causing, other then they are running the app.
With the service discovery being just to difficult to handle, I will build my own discovery by doing a initial ping like so
List<DiscoveredDevice> devices = new ArrayList<DiscoveredDevice>();
for (int i = 0; i < 256; i++)
{
// this hardcoded ip will be variable from the wifi's ip
String ip = "xx.xx.x." + i;
// this socket may be forever hard coded unless i find a better way. :(
devices.add(new DiscoveredDevice(32999, ip, "", ""));
}
hitting all devices, registering every device that accepts, and every device that accepts registering it.
On leave it will dispatch a command to be removed from every devices queue, and upon trying to send a device a connection that does not get accepted it will be removed.
Hackish, but the Android way wasn't working for me :(, and this way works beautifully.

JAVA server and .Net client programming

I am doing communication with Java server.
One application which is developed in java and it runs on some ip,port.
e.g. 192.168.1.1 port 9090
No wi want to communicate to that server using my ASp .NET ( C# )
I have following scenario:
connection with server
once the data has been trasferred, i have to inform the server that my data transfer is complete. So after that the server will process the data and will revert me(respone).
Then i will have to read that data.
When i am using the NetworkStream class.
I have 1 method which i am using is write to send data.
But the server dont understand the complete data has been received or not.
So it continuously wait for the data.
So how to do this?
Maybe you could consider to use Eneter Messaging Framework for that communication.
It is the lightweight cross-platform framework for the interprocess communication.
The Java service code would look something like this:
// Declare your type of request message.
public static class MyRequestMsg
{
public double Number1;
public double Number2;
}
// Declare your type of response message.
public static class MyResponseMsg
{
public double Result;
}
public static void main(String[] args) throws Exception
{
// Create receiver that receives MyRequestMsg and
// responses MyResponseMsg
IDuplexTypedMessagesFactory aReceiverFactory = new DuplexTypedMessagesFactory();
myReceiver =
aReceiverFactory.createDuplexTypedMessageReceiver(MyResponseMsg.class, MyRequestMsg.class);
// Subscribe to handle incoming messages.
myReceiver.messageReceived().subscribe(myOnMessageReceived);
// Create input channel listening to TCP.
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexInputChannel anInputChannel =
aMessaging.createDuplexInputChannel("tcp://127.0.0.1:4502/");
// Attach the input channel to the receiver and start the listening.
myReceiver.attachDuplexInputChannel(anInputChannel);
System.out.println("Java service is running. Press ENTER to stop.");
new BufferedReader(new InputStreamReader(System.in)).readLine();
// Detach the duplex input channel and stop the listening.
// Note: it releases the thread listening to messages.
myReceiver.detachDuplexInputChannel();
}
private static void onMessageReceived(Object sender,
TypedRequestReceivedEventArgs<MyRequestMsg> e)
{
// Get the request message.
MyRequest aRequest = e.getRequestMessage();
... process the request ...
// Response back the result.
MyResponseMsg aResponseMsg = new MyResponseMsg();
... set the result in the response message ...
try
{
// Send the response message.
myReceiver.sendResponseMessage(e.getResponseReceiverId(), aResponseMsg);
}
catch (Exception err)
{
EneterTrace.error("Sending the response message failed.", err);
}
}
// Handler used to subscribe for incoming messages.
private static EventHandler<TypedRequestReceivedEventArgs<MyRequestMsg>> myOnMessageReceived
= new EventHandler<TypedRequestReceivedEventArgs<MyRequestMsg>>()
{
#Override
public void onEvent(Object sender, TypedRequestReceivedEventArgs<MyRequestMsg> e)
{
onMessageReceived(sender, e);
}
};
And the .NET client would look something like this:
public class MyRequestMsg
{
public double Number1 { get; set; }
public double Number2 { get; set; }
}
public class MyResponseMsg
{
public double Result { get; set; }
}
private IDuplexTypedMessageSender<MyResponseMsg, MyRequestMsg> myMessageSender;
private void OpenConnection()
{
// Create message sender.
// It sends string and as a response receives also string.
IDuplexTypedMessagesFactory aTypedMessagesFactory = new DuplexTypedMessagesFactory();
myMessageSender =
aTypedMessagesFactory.CreateDuplexTypedMessageSender<MyResponseMsg, MyRequestMsg>();
// Subscribe to receive response messages.
myMessageSender.ResponseReceived += OnResponseReceived;
// Create TCP messaging.
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexOutputChannel anOutputChannel =
aMessaging.CreateDuplexOutputChannel("tcp://127.0.0.1:4502/");
// Attach the output channel to the message sender and be able
// send messages and receive responses.
myMessageSender.AttachDuplexOutputChannel(anOutputChannel);
}
private void CloseConnection(object sender, FormClosedEventArgs e)
{
// Detach output channel and stop listening to response messages.
myMessageSender.DetachDuplexOutputChannel();
}
private void SendMessage()
{
// Create message.
MyRequestMsg aRequestMessage = new MyRequestMsg();
...
// Send message.
myMessageSender.SendRequestMessage(aRequestMessage);
}
private void OnResponseReceived(object sender,
TypedResponseReceivedEventArgs<MyResponseMsg> e)
{
// Get the response message.
MyResponseMsg aResponse = e.ResponseMessage;
.... process the response from your Java client ....
}

Does Smack work well in Java EE

Does Smack function properly in Java EE?? I am having issues with presence.
I get the credentials from the login form via doPost method..I can able to successfully authenticate as well as connection.getRoster() also works.Next I want to show only users who are online so when I get the presence of user,presence object stores default value "unavailable" for all users even when they are available!!
The whole chat app works without flaw in a normal java class without any change..
String userName = request.getParameter("username");
String password = request.getParameter("password");
HttpSession session=request.getSession();
session.setAttribute("username", userName);
SmackAPIGtalkServlet gtalk = new SmackAPIGtalkServlet();
ConnectionConfiguration config = new ConnectionConfiguration(
"talk.google.com", 5222, "gmail.com");
connection = new XMPPConnection(config);
config.setSASLAuthenticationEnabled(false);
try {
connection.connect();
} catch (XMPPException e) {
e.printStackTrace();
}
try {
connection.login(userName, password);
} catch (XMPPException e) {
e.printStackTrace();
}
System.out.println(connection.isAuthenticated());
boolean status = connection.isAuthenticated();
if (status == true) {
gtalk.displayOnlineBuddyList();
response.sendRedirect("Roster.jsp");
}
else
{
response.sendRedirect("Failed.jsp");
}
}
public void displayOnlineBuddyList() {
Roster roster = connection.getRoster();
Collection<RosterEntry> entries = roster.getEntries();
int count1 = 0;
int count2 = 0;
for (RosterEntry r : entries) {
Presence presence = roster.getPresence(r.getUser());
if (presence.getType() == Presence.Type.unavailable) {
// System.out.println(user + "is offline");
count1++;
} else {
System.out.println(name+user + "is online");
count2++;
}
}
roster.addRosterListener(new RosterListener() {
// Ignored events public void entriesAdded(Collection<String>
// addresses) {}
public void entriesDeleted(Collection<String> addresses) {
}
public void entriesUpdated(Collection<String> addresses) {
}
public void presenceChanged(Presence presence) {
System.out.println("Presence changed: " + presence.getFrom()
+ " " + presence);
}
#Override
public void entriesAdded(Collection<String> arg0) {
// TODO Auto-generated method stub
}
});
}
I am stuck with this and not able to get the code working with servlets..Can anyone help me out??
Will Smack work inside of Java EE, yes and no.
Smack will work inside of a web container, but since it creates its own threads it will NOT work inside of an EJB container. So it will work depending on where you are running it.
To understand some of your issues, you have to understand that the lifecycle of your objects in a servlet is tied to the request/response cycle of each request. This is not the same as a standard java app where the objects will typically live as long as you need them to, since you control their lifecycle.
For example, in the code you have shown, you create the connection for each request (I assume, since not all the code is shown). Therefore registering listeners against that connection will be pointless since it will pass out of scope as soon as you leave the method, and eventually get garbage collected. You will have to maintain the connections outside of the scope of the servlet requests for this to work, otherwise you will be opening and closing connections for each request.
XMPP is completely asynchronous by nature whereas servlet requests are synchronous. You have to put some effort in to making them work together, so don't expect code that works in a standalone app to simply work in this environment.
You have to implement the RosterListener interface in which you have to override the presenceChanged method in that you can get the presence of the users.
It works for me.
When you are getting the rosters of GTalk all will have status as unavailable.
But after sometime their presence changes and the presence can be get from the presenceChanged method in the RosterListner but for that you have to implement the RosterListener's presenceChnaged method.
And ya it works well in Java EE, Android as well as WAP.
Does Smack function properly in Java EE?? I am having issues with presence. I get the credentials from the login form via doPost method..I can able to successfully authenticate as well as connection.getRoster() also works.Next I want to show only users who are online so when I get the presence of user,presence object stores default value "unavailable" for all users even when they are available!! here my code
<%
Roster rst = roster;
rst.addRosterListener(new RosterListener() {
public void entriesAdded(final Collection args) {}
public void entriesDeleted(final Collection<String> addresses) {}
public void entriesUpdated(final Collection<String> addresses) {}
public void presenceChanged(final Presence presence) {
final Presence prsence1 = presence;
prsenceChanged(prsence1);
if (prsence1.isAvailable()) {
System.out.println("Is Available: " + presence.isAvailable());
}
}
});
%>
<%!void prsenceChanged(Presence presence){ if(null != presence){%>
<script language="javascript">
alert("hai");
</script>

Categories