Archived

This topic is now archived and is closed to further replies.

TreizeSG

[java] Same topic, new problem!!

Recommended Posts

I figured out what was going wrong, now I've either gotta stay with RMI and fix the problem, or scrap it altogether and go with java.net Basically, what happened was this: Whenever a user logged on, it sent a notice to the server saying, here I am, this is my name, this is my instance of the GAME class. This info was stored in a couple of java.util.Vectors, and any time I sent an update, whether it was the position of a player, or a message to display in the chatbox... all the games in the activePlayers Vector got notified. What I didn't realize is that, THOSE got notified. However, the clients were still sitting there waiting!! The Vector doesn't contain REFERENCES to those clients, it actually made a copy of the client's JavaRPG instance. So... here's my question to you. RMI isn't a two-way street is it? Clients can make a connection to the server, but the server can't talk to other clients, can it? If it can't, should I just go with java.net? That seems a bit difficult, based on streams and all, not like the wonderful OO'ness of RMI. [edited by - TreizeSG on August 11, 2003 11:27:08 AM]

Share this post


Link to post
Share on other sites
Are you doing any debugging? There seems to be some good spots in there to grab more info on what's going on.

In your catch block add a re.printStackTrace(). For all you know an exception is being thrown and no messages actually get sent. In the development phase stack traces are very nice things, always grab them from exceptions.

Are you sure you have added an action listener to your text field? I do that all the time, set up my action listener, get everything dandy, but never connect the two
Add a System.out line into actionPerformed to confirm it's really being called.

In putText add a line
System.out.println("Just received text: " + s);

That way, you a) know the method got called, b) know what argument it got called with.



[edited by - tortoise on August 7, 2003 12:30:57 PM]

Share this post


Link to post
Share on other sites
Actually, I did use println statements, I simply took them out for the sake of presentation. The server correctly searches through the users, and does send the message, it simply isn''t being displayed in the textbox. Quite ironically, if I tell the computer to

System.out.println(recieve.getText());

It gets the text that should be there. The computer thinks it''s in the box, but I don''t see anything...

Share this post


Link to post
Share on other sites
If the textarea reports it has the text, then it''s possible that it''s view just isn''t being updated. Try a call to repaint(). Sometimes the parent component (usually the JFrame or whatever) needs to call paintAll(getGraphics()) to really force a good flushing throughout the whole system.

Share this post


Link to post
Share on other sites
repaint() successfully fails to work.
What exactly is the paintAll() method. Is it possible that that''ll work even if repaint() doesn''t?

Share this post


Link to post
Share on other sites
the problem with repaint() is it''s just a request to repaint. The OS will repaint your component when it''s good and ready, and it''s possible to get in situations where it will never paint your component (although rare). In my experience, paintAll(getGraphics()), for whatever reason, does a better job forcing a repaint. paintAll(Graphics g) tells a component to paint itself and all of its subcomponents with the provided Graphics context.

Share this post


Link to post
Share on other sites
I don't know how well you know RMI, but when I used the println statements, they showed up in the server JVM, not the client. Do you think its something messed up with RMI and not repaint()?


EDIT: Any time the message is sent to the server, IT knows what's in the client's textArea. However, the client only prints out what is actually there. Uh... I'm confused *grabs head in agony* LOL server knows more about client than the client knows about the client, that's not good OOP

[edited by - TreizeSG on August 9, 2003 10:45:13 AM]

Share this post


Link to post
Share on other sites
=> send your code, it'll maybe be easier to find what's wrong.
If you send a message from the server and recieve it on the client correctly (or the opposite), then it should be correctly done with RMI. Else, it means it talks to itself. :-P

[edited by - misterx on August 9, 2003 8:57:35 AM]

Share this post


Link to post
Share on other sites
Both the server and the clients would have to be instances of Remote or UnicastRemoteObject to be able to do 2 way communication. And I think you''d have to manually check to make sure they don''t send stuff to themselves:

for(Enumeration e = remotes.elements(); e.hasMoreElements() {
...Game g = (Game)e.nextElement();
...if(g != this) g.send(crap);
}

Something like that. Sorry if this didn''t help, I kinda just skimmend your question...

Share this post


Link to post
Share on other sites
quote:
Original post by TreizeSG
RMI isn''t a two-way street is it? Clients can make a connection to the server, but the server can''t talk to other clients, can it?



You are correct that RMI is not a two-way street, sort of. What you are missing is that methods can have a return type. So what you can do is set up a thread to poll the server every second or whatever and get a String back from the server with the latest chat messages. Something like:

class MyThread extends Thread {
.
.
.

public void run() {
while(!done) {
String message= chatClassRMIInstance.update("username");
if(message!=null) {
//update client area

}
try {
Thread.sleep(1000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
.
.
.
}




First make it work,
then make it fast.

--Brian Kernighan

"I’m happy to share what I can, because I’m in it for the love of programming. The Ferraris are just gravy, honest!" --John Carmack: Forward to Graphics Programming Black Book

Share this post


Link to post
Share on other sites
Thanks CJ, that idea worked really well, however I have a few questions about it.

First, how would the computer tell which chat updates were "the latest" without reprinting the entire chatlog over again? Wouldn''t it be a bit inefficient to reprint the same thing in the chatbox over and over again, even if there was nothing new? I was thinking that the server could keep a StringBuffer and purge it every second, so that all the clients are guaranteed to get the messages, and you don''t have to keep reprinting a 100 line chatlog every second.

Secondly, although I''m able to display all of the fighters on the screen, regardless of what comp their playing from, no one can move their characters. It doesn''t take a friggin programmer to figure that this is a problem. I know this involves... the dreaded... MULTITHREADING!!! Can I start this thread separately from the main() thread in the JavaRPG class?

Share this post


Link to post
Share on other sites
For each message that comes in, keep it in a Vector


Vector messageList=new Vector();

public void processMessage(String newMsg) {
messageList.add(newMessage);
}


Then keep a pointer for each user that points to which message was the last one they retreived. When tehy asked for the latest messages, concatenate all the new ones together and update the pointer.

If you have a main game loop somewhere, you could start the chat thread before you enter the main loop, or you could build the updates as part of the loop.



First make it work,
then make it fast.

--Brian Kernighan

"I’m happy to share what I can, because I’m in it for the love of programming. The Ferraris are just gravy, honest!" --John Carmack: Forward to Graphics Programming Black Book

Share this post


Link to post
Share on other sites