Smack Presence Doesn't Work - java

Actually I programming a IM service (inherited google chat) by using smack API. But when i want to print buddy list and their presences, the compile mode show all presences unavailable, but in the debug mode it shows the real availability!
My code is ...
1- create connection
public boolean openConnection() {
ConnectionConfiguration connectionConfiguration = new ConnectionConfiguration("talk.google.com", 5222, "mail.google.com");
this.connection = new XMPPConnection(connectionConfiguration);
try {
this.connection.connect();
} catch (XMPPException e) {
// TODO: Send Error Information To Programmer's Email Address
}
if(this.connection.isConnected()) {
this.roster = this.connection.getRoster();
this.roster.addRosterListener(new RosterListener() {
public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {}
});
return true;
}
return false;
}
2- login
public boolean login(String jid, String password) {
try {
this.connection.login(jid, password, "smack");
} catch (XMPPException e) {
// TODO: Send Error Information To Programmer's Email Address
}
if(this.connection.isAuthenticated()) return true;
return false;
}
3- buddy list
public void buddiesList() {
Collection<RosterEntry> rosterEntries = this.roster.getEntries();
for(RosterEntry rosterEntry: rosterEntries) {
System.out.println(rosterEntry.username() + " === " + this.roster.getPresence(rosterEntry.getUser()));
}
}
4- implementation
public static void main(String args[]) {
IMService imService = new IMService();
imService.openConnection();
imService.login("google account", "password");
imService.buddiesList();
}

Your RosterListener doesn't do anything. This is where you have to put code to update your roster when things like presence messages are received.
The presence you are retrieving is a snapshot in time of what the state was when it was created. To keep the state current, you have to actually code the RosterListener. This is clearly stated in the Javadoc for the getPresence() method.

Adding a Listener to your roster could be better:
https://www.igniterealtime.org/builds/smack/docs/latest/documentation/extensions/rosterexchange.html

Related

SignalR java client can't invoke method and send data

I created a basic selfhosted SignalR server with the following code:
class Program
{
static void Main(string[] args)
{
// This will *ONLY* bind to localhost, if you want to bind to all addresses
// use http://*:8080 to bind to all addresses.
// See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx
// for more information.
string url = "http://localhost:8080";
using (WebApp.Start(url))
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
}
Which is taken from: https://learn.microsoft.com/en-us/aspnet/signalr/overview/deployment/tutorial-signalr-self-host and works with the Javascript client.
I am now trying to create a Java client and got the following code that is simply supposed to send a message to the server:
String host = "http://localhost:8080";
HubConnection connection = new HubConnection(host);
HubProxy proxy = connection.createHubProxy("MyHub");
connection.start();
try {
System.out.println("Sendng message...");
proxy.invoke( "Send", "Client", "Hello world!" ).get();
System.out.println("Message sent!");
} catch (InterruptedException e) {
System.out.println("err1");
// Handle ...
} catch (ExecutionException e) {
System.out.println("err2");
// Handle ...
}
The problem that im having is that the message is not received by the server, it seems like the code is stuck at the invoke call and doesn't print the Hello world! message. Does someone know what im doing wrong?
hubProxy.invoke("sendMessageByUser", Message, WebApiToken).done(new Action<Void>() {
#Override
public void run(Void aVoid) {
if (aVoid != null)
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyApplicationService.this, "Mesaj gönderildi", Toast.LENGTH_SHORT).show();
}
});
}
}).onError(new ErrorCallback() {
#Override
public void onError(final Throwable error) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MyApplicationService.this.getApplicationContext(), "Bir hata oluştu" + error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
});

why am i getting an error on .verifyCredentials()

I want to get the data using twitter's fabric api but whenever i tend to verify credentials and use a callback it shows an error , specifically ,"The arguments differ in length"
void getUserData() {
Twitter.getApiClient(session).getAccountService()
.verifyCredentials(true, false, new Callback<User>() {
#Override
public void failure(TwitterException e) {
}
#Override
public void success(Result<User> userResult) {
User user = userResult.data;
String twitterImage = user.profileImageUrl;
try {
Log.d("imageurl", user.profileImageUrl);
Log.d("name", user.name);
Log.d("email",user.email);
Log.d("des", user.description);
Log.d("followers ", String.valueOf(user.followersCount));
Log.d("createdAt", user.createdAt);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
If you check the fabric documentation, it shows two version of the method, however when I tried to open the source code in Android Studio but it had only the version without the callback.
You can solve the isssue as follows:
//Getting the account service of the user logged in
Call<User> call = Twitter.getApiClient(session).getAccountService()
.verifyCredentials(true, false);
call.enqueue(new Callback<User>() {
#Override
public void failure(TwitterException e) {
//If any error occurs handle it here
}
#Override
public void success(Result<User> userResult) {
//If it succeeds creating a User object from userResult.data
User user = userResult.data;
String twitterImage = user.profileImageUrl;
try {
Log.d("imageurl", user.profileImageUrl);
Log.d("name", user.name);
Log.d("email",user.email);
Log.d("des", user.description);
Log.d("followers ", String.valueOf(user.followersCount));
Log.d("createdAt", user.createdAt);
} catch (Exception e) {
e.printStackTrace();
}
}
});
Source
Documentation
Just change the twitter dependency in your Build.Gradle
from
compile('com.twitter.sdk.android:twitter:2.0.0#aar') {
transitive = true;
}
to
compile('com.twitter.sdk.android:twitter:1.11.0#aar') {
transitive = true;
}
The new version of the .verifyCredentials() method doesn't accept a callback hence your error.

Kryonet not receiving custom classes

I'm trying to set up a basic client and server to get the hang of networking, but I'm running into a problem.
Whenever I send a class with one of my own classes as a variable, the server does not receive it. I can use a string/int/etc for the variable perfectly fine but whenever a variable of my own type is included it is not received, along with all objects I try to send after it.
Everything is registered with Kryo. Am I just missing something? Any help is appreciated!
From GameClient:
public GameClient(String name) {
client = new Client();
client.start();
NetworkManager.register(client);
listener = new ClientListener();
client.addListener(listener);
try {
client.connect(5000, "24.207.67.56", NetworkManager.port);
} catch (Exception e) {
e.printStackTrace();
}
Login login2 = new Login();
User user2 = new User(name);
login2.user = user2;
login2.name = user2.name;
client.sendTCP(login2); // server does not recieve this
Login login = new Login();
login.name = user.name;
client.sendTCP(login); // server receives this only when it is sent before the Login containing the User
}
From GameServer :
public GameServer() {
server = new Server();
NetworkManager.register(server);
listener = new ServerListener(server);
server.addListener(listener);
try {
server.bind(NetworkManager.port);
} catch (IOException e) {
e.printStackTrace();
}
server.start();
}
In ServerListener:
#Override
public void received(Connection c, Object o) {
System.out.println("recieved");
if (o instanceof Login) {
System.out.println("[SERVER] " + ((Login) o).name + " logged in.");
LoginResult lr = new LoginResult();
lr.result = true;
c.sendTCP(lr);
}
}
From NetworkManager:
public static void register(EndPoint endPoint) {
Kryo kryo = endPoint.getKryo();
kryo.register(Login.class);
kryo.register(User.class);
}
public static class Login {
public User user;
public String name;
}
User:
public class User {
public String name;
public User(String name) {
this.name = name;
}
}
So it turns out that the problem was caused by the lack of default constructor in the User class. Removing the User(String name) constructor or adding a plain User() constructor fixes the issue.
It would be useful if it threw an error when you tried to do it incorrectly, but oh well.

Why the roster isn't added on both the sides?

user-a sends a subscription request to user-b. Subscription mode has been set to accept_all. Also, packet listener has been registered for both the users.
When user-a sends a request to user-b this method is called :
private void searchUser(java.awt.event.ActionEvent evt) {
try {
String userToSearch = jTextField1.getText();
if(!xmppParamInit) {
initUXmppP();
xmppParamInit = true;
}
Presence subscribe = new Presence(Presence.Type.subscribe);
userToSearch += "#localhost";
subscribe.setTo(userToSearch);
ofConnection.sendPacket(subscribe); // Send the 'subscribe' packet
}catch(Exception exc) {
exc.printStackTrace();
}
}
Prior to this method, following are called :
private void startPLThread() { // start packet-listener-thread
Runnable r = new Runnable() {
#Override
public void run() {
startPL();
}
};
new Thread(r,"packet listener thread").start();
}
private void startPL() {
PacketListener pListener = new PacketListener() {
#Override
public void processPacket(Packet packet) {System.out.println("Inside process packet");
if(packet instanceof Presence) {
Presence presence = (Presence) packet;
Presence subscription = new Presence(Presence.Type.subscribe);
subscription.setTo(presence.getFrom());
System.out.println("presence.getFrom : " + presence.getFrom());
ofConnection.sendPacket(subscription);
}
}
};
PacketFilter pFilter = new PacketFilter() {
#Override
public boolean accept(Packet packet) {
return true;
}
};
ofConnection.addPacketListener(pListener, pFilter);
}
The problem is user-a can see user-b in his roster but user-b cannot see user-a in its roster. I do not understand the reason for this. What could be the problem ?
Subscription mode has been set to accept_all in this method that is called from within search user :
private void initUXmppP() { // Initialize user-xmpp-parameters
Roster roster = ofConnection.getRoster();
roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
}
It is a GUI application and I tried keeping both the users online

How to get DN and password with UnboundID

I need some help concerning UnboundID. I heard it was a great choice but I'm not really used to it.
So I need to make a LDAP listener. On this listener, i should be able to catch bind request (from a ldap browser for example). I wonder how to get the DN and the password. Here is my code for the LDAP listener:
public ResultCode CreateLdapServer () throws LDAPException {
CannedResponseRequestHandler requestHandler = new CannedResponseRequestHandler();
LDAPListenerConfig config =
new LDAPListenerConfig(4243, requestHandler);
try
{
config.setListenAddress(
InetAddress.getByName("localhost"));
}
catch (final Exception e)
{
System.err.println("Unable to create the listen server.");
return ResultCode.PARAM_ERROR;
}
listener = new LDAPListener(config);
try
{
listener.startListening();
System.out.println("Serveur is listening ...");
}
catch (final Exception e)
{
System.err.println("Unable to start listening.");
return ResultCode.LOCAL_ERROR;
}
return ResultCode.SUCCESS;
}
public static void main(String[] args) throws LDAPException {
MyConnection connect = new MyConnection();
connect.CreateLdapServer();
}
I read a lot of UnboundID documentation, but i can't find any simple example of what I need.
Also, i'm not really sure of the utility of CannedResponseRequestHandler. For what i need, is it enough ?
An other question: I'm not sure, but I have the feeling that my server is not listening OR i don't catch anything (when I connect with a ldap Browser, nothing happened). Any Idea / Suggestion ?
Thanks and have a nice day !
EDIT : Thanks to xhochy, I was able to catch the password and the username. As he said, I subclassed LDAPListenerRequestyHandler to override, first, newInstance then ProcessBindRequest. Here is the code (it's absolutely not perfect and it's still a beginning).
public class MyConnection {
private LDAPListener listener;
public MyConnection(){
}
public ResultCode CreateLdapServer() throws LDAPException {
MyLDAPListenerRequestHandler requestHandler = new MyLDAPListenerRequestHandler();
LDAPListenerConfig config =
new LDAPListenerConfig(4243, requestHandler);
try
{
config.setListenAddress(
InetAddress.getByName("localhost"));
}
catch (final Exception e)
{
System.err.println("Unable to create the listen server.");
return ResultCode.PARAM_ERROR;
}
listener = new LDAPListener(config);
try
{
listener.startListening();
System.out.println("Serveur is listening ...");
}
catch (IOException e)
{
System.err.println("Unable to start listening.");
return ResultCode.LOCAL_ERROR;
}
return ResultCode.SUCCESS;
}
public static void main(String[] args) throws LDAPException {
MyConnection connect = new MyConnection();
connect.CreateLdapServer();
}
}
Then the subclass of LDAPListenerRequestHandler:
public class MyLDAPListenerRequestHandler extends LDAPListenerRequestHandler {
#Override
public LDAPListenerRequestHandler newInstance(
LDAPListenerClientConnection arg0) throws LDAPException {
System.out.println("New Instance.");
LDAPConnectionOptions option = new LDAPConnectionOptions();
LDAPConnection connection = new LDAPConnection(option, "yourIPadress", yourport);
System.out.println("Connected to : " + connection.getConnectedAddress()+ " " + connection.getConnectedPort());
return this;
}
#Override
public LDAPMessage processBindRequest(int arg0, BindRequestProtocolOp arg1,
List<Control> arg2) {
System.out.println(arg1.getBindDN());
System.out.println(arg1.getSimplePassword());
return null;
}
}
Thanks again !
Many LDAP server implementations will not return a password and many will not return a password you can use. (ie it maybe a hash).
I would be very curious why there could be a reason to return the password.
-jim
You should subclass LDAPListenerRequestHandler and implement processBindRequest. All the information you are looking for is included in BindRequestProtocolOp (second argument of processBindRequest). Add an empty implementation for all other abstract methods.
If request is your BindRequestProtocolOp instance then you get your information via:
String username = request.getBindDN();
ByteString password = request.getSimplePassword();

Categories