When broadcasting live games so they could be followed through a web browser rather than needing download of a dedicated client, I have always made use of a JavaScript and polling through a XMLHttpRequest call (AJAX). The problem has always been that for low polling frequency the latency tends to be large, while fast polling easily overloads the server if many viewers are on line. The polling originally requested the game file for the game in progress, while the JavaScript at the client side then determined if any moves were added, and would display those if there were.
Now I want to extend this system to a server where people can actually play themselves through the browser. Access to the game file is controlled by a CGI 'script' (actually a compiled C binary), which allows users to 'upload' moves as part of the URL, which are then appended to the indicated game (also indicated in the URL). The polling can also be streamlined, by allowing the client to request only the tail of the game through the URL, i.e. suppress the sending of the first N moves that this client already has. This is good enough to set up a turn-based server, but would require an inconveniently high polling frequency if you would want to use it in live blitz or bullet games.
I would therefore like to have something better, but I know only little about web programming techniques. Some Googling suggested a technique that I am at least a bit familiar with, namely 'long polling'. The only difference with what I already do is that when a user would request (through the CGI script) the N+1st move from a game that currently only contains N moves, the script would not immediately sent an empty reply, but defers the reply (keeping the connection to the requesting client open) until such a move was added by the opponent. This is probably still inefficient, but at least every poll is now guaranteed to be a success (even if only after some time), while before there would typically be many poll requests before one finally retrieved a move.
This sort of displaces the problem, however, to the CGI script that was launched by the HTTP server on each request. This must somehow quietly wait for the next move in the game to arrive. You don't want it to waste server CPU by incessantly polling the game file to see if it has grown. Reading from a pipe- or socket-like connection would block execution until data arrives, but from a file you get EOF immediately if there is no data. So you could have the CGI script set up a socket connection to a constantly running server, which would then consider the client 'logged on', and push arriving moves immediately to clients that are waiting for them. It is a bit of a pain to set up a constantly running server, and having to make TCP connections to it.
Limiting myself to techniques that I know, a possibility would be this: a CGI script that gets a request that cannot be immediately satisfied would write its process ID to (an empty slot in) a file of logged-on clients, together with the ID of the game it wants to have the upcoming move of, and then put itself asleep for a reasonable time-out period. (And terminate unsuccesfully if that timeout ever expires, removing itself from the file again.) If a player submits a move through another instance of that same CGI script, the latter would add the move to the game file, and then read the file of waiting clients, checking if anyone was waiting for a move in that game. Every so waiting CGI process would then receive a Linux signal SIGINT to wake it up, after it would find a new move in the game file, and immediately forward it to the requesting client.
Would there be better ways to do this?
Making a web server for life broadcasts and playing
Moderator: Ras
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
Rémi Coulom
- Posts: 438
- Joined: Mon Apr 24, 2006 8:06 pm
Re: Making a web server for life broadcasts and playing
Do you known about web sockets?
https://en.wikipedia.org/wiki/WebSocket
https://en.wikipedia.org/wiki/WebSocket
-
stegemma
- Posts: 859
- Joined: Mon Aug 10, 2009 10:05 pm
- Location: Italy
- Full name: Stefano Gemma
Re: Making a web server for life broadcasts and playing
I'm developing an application WEB server in C++, based on HTTP, for a business applications. I simply use AJAX, because I don't have real-time requirements, at the moment. I've read the proposed web-socket solution but it seems not simple and maybe not guaranted, on any browser/firewall/proxy environment.
Maybe it would be enough, to broadcast games, to save the game in a stack with timestamp for any move, that the client can poll any laps of time, sending the timestamp that it want to watch from (the client current time, in fact, or the last required before). If there are multiple moves after the required timestamp, the server can send all or just one (at your choice). If you send the first move after the timestamp, then the client can ask immediately for a new one, if the move timestamp is very old, or just wait until the next laps of time. This way, if a client rest back because of heavy traffic, it can follow the full game with different laps from move to move but still in a complete way.
This won't works for playing bullet games between users/engines but for engines a direct socket protocol would be better (as on ICS).
Maybe it would be enough, to broadcast games, to save the game in a stack with timestamp for any move, that the client can poll any laps of time, sending the timestamp that it want to watch from (the client current time, in fact, or the last required before). If there are multiple moves after the required timestamp, the server can send all or just one (at your choice). If you send the first move after the timestamp, then the client can ask immediately for a new one, if the move timestamp is very old, or just wait until the next laps of time. This way, if a client rest back because of heavy traffic, it can follow the full game with different laps from move to move but still in a complete way.
This won't works for playing bullet games between users/engines but for engines a direct socket protocol would be better (as on ICS).
Author of Drago, Raffaela, Freccia, Satana, Sabrina.
http://www.linformatica.com
http://www.linformatica.com
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Making a web server for life broadcasts and playing
I stumbled on the Websockets too. But a quick read left me uncertain as to whether this is generally supported by every browser and every http server (e.g. lighttpd), nowadays. And it was not clear to me at all what I would have to do at the server side. What I read suggested that the Websocket would be using the http port, so that the http server would have to act as a 'reverse proxy'. But I still have no idea how I would have to set it up so that it would forward the connection to the actual server. Would it use a TCP connection to another port on localhost for that?Rémi Coulom wrote:Do you known about web sockets?
https://en.wikipedia.org/wiki/WebSocket
-
jdart
- Posts: 4423
- Joined: Fri Mar 10, 2006 5:23 am
- Location: http://www.arasanchess.org
Re: Making a web server for life broadcasts and playing
WebSockets is part of HTML 5 now. I would recommend this over CGI. CGI always reloads the whole page (or at least a frame, if you are using frames). That is expensive.
I could be wrong but I don't think you are going to need special server configuration unless the client is not going to directly hit your server through a socket connection to the URL you are serving the page from. That would be the case if you were using a load-balancer, caching proxy, or something like that.
(Addendum: see https://www.nginx.com/blog/websocket-nginx/ for one example of a load balancer/proxy that supports WebSockets).
--Jon
I could be wrong but I don't think you are going to need special server configuration unless the client is not going to directly hit your server through a socket connection to the URL you are serving the page from. That would be the case if you were using a load-balancer, caching proxy, or something like that.
(Addendum: see https://www.nginx.com/blog/websocket-nginx/ for one example of a load balancer/proxy that supports WebSockets).
--Jon
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Making a web server for life broadcasts and playing
Well, the way I was planning to use it the CGI script would send only the moves the client has not seen yet (which for a player could be at most the single move made by the opponent), or an error code to say it timed out. That would be at most a line of a dozen characters, or so. The efficiency issue is not so much communication bandwidth as load on the server machine, as for every CGI request the HTTP server would have to fork off a process to execute the CGI script.
Perhaps my lack of understanding of these Websockets stems from that I have no idea what the URL you connect to means. E.g.if my JavaScript would use the example on the html5rocks page:
what is supposed to be this 'echo' on the addressed machine? It must be something that is able to interactively react to what I will sent through that connection. So is it the name of an executable program somewhere on the server? And if it is, how should it communicate? Just via stdin and stdout, like a Chess engine? Would it be enough to put 'fruit' in the root of my server tree, to have clients that open a Websocket be able to send UCI commands into the Websocket, and get moves back?
Even if that was the case, it still would not tell me how I could connect to an already running process, like an ICS.
Perhaps my lack of understanding of these Websockets stems from that I have no idea what the URL you connect to means. E.g.if my JavaScript would use the example on the html5rocks page:
Code: Select all
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
Even if that was the case, it still would not tell me how I could connect to an already running process, like an ICS.
-
jdart
- Posts: 4423
- Joined: Fri Mar 10, 2006 5:23 am
- Location: http://www.arasanchess.org
Re: Making a web server for life broadcasts and playing
There are many Websocket server technologies and which one you use depends on what back-end server you like and what language you prefer.
If you are using Apache, mod_proxy_wstunnel can direct your Websockets requests to your choice of server.
https://github.com/google/pywebsocket is an apache mod and standalone server that uses Python.
There are many other solutions, for Node.js (server-side JavaScript), Java, PHP, etc.
--Jon
If you are using Apache, mod_proxy_wstunnel can direct your Websockets requests to your choice of server.
https://github.com/google/pywebsocket is an apache mod and standalone server that uses Python.
There are many other solutions, for Node.js (server-side JavaScript), Java, PHP, etc.
--Jon
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Making a web server for life broadcasts and playing
I am currently using Lighttpd on my rented VPS, as use of Apache led to complaints by the company from which I rent that it was too memory intensive, and caused excessive swapping. But do I understand correctly that it is likely that I would have to install some extra module at the server to allow the handling of Websocket requests, and that I somehow have to learn how to configure that so that the file-name part of the URL will be mapped onto a server port of my choice? E.g. onto port 5000, where an ICS is running on the same machine, and then communicate with the Websocket as if it was a direct TCP/IP connection to that ICS?
-
jdart
- Posts: 4423
- Joined: Fri Mar 10, 2006 5:23 am
- Location: http://www.arasanchess.org
Re: Making a web server for life broadcasts and playing
Yes, that is basically it. A script could do the mapping or the server itself, if all you have to do is pass the request along.
--Jon
--Jon
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Making a web server for life broadcasts and playing
What I like about the long-polling appoach is that it is automatically robust against disconnects. You would make a new connection for every move anyway. When the server is not only used to relay moves, but also relays chat messages, you can already start a new poll request as soon as you received the opponent's move, even though it is your turn at that point, as you might want to receive chat even during your own turn. Then for a real-time game there would always be a long-polling request pending for at least one of the players of the game (while the other is only briefly interrupted when data is pushed to a playing client until he renews it). This could be used to recognize the game as 'active', and thus to treat decide whether polling from observers beyond the current game end should be deferred as long polling or should return an immediate negative result. Or to allow clients to request a list of currently active games.