• Welcome to Valhalla Legends Archive.
 

Designing and implementing a my own chat client and chat server.

Started by Sorc.Polgara, June 20, 2006, 02:20 PM

Previous topic - Next topic

Sorc.Polgara

Ok.  Since I'm bored as hell this summer I've decided to write my own very simply web-based chat client and server using my own custom chat protocol.  I've already decided to write it in Java.

Now I don't think I'll have much of a problem designing and implementing my own custom chat protocol because I plan using the BNLS or BNCS protocol as a kind of guide, more or less.

However I'm in need of tips, advice, and suggestions on how to design a basic chat server that is robust enough that I'll have the option to make it more complex with relative ease if I ever decide to in the future.  I lack knowledge in server design (even basic server design) so any tips, suggestions, and advice would be appreciated.

I don't have any specific questions at the moment, but I will very soon.

EDIT:

Question #1:  There are at least three main parts to this project:  Designing and implementing the server, client, and chat protocol.  Since all three are very interconnected, it makes sense to design the chat protocol first, the server second, and the client last, while still keeping in mind how the design of one affects the others?

Banana fanna fo fanna

No way man, that's totally opposite of what you want to do.

Architect it such that you have methods like Chatroom.sayAloud(), User.whisper(), and onWhisper() etc. Then have those specific classes call methods on a Server object (i.e. onWhisper(), onTalkAloud() etc), and have it call event handlers on the Users on the server. At this point, you have a system with no notion of message passing except for methods and calls. Next, refactor it such that rather than having Chatroom and User call methods on Server, construct a Message object (preferably a subclass depending on what message you're sending) and pass it to Server.onMessage(), who will then construct another Message and pass it to User.onMessage(). Now finally at this point you can start thinking about the protocol. Rather than passing the message, write Message.serialize() and class Message.deserialize(byte[]) and pass byte[]'s rather than Message instances. Then, replace the passing of objects with reading/writing of byte arrays from a network stream, and you're good to go.

Also, a word of advice for all your networked apps: no matter what anyone tells you, don't put any significant logic in threads. You'll have one Thread per connection, and its only job should be to read and dump Message instances into a queue for the main thread (which runs all the logic) to process.

Ender

Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
Ok. Since I'm bored as hell this summer I've decided to write my own very simply web-based chat client and server using my own custom chat protocol.
Web-based? You mean with applets as the client and servlets/JSP as the server? This can run into a lot of complications... for instance you need to sign applets in order for them to have access to remote (and maybe even local) resources. I'd recommend just using plain old sockets, but perhaps I misunderstood you and that is what you meant.

Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
I've already decided to write it in Java.
The sensible choice ;-) </java promotion>

Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
Now I don't think I'll have much of a problem designing and implementing my own custom chat protocol because I plan using the BNLS or BNCS protocol as a kind of guide, more or less.
You can also use RMI, which is a Java framework that abstracts protocols and allows client programs to invoke methods on server programs by shipping bytecode over the network. Just another option.

Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
However I'm in need of tips, advice, and suggestions on how to design a basic chat server that is robust enough that I'll have the option to make it more complex with relative ease if I ever decide to in the future. I lack knowledge in server design (even basic server design) so any tips, suggestions, and advice would be appreciated.
If you don't have a solid education in design patterns and in-depth OOP, I'd recommend reading up on it.

Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
Question #1: There are at least three main parts to this project: Designing and implementing the server, client, and chat protocol. Since all three are very interconnected, it makes sense to design the chat protocol first, the server second, and the client last, while still keeping in mind how the design of one affects the others?
Well, it's a tradeoff. I think you should create quick test client/server programs with a basic protocol to just get going -- like a class or two in each program. The danger of writing the client first is that you cannot easily test it against the server. I think you should write the server first, personally. As for the protocol... you should design your programs so that you can easily change protocol without affecting anything else.

Quote from: Banana fanna fo fanna on June 20, 2006, 05:15 PM
Also, a word of advice for all your networked apps: no matter what anyone tells you, don't put any significant logic in threads. You'll have one Thread per connection, and its only job should be to read and dump Message instances into a queue for the main thread (which runs all the logic) to process.
For the server, use non-blocking IO -- no question about it. Non-blocking IO doesn't require multithreaded socket management (a single thread would suffice, but the rest of your program of course will probably be multithreaded) because the IO operations don't block -- that is, there are no infinite loops that sends, receives, and acceptances. Servers using blocking IO won't be able to handle many clients because there will be too many threads... after you get 10 clients, you will have significant performance deficiencies.  iago has a great non-blocking IO package, which he calls socket_manager. I've used it a lot in my programs, and I've found it very reliable. I recommend using this. Java provides support for non-blocking (or more generically, block io -- block io != blocking io) IO in the java.nio package, which iago used in his socket_manager package.

For the client, I'd also recommend non-blocking IO, as I find it easier to manage and more extensible (for instance, if you want to connect to multiple services). Blocking IO is very much possible for the client, as you will usually only be connected to one server, but I still prefer non-blocking IO.

Banana fanna fo fanna

There's not too much of a difference using nonblocking I/O and threads with very little state in them.

Ender

Non-blocking IO allows for far more clients than blocking IO and is "cleaner." It doesn't matter how little state the threads have; they still eat up unnecessary CPU cycles.

Banana fanna fo fanna

Quote from: Ender on June 22, 2006, 07:22 PM
It doesn't matter how little state the threads have; they still eat up unnecessary CPU cycles.

I disagree.

MyndFyre

Quote from: Ender on June 20, 2006, 10:59 PM
Quote from: Sorc.Polgara on June 20, 2006, 02:20 PM
Now I don't think I'll have much of a problem designing and implementing my own custom chat protocol because I plan using the BNLS or BNCS protocol as a kind of guide, more or less.
You can also use RMI, which is a Java framework that abstracts protocols and allows client programs to invoke methods on server programs by shipping bytecode over the network. Just another option.
The problem with RMI is that you are locked into Java, which may be inappropriate.  You can get around this if you use SOAP, but that's terribly wasteful IMO.

You'll probably want to look into using the Socket class's .select() method.  I know iago knows how it works in Java.  It's much more efficient than multithreading, especially once you get into large-sized servers.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Sorc.Polgara

Where is this socket_manager package?  I don't see it in the JavaOp2 source... so is it elsewhere?