Sign in to follow this  
Stelimar

[java] [Solved] Java String Troubles

Recommended Posts

Stelimar    102
I've been doing some networking stuff in Java lately, and I made a simple chat server where multiple users can register, login and chat with each other. Now I am trying to add the ability to notify users when someone else has logged in, and send the newly logged in user a list of all users currently logged in. The client then keeps a list of all users logged in. The following is the function called when a user logs in:
	public void loggedIn(User user) {
		//Notify all clients that the user logged in
		int userID = user.id;
		SocketChannel userSocket = user.getSocket();
		String[] params = new String[3];
		params[0] = Integer.toString(user.id);
		params[1] = user.name;
		params[2] = STATUS_LOGGED_IN;
		ModuleCommand command = new ModuleCommand(null,this.id,this.id,USER_STATUS,params);
		broadcast(command);
		//Send the user all other users currently logged in
		ListIterator i = users.listIterator();
		params[2] = STATUS_PREVIOUSLY_LOGGED_IN;
		while (i.hasNext()) {
			user = (User) i.next();
			if (user.id != userID) {
				params[0] = Integer.toString(user.id);
				params[1] = user.name;
				command.parameters = params;
				command.socket = userSocket;
				cHandler.sendCommand(command);
			}
		}
	}


The operation of my sockets are based on this tutorial. My problem is that the usernames that are sent are all the same. For example, if user1 logs in, then user2 logs in, then the server will send a "user1 logged in" command both times (I hope that makes sense). However, if I add a simple System.out.println(user.name) somewhere inside of the while loop, then the server sends the correct usernames. I'm thinking this has something to do with the fact that Java stores references to objects in variables rather than the objects themselves, and since the code which actually sends the command to the client is running in a separate thread, the string gets changed before the request is actually processed. However I can't for the life of me figure out an easy way to simply copy a string (and I don't even know for sure if that will fix it). I've tried changing
params[1] = user.name;

to
params[1] = String(user.name);

but I get the error "cannot find symbol : method String(java.lang.String)" which really confuses me, because the Java API reference lists String(String original) as a constructor. Any help would be greatly appreciated. -Stelimar [Edited by - Stelimar on November 19, 2008 11:24:31 PM]

Share this post


Link to post
Share on other sites
Codeka    1239
It's because you're using the same "params" array for both calls. Presumably your broadcast method does it's actualy work in a seperate thread...

You need to ensure the params is not modified before that thread finishes with it, and the simplest way would be to use a different array for each call:


public void loggedIn(User user) {
//Notify all clients that the user logged in
int userID = user.id;
SocketChannel userSocket = user.getSocket();
String[] params = new String[3];
params[0] = Integer.toString(user.id);
params[1] = user.name;
params[2] = STATUS_LOGGED_IN;
ModuleCommand command = new ModuleCommand(null,this.id,this.id,USER_STATUS,params);
broadcast(command);
//Send the user all other users currently logged in
ListIterator i = users.listIterator();
while (i.hasNext()) {
user = (User) i.next();
if (user.id != userID) {
String[] params2 = new String[3];
params2[0] = Integer.toString(user.id);
params2[1] = user.name;
params2[2] = STATUS_PREVIOUSLY_LOGGED_IN;
command.parameters = params2;
command.socket = userSocket;
cHandler.sendCommand(command);
}
}
}



By the way, the use of a string array for passing parameters seems rather, un-Javaish. The normal pattern would have a strong-typed sub-class of "ModuleCommand" for each different type of command you can send...

Share this post


Link to post
Share on other sites
Stelimar    102
I don't know why I thought of the String being changed but not the Array/ModuleCommand (both of which I needed to create new instances of). Thanks for the help, and the suggestion about handling the parameters. I got it working now =)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this