I have been considering writing a chat application in java to see if I can do it. I am plannign to use RMI to send information back and forth between clients and servers but have a few questions about how to actually get this to work: I guess when the user clicks submit it sends the response to the server which saves the string into a vector and then the vector is returned to the client to be added to a JList If I have many clients connecting will they have access to the same vector and it will just keep building as people add text?? also can I use threads on the client to query from the server every 5 seconds or so to grab the vector and repaint the list box?? Is this gross inefficient? IS there a better design... please enlighten me.
I can't help thinking that it would be a bad idea to send the whole conversation backwards and forwards every time. Working from the assumption that once something is sent it will never be changed again, it seems wiser to just send new messages. How about the following rough design: The server system has a message store (a Vector in the simple case, or maybe a database for large conversations) of messages each with an associated timestamp. It provides a few simple interfaces:
submit a new message A supplied message is marked up with the timestamp and added to the store.
Get recent messages Return a Vector of all messages submitted since a specified time.
Get all messages Return a Vector or just a String of all the messages in the conversation so far. Used when someone joins the conversation, or if the client needs to refresh its display.
When the client joins a conversation it requests all the messages so far and displays them. From time to time it can request to see any new messages. When a message is submitted, the client sends it, and probably requests any new messages as well. Possible improvements to this model include sending a client current-time timestamp with each request, and the server comparing that with its notion of current time, and using the difference to adjust the timestamp supplied in a recent messages request. This would allow the design to cope with users in different timezones or with strangely configured computers. This design has the problem common to any "polling" design, that on a slow conversation many requests for new messages will be submitted which return no new data. The advantage it has is that no "logon/logoff" procedure is required. The server doesn't care how many clients are listening. This is a generally similar model to bulletin boards such as The Electric Porkchop. An alternative publish and subscribe design would have a client logging in to a conversation, and the server updating all participating clients whenever a new one arrives. This model would have the advantage that no empty requests are sent, but it isn't very tolerant of clients dropping connections or forgetting to log off. This model is similar to a typical mailing list. You are right in that the key to all this is the thread issues. The server must provide robustly multi-threaded access to a central data item, and the client will need to send requests, receive new messages and update the display all while the user is thinking or typing new messages. Let us know how you get on.
Ok- I got it up and running in a crude state. I used RMI for the clients to interact with the server...and I am using threads to refill the list box.... I am still passing the whole conversation around via a Vector... Still trying to think out the most efficient and easiest way to maybe only pass around an array of strings of newest messages.... How grossly inefficient is passing this whole conversation around?
How grossly inefficient is passing this whole conversation around? Depends on the size of the conversation. If the conversation has n entries, and someone submits a new message/requests an update they get n+1 messages back. So A converstaion with 100 entries will be use 100 times more bandwidth (on average) than just sending the added message. And this keeps growing. When the conversation reached 1000 messages, it's 1000 times less efficient. Just sending updates scales well with conversation size, whereas sending the whole conversation gets geometrically less efficient. And if there's one thing that is certain, it's that a conversation will grow. It's the whole point of the system.
Ok I got the chat up and mostly running. What I am doing is passing a Timestamp with text I add to the conversation and everytime the thread tries to get the conversations it sends a Timestamp... Then my method no the server checks for equal or after timestamps and returns the messages... The only thing is I believe my logic works, my chat room just doesn't always work.. It doesnt always retrieve all the messages it was missing from before and I can't figure out why....
OK- The code is up at http://www.geocities.com/SiliconValley/Screen/8348/ I used RMI to have clients connect to the server. The problem I have is that it works....sometimes! Sometimes it doesn't grab the most recent messages and send them to the client... and then later on it will start working. I haven't been able to figure out a pattern to this so I can't diagnose what is going on... any insight is much appreciated.
Here is another thing I was just thinking about and not sure how it could be accomplished as I think RMI might not be that course of action... How could one write a program so the Server new who the clients were and could differentiate them? Right now how my chat is written the server doesn't differentiate between clients... I am thinking on a larger scale say if I wanted to make a network trivia type game... how could I keep track of scores and who is who .... I think I would need to use sockets, but not sure how sockets can send objects?
How could one write a program so the Server new who the clients were and could differentiate them? There are two basic approaches. One is where each client knows some way to uniquely represent itself, and passes that to the server, with each request. The other is where the server can somehow tell enough about a client connection to deduce a unique identifier from it. The two approaches are appropriate for different environments. On a small local network with one workstation per user, a soecket server could use the IP address of the incoming request as a unique id, for example. In most real cases, it's best to use the client-knows approach, but there isn't really any easy and guaranteed way of deriving a unique id for a client, so supply the knowledge from the server. As a concrete example, consider the following user story: A user fires up the client software and contacts the server. The first response from the server is a "login" request. The client returns a user id, and maybe a password. The supplied user id is checked against the list of known users. The reply from the server is some sort of session id which the client software must then send back with each future request. Now for each following client request, the server always know "who" it is receiving the request from, and can log statistics or customize output as required. This approach gets round some otherwise not very obvious problems, like "what happens if two users are running the client software on the same machine at once?" and "what happens if the users are accessing the server through a firewall or other anonymity mechanism?" And, guess what? It's the mechanism used by this bulletin board!
I've seen this done with sockets instead of RMI. It followed the typical socket server pattern of starting a thread to service each client (which could be prohibitive with lots of clients) and simply echoed every incoming message to all connected clients. I kinda liked the idea of keeping old messages so a client could make a special request to get "previous n" or "since hh:mm" or all. Rather than keep all messages (which opens you up to some unfriendly client sending zillions and using all memory) I might keep the last "n" in a circular buffer.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Politics is a circus designed to distract you from what is really going on. So is this tiny ad: