Initiation au Lua


Télécharger Initiation au Lua

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Initiation au Lua ressource de formation complet [Eng]

...

Installation

Vous pouvez utiliser LuaRocks pour installer Turbo sur Linux.

Luarocks installer turbo

Si l'installation échoue, assurez-vous d'avoir les pacakages requis:

apt-get installer luajit luarocks git construire-essentiel libssl-dev

Pour Windows, utilisez le fichier install.bat inclus. Cela va installer toutes les dépendances: Visual Studio, git, mingw, gnuwin, openssl en utilisant Chocolatey. LuaJIT, le gestionnaire de paquets LuaRocks et Turbo seront installés sur C: \ turbo.lua. Il installera également LuaSocket, LuaFileSystem et LuaSec avec LuaRocks. L'environnement Windows sera prêt à utiliser en cas de succès.

Essayez: luajit C: \ turbo.lua \ src \ turbo \ examples \ helloworld.lua

Si l'un des fichiers .dll ou. soâ € ™ s sont placés à un emplacement autre que celui par défaut, puis utilisez les variables d'environnement pour pointer vers l'endroit correct:

Exemple: SET TURBO_LIBTFFI = C: \ turbo.lua \ src \ turbo \ libtffi_wrap.dll et SET

TURBO_LIBSSL = C: \ Program Files \ OpenSSL \ libeay32.dll

S'applique uniquement aux systèmes d'exploitation Linux et OSX:

Turbo.lua peut également être installé par le Makefile inclus. Il suffit de télécharger et d'exécuter make install (requiert le privilège root). Il est installé dans le répertoire par défaut des modules Lua 5.1 et LuaJIT 2.0.

Vous pouvez spécifier votre propre préfixe en utilisant make install PREFIX = <préfixe>, et vous pouvez spécifier la version de LuaJIT avec un paramètre de style LUAJIT_VERSION = 2.0.0.

Pour compiler sans support pour OpenSSL (et les connexions SSL), utilisez l'option make SSL = none. Pour compiler avec le support axTLS au lieu d'OpenSSL, utilisez l'option make SSL = axTLS.

En substance, le toolkit peut fonctionner depuis anywere, mais il doit être capable de charger le libtffi_wrap.so lors de l'exécution. Pour vérifier une installation, vous pouvez essayer d'exécuter les applications dans le dossier examples.

...

Objet orienté Lua

Turbo.lua sont programmés de manière orientée objet. Il y a plusieurs façons de faire l'orientation des objets dans Lua, cette bibliothèque utilise le module Middleclass. Qui est documenté à ... Middleclass est utilisé en interne dans Turbo Web, mais est également exposé à l'utilisateur lors de l'héritage de classes telles que le turbo. classe web.RequestHandler. Middleclass est un très léger, rapide et très facile à apprendre si vous êtes habitué à Python, Java ou C ++.

...

Tutoriels

9.1 Premiers pas avec Turbo

Un ensemble d'exemples simples pour vous aider à utiliser Turbo. 9.1.1 Installer Turbo

Turbo a besoin de LuaJIT pour s'exécuter, car il utilise la librairie LuaJIT FFI, il ne fonctionnera pas sur le /officiel / normal / vanilla? Lua. Installation rapide sur Debian / Ubuntu (vous devrez peut-être ajouter sudo ou les exécuter en tant qu'utilisateur root):

$ apt-get installer luajit luarocks git construire-essentiel libssl-dev $ luarocks installer turbo

Vous pouvez également installer Turbo utiliser le Makefile inclus dans la source du projet:

$ git clone ...$ cd turbo && faire l'installation

Vous pouvez fournir un argument PREFIX à make qui installera Turbo dans un répertoire spécifié.

Pour les utilisateurs Windows, il est recommandé d'utiliser le fichier install.bat inclus ou d'exécuter la commande d'une ligne ci-dessous à partir d'une ligne de commande administrative. Attention, cela va compiler et installer toutes les dépendances: Visual Studio, git, mingw, gnuwin, openssl en utilisant Chocolatey. LuaJIT, le gestionnaire de paquets LuaRocks et Turbo seront installés sur C: \ turbo.lua. Malheureusement, il est nécessaire d'avoir Visual Studio pour utiliser efficacement LuaRocks sur Windows. LuaRocks sera utilisé pour installer LuaSocket et LuaFileSystem. L'environnement Windows sera prêt à être utilisé en cas de succès, et les commandes luajit et luarocks seront dans votre environnement Windows PATH.

powershell -command "& {iwr ... master / install.bat -OutFile t.bat}" && t.bat

9.1.2 Bonjour tout le monde

Le traditionnel et obligatoire "Monde des Hello" â € "¢

- Importer le turbo,

turbo local = besoin ("turbo")

- Créez un nouveau requesthandler avec une méthode get () pour HTTP GET.

local HelloWorldHandler = class ("HelloWorldHandler", turbo.web.RequestHandler) fonction HelloWorldHandler: get ()

self: écrire ("Bonjour tout le monde!")

fin

- Créez un objet Application et liez notre HelloWorldHandler à la route '/ hello'. application locale = turbo.web.Application: new ({

{"/ Bonjour", HelloWorldHandler}

})

- Définissez le serveur à écouter sur le port 8888 et démarrez l'ioloop. application: écouter (8888)

turbo.ioloop.instance (): start ()

Enregistrez le fichier sous helloworld.lua et exécutez-le avec luajit helloworld.lua.

9.1.3 Paramètres de la demande

Un exemple un peu plus avancé, un serveur faisant écho au paramètre de demande «nom».

turbo local = besoin ("turbo")

HelloNameHandler local = class ("HelloNameHandler", turbo.web.RequestHandler)

function HelloNameHandler: get ()

- Obtenir l'argument 'nom', ou utiliser 'Père Noël' s'il n'existe pas nom local = self: get_argument ("nom", "Père Noël")

self: write ("Bonjour" .. nom .. "!")

fin

function HelloNameHandler: post ()

- Récupère l'argument 'name', ou utilise 'Easter Bunny' s'il n'existe pas. Name local = self: get_argument ("nom", "Easter Bunny")

self: write ("Bonjour" .. nom .. "!")

fin

application locale = turbo.web.Application: new ({{"/ hello", HelloNameHandler}})

application: écouter (8888)

turbo.ioloop.instance (): start ()

9.1.4 Itinéraires

Turbo a une fonction de routage agréable utilisant l'appariement de motifs Lua. Vous pouvez affecter des classes de gestionnaire aux routes du constructeur turbo.web.Application.

turbo local = besoin ("turbo")

- Gestionnaire qui ne prend pas d'argument, tout comme dans l'exemple du monde hello local IndexHandler = class ("IndexHandler", turbo.web.RequestHandler) function IndexHandler: get ()

self: write ("Index ..")

fin

- Gestionnaire qui prend un seul argument 'nom d'utilisateur'

userHandler local = class ("UserHandler", turbo.web.RequestHandler) function UserHandler: get (nom d'utilisateur)

self: write ("Nom d'utilisateur est" .. nom d'utilisateur)

fin

- Gestionnaire qui prend deux entiers comme arguments et les ajoute .. local AddHandler = class ("AddHandler", turbo.web.RequestHandler) function AddHandler: get (a1, a2)

self: write ("Le résultat est:" .. tostring (a1 + a2))

fin

application locale = turbo.web.Application: new ({

- Aucun argument, fonctionne pour 'localhost: 8888' et 'localhost: 8888 /' {"/ $", IndexHandler},

- Utilisez la partie de l'URL après / user / comme premier argument de - UserHandler: get

{"/user/(.*)$", UserHandler},

- Trouver deux int séparés par un '/' après / ajouter dans l'URL - et les passer en arguments à AddHandler: get

{"/ add / (% d +) / (% d +) $", AddHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

9.1.5 Traitement de fichiers statiques

Itâ € ™ s souvent utile de pouvoir servir des actifs statiques, au moins à des fins de développement. Turbo rend cela très facile avec le turbo.web.StaticFileHandler intégré, il suffit de spécifier un répertoire, et il fera le gros du travail, ainsi que de mettre en cache vos fichiers pour des performances optimales.

turbo local = besoin ("turbo")

app = turbo.web.Application: new ({



- Servir des fichiers statiques depuis / var / www en utilisant la route "/ static / (chemin vers fichier)" {"/static/(.*)$", turbo.web.StaticFileHandler, "/ var / www /" }

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

9.1.6 Sortie JSON

Turbo a une conversion JSON implicite. Cela signifie que vous pouvez passer une table JSON-serializable à self: write et Turbo définira l'en-tête TypeContent-Type à l'application / json. "¢ et sérialiser la table pour vous.

turbo local = besoin ("turbo")

- Gestionnaire qui répond avec '{"bonjour": "json"}' et un Content-Type d'application /, json

local HelloJSONHandler = class ("HelloJSONHandler", turbo.web.RequestHandler) fonction HelloJSONHandler: get ()

self: write ({hello = "json"})

fin

application locale = turbo.web.Application: new ({{"/ hello", HelloJSONHandler}})

application: écouter (8888)

turbo.ioloop.instance (): start ()

9.2 Modules asynchrones

L'utilisation de modules natifs au lieu de modules Lua génériques est importante lors de l'utilisation de sockets pour communiquer avec des bases de données, par exemple, pour obtenir les meilleures performances, car les modules génériques se bloqueront pendant des opérations longues. Si les opérations que vous effectuez sont relativement rapides, vous pouvez utiliser un module générique. C'est quelque chose que vous devez vous comparer dans vos cas spécifiques.

Créer des modules pour Turbo en utilisant les classes IOStream hautement abstraites est vraiment facile. S'il n'y a pas de pilote pour, par exemple, une base de données, etc., veuillez essayer de le faire.

9.2.1 Aperçu

Il existe plusieurs façons d'implémenter des modules asynchrones dans Turbo.lua. Pour lister les plus apparents:

  • Utilisation des rappels
  • Utilisation des fonctions d'emballage de Coroutine
  • Utilisation de Coroutines et de la classe CoroutineContext

Lequel convient le mieux à votre module. Sachez qu'au moment de l'écriture, aucune fonction dans l'espace de noms Lua Coroutine n'est inline par LuaJIT. Au lieu de cela, il revient à l'interprète très rapide. Donc, si chaque petite performance compte, les rappels sont la voie à suivre. Tous les modules de la structure de base utilisent des fonctions wrappables Coroutine, à l'exception de HTTPClient, qui utilise des coroutines et la classe CoroutineContext.

Les modules basés sur les rappels sont probablement la saveur la plus utilisée auparavant. Fondamentalement, vous prenez un rappel (et peut-être un argument de rappel / userdata) comme argument (s) pour les fonctions de votre module. Cette fonction est appelée lorsque les E / S ont été complétées. Cela signifie que l'utilisateur de votre module doit soit diviser son flux de programme en fonctions séparées (apparemment en parties) ou créer des fermetures à l'intérieur des fonctions.

Coroutine wrappable fonctions signifie que les fonctions de votre API adhère strictement à la convention où les deux derniers arguments d'une fonction sont toujours un callback ET un argument de rappel (l'argument est passé comme premier argument dans le callback fourni lorsqu'il est appelé I / O achèvement). Si, et seulement si ces conditions sont remplies, les utilisateurs de votre module peuvent utiliser la fonction turbo.async.task pour envelopper la fonction et utiliser la fonctionnalité intégrée Lua yield. Ces fonctions prennent en charge à la fois le style de rappel et la programmation de rendement.

Coroutine directement avec la classe CoroutineContext n'offre pas d'API compatible avec les callbacks, et les utilisateurs du module doivent toujours céder à la boucle d'E / S. Cela a quelques avantages en ce sens qu'il crée un 100% «Je ne me soucie pas de cet environnement de choses async.

Par programme, cela peut être illustré comme suit: «Je ne me soucie pas de ce module async stuff»:

turbo local = nécessite "turbo"

turboredis local = besoin de "turbo-redis"

local rconn = turboredis.connect ("127.0.0.1", 1337)

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler) function ExempleHandler: get ()

self: write ("La valeur est" .. rconn: get ("myvalue"))

fin

application locale = turbo.web.Application ({{"^ / ​​$", ExampleHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

Module de type rappel:

turbo local = nécessite "turbo"

turboredis local = besoin de "turbo-redis"

local rconn = turboredis.connect ("127.0.0.1", 1337)

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler)

function ExempleHandler: get ()

local _self = self

rconn: get ("myvalue", fonction (val)

_self: write ("La valeur est" .. rconn: get ("myvalue"))

fin)

fin

application locale = turbo.web.Application ({{"^ / ​​$", ExampleHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

Module de type callback avec argument de rappel et pas de fermeture, probablement connu pour ceux qui connaissent Python et Tornado.

turbo local = nécessite "turbo"

turboredis local = besoin de "turbo-redis"

local rconn = turboredis.connect ("127.0.0.1", 1337)

function ExampleHandler: _process_request (données) self: write ("La valeur est" .. données)

fin

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler) function ExempleHandler: get ()

rconn: get ("myvalue", ExampleHandler._process_request, self)

fin

application locale = turbo.web.Application ({{"^ / ​​$", ExampleHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

Coroutine wrappable Module de type callback:

turbo local = nécessite "turbo"

turboredis local = besoin de "turbo-redis"

tâche locale = turbo.async.task rendement local = coroutine.yield

local rconn = turboredis ("127.0.0.1", 1337)

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler) function ExempleHandler: get ()

self: write ("La valeur est" .. yield (tâche (turboredis.get (rconn, "myvalue"))))

fin

application locale = turbo.web.Application ({{"^ / ​​$", ExampleHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

Le plus facile à utiliser est probablement le premier, où le flux de programme et les chemins de code sont plus faciles à suivre. Le HTTPClient intégré utilise ce style d'API ... Il est probablement aussi un bon choix pour les requêtes de base de données, etc, de sorte que vous pouvez garder votre logique propre et facile à suivre.

Tous les rappels ajoutés à la boucle d'E / S sont exécutés dans sa propre routine. Les fonctions de rappel peuvent renvoyer l'exécution à la boucle d'E / S. Les rendements de Lua peuvent renvoyer un objet quand il revient à l'endroit où la coroutine a démarré ... Ceci est utilisé dans la boucle d'E / S de Turbo.lua qui traitera des rendements différents en fonction de ce qu'ils retournent car ils rendement. La boucle d'E / S prend en charge ces retours:

 · Une fonction, qui sera appelée à l'itération suivante et ses résultats retournés lors de la reprise du thread coroutine.

 · Nil, un rendement vide qui reprendra simplement le fil coroutine à la prochaine itération.

 · Une classe CoroutineContext, qui agit comme une référence à la boucle d'E / S qui permet de gérer manuellement le thread coroutine et de le reprendre à la demande.

9.2.2 Exemple de module

Gardons cela à l'esprit, créons un module CouchDB.

Nous allons créer celui-ci avec une API qui supporte le style de programmation business as usual où le programmeur ne cède pas ou ne contrôle pas ce flux par lui-même. Notez qu'il ne s'agit en aucun cas d'un module complet et stable, il est uniquement destiné à donner quelques indications:



...

- Ecrivez l'en-tête HTTP de la requête pour diffuser et attendez de finir en utilisant le moyen simple ~ â € "avec l'enveloppe turbo.async.task

-- fonction.

coroutine.yield (turbo.async.task (self.iostream.write, self.iostream, buf))

- Attendre la fin de l'en-tête de réponse HTTP.

local res = coroutine.yield (turbo.async.task (self.iostream.read_until_pattern,, self.iostream, "\ r? \ n \ r? \ n"))

- Décoder l'en-tête de réponse.

response_headers local = turbo.httputil.HTTPParser (res, turbo.httputil.hdr_t [~ "HTTP_RESPONSE"])

- Lisez le corps actuel maintenant que nous connaissons la taille du corps. corps local = coroutine.yield (turbo.async.task (

self.iostream.read_bytes,

self.iostream,

tonumber ((response_headers: get ("Content-Length")))))

- Décoder le corps de la réponse JSON et le renvoyer à l'appelant. local json_dec = turbo.escape.json_decode (body) return json_dec

fin

--- Ajouter plus de méthodes :) retour canapé

Utilisation depuis un turbo.web.RequestHandler:

turbo local = nécessite "turbo"

canapé local = nécessite "turbo-couch"

- Créer une instance.

local cdb = couch.CouchDB ("localhost: 5984")

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler) function ExempleHandler: get ()

- Écrivez la réponse directement à travers.

self: write (cdb: get ("/ test / toms_resource"))

fin

turbo.web.Application ({{"^ / ​​$", ExampleHandler}}): écoute (8888) turbo.ioloop.instance (): start ()

...

Documentation de l'API

10.1 Version de l'API Turbo.lua

10.1.1 Préliminaires

Tous les modules sont requis dans turbo.lua, donc il suffit de

turbo local = besoin ('turbo')

Toutes les fonctionnalités sont placées dans l'espace de noms «turbo». 10.1.2 Version du module

La version Turbo Web est de la forme A.B.C, où A est la version majeure, B est la version mineure, et C est la version micro. Si la version micro est zéro, elle est omise de la chaîne de version.

Lorsqu'une nouvelle version ne corrige que des bogues et qu'elle n'introduit pas de nouvelles fonctionnalités ou fonctionnalités, la version micro est incrémentée. Lorsque de nouvelles fonctionnalités sont ajoutées de manière compatible avec les versions précédentes, la version mineure est incrémentée et la version micro est mise à zéro. Lorsqu'il y a des modifications incompatibles en arrière, la version majeure est incrémentée et les autres sont mises à zéro.

Les constantes suivantes spécifient la version actuelle du module:

turbo.MAJOR_VERSION, turbo.MINOR_VERSION, turbo.MICRO_VERSION Numéros spécifiant respectivement les versions majeure, mineure et micro.

turbo.VERSION Une représentation sous forme de chaîne de la version actuelle, par exemple "1.0.0" ou "1.1.0".

turbo.VERSION_HEX Une représentation hexadécimale à 3 octets de la version, par ex. 0x010201 pour la version 1.2.1 et 0x010300 pour la version 1.3.

10.2 turbo.web - Framework web de base

Le framework Web Turbo.lua est calqué sur le framework proposé par Tornado, basé à nouveau sur web.py et sur la webapp de Google. Quelques modifications ont été apportées afin de mieux s'intégrer dans le système Lua eco. Le framework Web utilise des fonctionnalités asynchrones qui lui permettent d'évoluer vers un grand nombre de connexions ouvertes (milliers). Le cadre prend en charge l'interrogation de la comète.

Créer un serveur Web qui écoute le port 8888 et imprime le monde canoncial Hello sur une requête GET est très simple:

turbo local = besoin ('turbo')

local ExampleHandler = class ("ExampleHandler", turbo.web.RequestHandler) function ExempleHandler: get ()

self: write ("Bonjour tout le monde!")

fin

application locale = turbo.web.Application ({

{"^ / ​​$", ExempleHandler}

})

application: écouter (8888)

turbo.ioloop.instance (): start ()

10.2.1 Classe RequestHandler

Classe RequestHandler de base. Le coeur de Turbo.lua. Le flux habituel d'utilisation de Turbo.lua est de sous-classer la classe Re-questHandler et d'implémenter les méthodes de requête HTTP décrites dans self.SUPPORTED_METHODS. L'objectif principal de cette classe est d'emballer une requête HTTP et d'offrir des utilitaires pour répondre à la demande. Les requêtes sont adressées à RequestHandler par la classe Application. La classe RequestHandler est implémentée afin qu'elle soit sous-classée pour traiter les requêtes HTTP.

Il est possible de modifier self.SUPPORT_METHODS pour ajouter du support pour d'autres méthodes si cela est souhaité. Points d'entrée

RequestHandler: on_create (kwargs)

Redéfinissez cette méthode si vous voulez faire quelque chose directement après l'initialisation de la classe. Ceci est appelé après qu'une demande a été reçue et avant que la méthode HTTP n'ait été vérifiée par rapport aux méthodes prises en charge. Donc, si une méthode non supportée est demandée, cette méthode est toujours appelée.

Paramètres kwargs (Table) - Les mots-clés avec lesquels vous initialisez la classe.

RequestHandler: prepare ()

Redéfinissez cette méthode si vous voulez faire quelque chose après l'initialisation de la classe. Cette méthode, contrairement à on_create, n'est appelée que si la méthode a été trouvée supportée.

RequestHandler: on_finish ()

Appelé après la fin d'une demande. Utile pour, par exemple, une routine de nettoyage.

RequestHandler: set_default_headers ()

Redéfinissez cette méthode pour définir les en-têtes HTTP au début de toute la requête reçue par RequestHandler. Par exemple définir un certain type de cookie ou ajuster la clé du serveur dans les en-têtes serait judicieux de faire dans cette méthode.

Sous-classe RequestHandler et implémenter l'une des méthodes suivantes pour gérer la requête HTTP correspondante. Si elles ne sont pas implémentées, elles fourniront un 405 (méthode NotAllowed). Ces méthodes reçoivent des arguments variables, en fonction de ce que l'instance d'application qui les appelle a capturé à partir de la correspondance de modèle de l'URL de requête. Les méthodes sont protégées, elles sont donc sans erreur. Lorsqu'une erreur se produit dans l'exécution de ces méthodes, la réponse à la question 500 Internal Server Error est donnée. En mode débogage, la trace de la pile menant au crash fait également partie de la réponse. Si le mode débogage n'est pas défini, seul le code d'état est défini.

RequestHandler: get (...) Gestionnaire de reqests HTTP GET.

Paramètres .. - Paramètres du modèle d'URL correspondant avec des accolades. E.g /users/(.*)$ fournirait n'importe quoi après / users / en tant que premier paramètre.

RequestHandler: post (...) Gestionnaire HTTP POST reqests.

Paramètres .. - Paramètres du modèle d'URL correspondant avec des accolades.

RequestHandler: head (...) HTTP HEAD demande un gestionnaire.

Paramètres .. - Paramètres du modèle d'URL correspondant avec des accolades.

RequestHandler: delete (...) Gestionnaire de reqests HTTP DELETE.

Paramètres .. - Paramètres du modèle d'URL correspondant avec des accolades.

RequestHandler: put (...) Gestionnaire de requêtes HTTP PUT.



199