Hello!
This is my first post here, I hope I don't do anything wrong.
I'm currently working on a webchat for my website. In the past I tried a lot of different solutions but all either where using too much bandwith, too much CPU ressources or where simply too slow. Java applets are no alternative IMO. I knew that streaming chatservers would probably do the trick but I didn't have a lot of C knowledge (and I still don't). I tried creating a chatserver in Perl, but they either took almost as much ressources as CGI scripts (a forking server) or crashed all the time (a selective server). The answer seemed to be multithreading but no good thread support for Perl. :/ So I gave up, because I didn't have my own server anyway.
Now I'm back with a dedicated webserver I have access to and started thinking about this idea again, because more than 70% of my visitors want a webchat.
I had an idea. Instead of coding the whole chat in C (which would be a PITA for me especially because C probably isn't the most friendly language for string manipulation and dynamic webpages), I'm going for a mixed solution.
The chatserver (in C) will do nothing but serve connected chatters with a chatstream. The input and everything else will be handled by PHP scripts. I searched google and found a freeware (GPL) multithreaded webserver. It wasn't difficult to manipulate this server to send persistant streams to connected clients. Only downside of this server is though, that it is a little bit more complex than I need. It's spawning a lot of worker threads to server requests as fast as possible. Of course this isn't usefull if every connection is persistant anyway. Also the problem is that it doesn't accept new connections when all worker threads are used. :/ I will try to change that later to a simple server that does spawn one thread per connection. It would be cool if someone could show me some example code for this. But for now I just spawn enough worker threads to handle a lot of chatters and this works for testing...
I wanted to use MySQL for storing the chatdata but faced a problem of course. When all threads would poll the database constantly, the load would be unacceptable. So I had an idea. I just spawned another thread that is doing all the polls (once a second) and serves the result to connected clients. To make this possible, every client "registers" itself in a "chatter" structure array and the polling thread checks all elements of this array for connected chatters to send the messages to.
To my big surprise, this even worked! I can already connect with serveral clients to this server, type something at one client and a second later it's on the screen of all clients. The load is almost non-existant and the delay is at most one second (because of the 1 second intervall of the polling thread). I'm really proud of this. I shared all those details because I thought other people might also be interested in doing something like this (although many serious hackers dislike the idea of webchats in favor of IRC, etc, those are extremely popular).
I also hope that some of you can assist me a little bit.
I have mainly two big problems to face yet.
1) Convert this to "one-thred-per-connection" to allow unlimited numbers of connections without pre-spawning threads.
I would be really really happy to find some tutorial or example script about this.
2) Detect when a client is disconnected. Atm, every client who connects gets a new slot (there are 1000 of them so far) and then goes in an endless loop (also with a sleep(1) to make it easy on the server) and accepts new data from the polling thread. This never stops. And I have no clue how to find out if the client is still accepting data (connected). Can anyone give me some hints?
The loop currently looks something like this:
Code:
while(connected) {
// check the buffer for new text to send
if (strlen(chatter[myid].buffer) > 0) {
sprintf(sendbuf, "%s", chatter[myid].buffer);
sprintf(chatter[myid].buffer, "");
if(!write(sock, sendbuf, strlen(sendbuf)))
connected = 0; // doesn't work (never happens)
}
sleep(1);
}
I would really appreciate any help!
If someone wants to see the code, I could upload it.
My last problem is a minor one. Or more something like a question. ATM, my chatter struct array is a fixed array of 1000 elements. Of course I would prefer a dynamic array to support unlimited chatters. Do you think that's a good idea?
And let's say 30 chatters connected, so the array got 30 elements long, suddenly client number 15 disconnects. Can I remove element 15 and reduce the length to 29 elements again (shifting element 16-30 to 15-29) without too much overhead (it would have to be changed all the time)?
I fear I'm still a complete newbie in C.
TIA
Sorry for the long text...
Spark