tornado est un serveur http non bloquant. Pour l'utiliser, nous utiliserons le framework tornado, la base de données mongodb et le moteur (le pilote asynchrone de mongodb) pour implémenter simplement la fonction non bloquante de tornado
Téléchargement et installation pris en charge par d'autres environnements
1 Installer mongodb
$ sudo apt-get install update $ sudo apt-get install mongodb
<. 🎜>
2. Installer le moteur$ pip install motor
# conf.py import os import motor from handlers import index, auth BASE_DIR = os.path.join(__file__) handlers = [ (r'^/$', index.IndexHandler), (r'^/auth/register$', auth.RegisterHandler), (r'^/auth/login$', auth.LoginHandler), ] settings = dict( debug = True, template_path = os.path.join(BASE_DIR, 'templates'), static_path = os.path.join(BASE_DIR, 'static'), ) client = motor.MotorClient("127.0.0.1") db = client.meet
Connectez-vous d'abord à la base de données dans le fichier de configuration, db_name dans client.db_name est le nom de la base de données
# handlers/__init__.py class BaseHandler(tornado.web.RequestHandler, TemplateRendering): def initialite(self): ... @property def db(self): return self.application.db
Ajoutez db() et utilisez la décoration de propriété pour accéder à la base de données comme une propriété
# auth.py import os import time import tornado.web from tornado import gen from . import BaseHandler class RegisterHandler(BaseHandler): def get(self): self.render_html('register.html') @tornado.web.asynchronous @gen.coroutine def post(self): username = self.get_argument('username', None) email = self.get_argument('email', None) password = self.get_argument('password', None) data = { 'username': username, 'email': email, 'password': password, 'timestamp': time.time() * 1000, } if username and email: yield self.db.user.insert(data) self.redirect('/') class LoginHandler(BaseHandler): @tornado.web.asynchronous @gen.coroutine def get(self): username = self.get_argument('useranme') user = yield self.db.user.find_one({'username': username}) self.render_html('login.html', user=user)
@gen.coroutine decoration fait la fonction. non bloquant et renvoie un contrôleur généré au lieu d'utiliser une fonction de rappel. Le moteur s'implémente également de manière asynchrone via le rendement (sinon, il devrait renvoyer une fonction de rappel. En fait, cet exemple ne reflète pas le problème de blocage. le temps est trop court.
Modifions le code# 之前 yield self.db.user.insert(data) # 之后 yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 10)
L'application est bloquée ici via tornado.ioloop.IOLoop.instance(). add_timeout. Il s'agit d'une implémentation non bloquante de time.sleep. Si time.sleep est utilisé ici car Tornado est monothread et bloquera l'intégralité de l'application, donc les autres gestionnaires ne pourront pas y accéder
Vous pouvez le voir. après m'être inscrit sur la page d'inscription, j'ai cliqué sur /auth/login pendant la période de blocage et j'ai directement accédé à la page de connexion pour terminer le processus non bloquant
<🎜. >Je rencontre souvent des problèmes lors de l'utilisation de tornado. Je noterai les problèmes rencontrés et les solutions (Merci ici de m'avoir aidé à répondre à mes doutes. pythonistas)
Problème
Je souhaite implémenter une fonction d'utilisateur enregistré. Le framework Web utilise la base de données tornado et mongodb mais une erreur de redirection d'exception se produit lors de l'enregistrement. Collez maintenant le code :
. Je voulais accéder à la page d'inscription si l'utilisateur saisit le code de vérification de manière incorrecte, mais le problème est que si le code de vérification est incorrect, il continuera à exécuter le code tout en ajoutant self.finish après self. .redirect mettra fin au code, car il y a déjà self.finish dans la fonction self.redirect, il y a deux codes signalant une terminaison anormaleclass Register(BaseHandler): def get(self): self.render_html('register.html') @tornado.web.aynchronous @gen.coroutine def post(self): username = self.get_argument('username') email = self.get_argument('email') password = self.get_argument('password') captcha = self.get_argument('captcha') _verify_username = yield self.db.user.find_one({'username': username}) if _verify_username: self.flash(u'用户名已存在', 'error') self.redirect('/auth/register') _verify_email = yield self.db.user.find_one({'email': email}) if _verify_email: self.flash(u'邮箱已注册', 'error') self.redirect('/auth/register') if captcha and captcha == self.get_secure_cookie('captcha').replace(' ',''): self.flash(u'验证码输入正确', 'info') else: self.flash(u'验证码输入错误', 'error') self.redirect('/auth/register') password = haslib.md5(password + self.settings['site']).hexdigest() profile = {'headimg': '', 'site': '', 'job': '', 'signature':'', 'github': '', 'description': ''} user_profile = yield self.db.profile.insert(profile) user = {'username': username, 'email': email, 'password': password, 'timestamp': time.time(), 'profile_id': str(user_profile)} yield self.db.user.insert(user) self.set_secure_cookie('user', username) self.redirect('/')
2. Solution
Ou
return self.redirect('/auth/register')
self.redirect('/auth/register') return
Self. terminer, bien sûr, ne sortira pas de la fonction, sinon que se passe-t-il si vous voulez faire quelque chose une fois la demande terminée ?
Résumé
Parce que vous-même. .finish était par erreur Le problème ci-dessus se produit lors de l'utilisation d'une fonction de sautself.redirect définira l'emplacement dans request.headers pour le saut
self.finish fermera la demande, mais le fera ne saute pas de la fonction
Pour plus d'articles liés au framework Tornado de Python implémentant un accès asynchrone non bloquant à la base de données, veuillez faire attention au site Web PHP chinois !