I would like to write a TCP Server class to handle essentially a basic IRC chat server. This would facilitate building from this application a lot of other things, but I would like to get a good base down first. Every user has unique name (ie. login required) Default input - goes to all users in current channel /who - shows all users in channel /msg <user> - sends message to specific user only /create <channel> /join <channel> /logout From my readings it seems evident that the end product should use 'thread pooling' of some kind, though I'm sure this wouldn't need to be implemented from the start. What I'm looking for is some guidance in the basic structures to implement this. I've written working TCP communication code before, so I understand all the syntax related, but am kind of lost in regards to handling multiple users updates. I obviously need to rely on the server to activly send new messages to clients as the telnet client will not be requesting info periodically. Well, here is what I have off the top of my head. Class: World main class, initiates server Contains list(vector?) of all connections Contains list(vector?) of all channels Contains queue(?) of server command requests Main loop initates server, then continiously processes server commands. Hrmm.. do I need a Command object? Probably as I plan on having a variety of commands. How do i make sure that once I process a command the client referred to in the command is still connected? Class: Server implements runnable Contains the .accept() loop thread. On accept sends client socket to World object Do I need a whole class just for this? Well, it does need to be runnable, could be an inner class of World I suppose. Class: Connection Holds client information (login name etc.) Holds thread that continually waits for .readline Then it parses that and creates a command and adds it to the World objects command queue. Who should parse the command, World, or Connection? I'm not sure.. Class: Channel I'm not sure if I should have this, I guess I should. It would contain the queue of messages for the channel and a vector of all the Connections for that channel. Just to clarify on messages queues. It's not my intent to have a queue to store all the messages in a channel and then send them all on a connect. The queue is just there because likely at somepoint we will be recieving messages faster then they can be broadcast to all users. So.. any suggestions? I haven't found a good networking book either that covers this kinds of design questions. Joe
You've described the situation quite well. I don't think you need a Command object, but it's not important. If the client you're sending the data (that is going on inside Connnection class) is disconnected - you'll get exception, you handle it and drop the connection. Also, IRC uses PING/PONG commands, so you have to have AT runner for sending/managing PING/PONG requests/answers. Yep, inner class for the Server is OK, and it may not be runnable. For commands parsing - I thnik connection should do it (calling some static method for it), so you can send an error back (queue error message) About Channel class - yes, I think it's good to have this, so when World is going through it's queue, it checks all Channels you have and send message to all Connections within Channel to which message belong. About message queues - I think one queue in World class is enough, so you put a request in a queue somehow, and then World finds out what channels this should go to.
------------------ With best of best regards, Pawel S. Veselov ( aka Black Angel )
With best of best regards, Pawel S. Veselov ( aka Black Angel )
You can thank my dental hygienist for my untimely aliveness. So tiny:
Free, earth friendly heat - from the CodeRanch trailboss