📜 ⬆️ ⬇️

Python Web Preference

Not for the first decade, there has been a dispute between architects of desktop applications on the subject of which approach, statefull or stateless, is preferable, and in what cases.
Now we are witnessing a certain trend in the delivery of positions by statefull apologists. Not least the blame for not even the web, but banal HTTP, which deservedly occupied the niche of the “universal protocol for everything”. Moreover, the possibility of transferring a cookie has very little effect on its stateless nature.

But what HTTP can offer us, if necessary, to create an interactive application on the web? In order to achieve the “reactivity” of an offline statefull application, the classic version with constant polling of the server state with short AJAX timer requests is not enough. HTML5 brings us WebSockets technology designed to solve this problem. But you need to work "here and now" on all browsers released in the current millennium.

Comet comes to the rescue, with which we have attempted to implement a browser-based Russian preference with an instant reaction to events.
')
So, get acquainted. Club of intellectual games "Trelyazh"
trellis-club.com

Trellis


Choosing a framework


Two candidates were casting for the role of a low-level asynchronous library for the project.
Twisted and Tornado. Both have their pros and cons, the totality of which won the Tornado. It is significantly inferior to its opponent in features, and most unpleasantly, it doesn’t know how to make asynchronous requests to the database out of the box, but ... sane html-templates, resource managers, built-in authorization tools on openid servers, impressive performance, very convenient and simple interface for the application programmer to move the bowl to the other side.

The problem with the number of simultaneously open connections


Looking at the simple and understandable examples from the Tornado delivery, it becomes clear how to write interactive things very quickly, such as the simplest chat. One would like to immediately make several independent connections listening to different types of events. But, unfortunately, the reality is that such a scheme does not work. This is due to old browsers that cannot handle more than two AJAX requests at the same time.

In other words, if we want to make something more complicated than a banal chat, we will have to come up with and implement our high-level message delivery protocol that runs on top of JSON.

Authorization and Authentication


Novice developers often confuse these two concepts. But between them there is a fundamental difference. Roughly speaking, authentication is the procedure for determining whether this user is who he claims to be, and authorization, respectively, is a procedure for granting those or other rights to a user who has already passed the authentication procedure.

In the current server version, authorization is eliminated as unnecessary. All players are equal and not divided into any classes.

Authentication is completely at the mercy of the OpenID protocol. The tornado includes authentication classes via Facebook, Gmail, and other popular services. There is no problem to add access to the authentication services of the same LiveJournal.

In addition to simplifying the login for players (the tedious registration procedure with inventing passwords, and confirmation of email simply becomes unnecessary), this scheme is more secure for players. The administration will not know any passwords of players, and at the same time, the server is not threatened by the invasion of anonymous vandals.

Game cycle


The general scheme is as follows. An interactive page makes a long AJAX request. The server for each game table holds a pool of these requests and waits for events. An event can be anything. The player clicked on the card, wrote a chat message, a timeout occurred, the bullet count changed, and so on. When an event enters the queue, the server closes the connections of all listeners with the answer to what exactly happened. The client page accepts the message and decides what to do next. She can take data from the message and redraw some of her parts, can make a “short” AJAX request for additional data, can redirect to another page, but in the end she again sends a “long” AJAX request that is waiting for the next event, and the cycle resumes.

It often happens that several events occurred on the server at once, and for performance reasons, our protocol should be able to send events not only one by one, but several at once in one request. For example, the player made a move, this move was the last, and you need to immediately calculate the game. In this case, the server will send both events to all table listeners in one iteration.

Web site


In addition to directly playing tables, the project needs a website with a home page, rules, blogs, forums, statistics and other things. It was decided not to separate the gaming room and the website into independent entities, and to integrate the website into the server integrally.

Given that with such an organization, the site has access to all operational server caches (including players' caches online), this gives certain performance advantages and simplifies the task of programming the functionality of the site as much as possible.

Database


In single-threaded non-blocking servers, it is very important that there are no long-term synchronous operations when generating a response. Connecting to a database and synchronously waiting for SQL queries to complete is a very time-consuming operation.

This is usually bypassed using asynchronous database requests. Of the popular drivers, this mode of operation is supported, for example, by psycopg2. You can go ahead and use the services of "adult" ORM like SQL Alchemy, which can add a layer of asynchrony for almost any driver.

The alternative is to use a minimum database. Game processes occur entirely in the memory of the server. All statistics for viewing is cached wherever possible. Information about the played game is reset to the database after calculation only once. Sessions in the generally accepted understanding of web applications in the database are generally not needed with this model of building a server. The main page of the website does not create a single sql query. Everything is taken from operational caches.

Thus, we keep the simplicity of synchronous programming, reduce the list of dependencies, and DDOS protection is an added bonus. Requests from non-logged players in principle do not have access to resources capable of generating SQL queries.

Total information


In addition to the operational data of each table, the server stores data that should be accessible from any module. This, for example, a general list of players online, caches of the last viewed games, database pool, and so on. Data of this kind is collected in one module. It would seem that here it is. Finally, the Singleton pattern will find at least some use. But not everything is so simple. Firstly, timeouts from the threading system module are actively used inside the server. This means that all our caches must be thread-safe. That is, calls that change their contents will have to be wrapped in safe sections. On the other hand, we need an easy-to-use test mode in which the common data module should work quite differently. Therefore, Singleton goes where it belongs, and Facade comes to its position.

Timeouts


The timeout system is significantly simplified compared to existing native clients. The player presses the "set the table" button. At the same time, the table immediately goes into the "convention" state. All players in this room are sent an appropriate message, and they immediately see that the table status has changed. A covering box with jquery-ui means a dialog box in which it can select game conventions and the timer ticks on top. The default is 2 minutes. If the covering party hasn’t decided what it wants to play for, the window closes and the table returns to “free” status without any consequences for the player.

After the table is created, it goes into endless waiting for players. Players can come to the table, watch the conventions, sit at the table, get up from the table (in this case the place is vacated). If the last player rose from the table, then the table is completely vacated, and you can set another game on it.

But as soon as the last player sat down at the table (third or fourth, depending on how many people laid the table), the game starts immediately without any warnings. For any player action a specific time is allotted (its amount determines the table setting. By default, 5 minutes). If a player moves away or thinks for a very long time, he is penalized and the game closes. There are no player waiting modes or party transfers in the current version of the server. Any problems with communication or over time lie entirely on the shoulders of the player, who must be in turn, by all means.

Lovers of foul play


The only restriction is: One and the same player cannot sit at the same table twice. No more restrictions. If he has time to play at two, and more tables at the same time, then this is his right.

The “problem of cash”, widely known in narrow circles, is not solved by technical means (who needs it, they know about anonymous proxies, and it’s not a problem to raise several virtual machines). In this case, deanonymity, auditing, the system of reviews and rating of players is very important. When you play not with impersonal nicknames, but with real people who have a first and last name (provided by open-id consumer, and it is impossible to change them on the server), everything becomes much easier in this regard.

What's next?


At the moment the server is in the status of BETA-testing.
Located at trellis-club.com

Pleasant and addictive game.

Source: https://habr.com/ru/post/84439/


All Articles