I have an idea for how to implement a Comet server using the SWI http
library in combination with blocking event queues.
(Comet and the long-polling technique is explained here:
<
http://en.wikipedia.org/wiki/Comet_(programming)#Ajax_with_long_polling>
<
http://en.wikipedia.org/wiki/Push_technology#Long_polling> )
Here's my code for a (remarkably simple!) long-polling comet style
chat server (I won't show any client code here, but I would be happy
to contribute a complete demo package once I have cleaned it up abit):
:- use_module(library('http/thread_httpd')).
:- use_module(library('http/http_dispatch')).
:- use_module(library('http/http_parameters')).
:- use_module(library('http/json')).
:- use_module(library('http/http_json')).
:- use_module(library(thread_pool)).
:- thread_pool_create(cheapthreads, 30,
[ local(100), global(100), trail(100), backlog(100)]).
:- http_handler('/chat',
http_reply_file('chatroom.html', []),
[]).
:- http_handler('/chat/send', send, []).
:- http_handler('/chat/receive', receive, [spawn(cheapthreads)]).
send(Request) :-
http_parameters(Request,
[ from(From, []),
msg(Msg, [])
]),
forall((thread_property(Id, status(running)), integer(Id)),
thread_send_message(Id, event(From,Msg))).
receive(_Request) :-
thread_get_message(event(From, Msg)),
reply_json(json([from=From, msg=Msg])).
:- http_server(http_dispatch, [port(5000)]).
This is how it works: When a user client "enters the room" it
immediately sends a requests for receiving messages to the server. The
request is handled in its own (cheap) thread. The request will just
hang there (since the call to thread_get_message/1 blocks) until an
event appears on its queue (or until the server times out). Thus, each
client in the room is "represented" by a running thread, waiting for
someone to say something. If any client sends a message to the room,
the message is sent (in the form of an event) to all running threads
in the room. That will wake them up, and send JSON representing the
message back to the user clients. When this happens, the clients will
immediately send a new requests for receiving messages to the server.
It's clear that this is resource demanding and won't scale to lots of
users in the room. Still, I think the long-polling comet style
approach to building interactive applications is interesting and that
it has lots of potential applications besides chat servers. I do have
a number of questions though:
- Just HOW many connected clients could it scale to? (I guess it
depends on the hardware and OS, and I'd like to know which hardware
and OS would be best.) What would be the most sensible options for the
thread pool?
- Are there other less resouce demanding ways to achieve the desired
effects, i.e. ways avoiding the creation of one thread per client? I
looked briefly at the library(http/xpce_httpd.pl) docs and thought
that maybe I should take a closer look at that. Or is that a red
herring?
- I feel a bit uneasy about relying on the fact that (some) thread IDs
are integers. Do you see a more reliable way to determine which
threads "represent" connected clients?
- Any other suggestions for how to improve the code?
Thanks,
Torbjörn
--
Torbjörn Lager
Professor of General and Computational Linguistics
Department of Philosophy, Linguistics and Theory of Science
Box 200, SE-405 30 Göteborg, Sweden
Phone: +46317864413
_______________________________________________
SWI-Prolog mailing list
SWI-Prolog@...
https://mailbox.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog