2017-02-28 1 views
0

Je suis relativement nouveau pour Common Lisp (SBCL) et Hunchentoot (en utilisant Quicklisp). Quelqu'un peut-il me dire comment je peux faire fonctionner ça? J'essaie d'enrouler un serveur Hunchentoot et certains chemins dans une fonction en tant qu'unité. Quand je lance ceci, seule la page d'index de Hunchentoot est disponible, les chemins/a et/b ne le sont pas.Dispatcheur Hunchentoot

(defun app0 (port) 
    (let ((*dispatch-table* nil) (server (make-instance 'hunchentoot:acceptor :port port))) 
    (push (hunchentoot:create-prefix-dispatcher "/a" (lambda() "a")) *dispatch-table*) 
    (push (hunchentoot:create-prefix-dispatcher "/b" (lambda() "b")) *dispatch-table*) 
    (hunchentoot:start server) server)) 
+0

'* dispatch-table *' est déjà une variable globale. –

Répondre

3

Il y a plusieurs problèmes, autant que je peux voir. Tout d'abord, demander la manipulation par *dispatch-table* exige que l'accepteur est de type easy-acceptor, à savoir, vous devrez

(make-instance 'easy-acceptor ...) 

Le documentation a les détails.

Le deuxième problème est que vous redéfinissez *dispatch-table* pendant le code d'installation et que vous insérez de nouvelles valeurs dans cette liaison. Étant donné que la liaison est rétablie après que le let est terminé (et que hunchentoot:start fonctionne de manière asynchrone), vos entrées dans *dispatch-table* sont effectivement perdues lorsque le serveur est en cours d'exécution. Essayez

(push (hunchentoot:create-prefix-dispatcher "/a" (lambda() "a")) *dispatch-table*) 
(push (hunchentoot:create-prefix-dispatcher "/b" (lambda() "b")) *dispatch-table*) 

au niveau supérieur (ou faites quelque chose comme ça dans une fonction d'installation dédiée). Si vous n'aimez pas l'approche globale *dispatch-table*, vous pouvez également créer une sous-classe de acceptor et remplacer acceptor-dispatch-request (et ainsi implémenter tout type de répartition que vous aimez). Juste comme une note de côté: vous ne préfixez pas *dispatch-table*, tandis que vous préfixez virtuellement tout autre symbole du paquet hunchentoot. Est-ce juste une erreur de copier/coller, ou est-ce aussi le cas dans votre code actuel? Si vous n'obtenez pas le paquet hunchentoot dans le paquet où votre code arrive à vivre, vous devez également qualifier la table de répartition comme hunchentoot:*dispatch-table*.

Modifier (pour répondre à la question dans la section commentaire) Il y a une example in the hunchentoot documentation, qui semble faire exactement ce que vous voulez faire:

(defclass vhost (tbnl:acceptor) 
    ((dispatch-table 
    :initform '() 
    :accessor dispatch-table 
    :documentation "List of dispatch functions")) 
    (:default-initargs 
    :address "127.0.0.1")) 

(defmethod tbnl:acceptor-dispatch-request ((vhost vhost) request) 
    (mapc (lambda (dispatcher) 
     (let ((handler (funcall dispatcher request))) 
     (when handler 
      (return-from tbnl:acceptor-dispatch-request (funcall handler))))) 
    (dispatch-table vhost)) 
    (call-next-method)) 

(defvar vhost1 (make-instance 'vhost :port 50001)) 
(defvar vhost2 (make-instance 'vhost :port 50002)) 

(push 
(tbnl:create-prefix-dispatcher "/foo" 'foo1) 
(dispatch-table vhost1)) 
(push 
(tbnl:create-prefix-dispatcher "/foo" 'foo2) 
(dispatch-table vhost2)) 

(defun foo1() "Hello") 
(defun foo2() "Goodbye") 

(tbnl:start vhost1) 
(tbnl:start vhost2) 

(commentaires présents dans la documentation supprimée par souci de concision) . Le tbnl est un pseudonyme prédéfini pour le package hunchentoot. Vous pouvez utiliser les deux de façon interchangeable, bien que je vous recommande, que vous en choisissez un et y adhérez. Mélanger les deux peut générer de la confusion.

+0

Merci pour votre réponse. Le premier/problème était une faute de frappe dans mon code, et je l'ai réglé sur easy-acceptor, je mettrai mon post à jour sous peu. La deuxième partie aide vraiment à éclaircir une certaine confusion que j'avais autour des liaisons et hunchentoot ne voyant pas ces routes. J'ai échoué à réaliser que les liaisons étaient en train d'être réinitialisées. Merci aussi pour la note de côté, je crains de ne pas avoir préfixé * dispatch-table * avec le nom du package. – rebnoob

+0

Je ne suis pas vraiment à la recherche de dispatching sophistiqué, donc je voudrais éviter de sous-classer accepteur et dans le processus introduire des erreurs. Ce que j'espérais accomplir était de pouvoir créer plusieurs instances d'un serveur fonctionnant sur différents ports avec des données spécifiques d'instance comme une connexion DB. Recommanderiez-vous le meilleur moyen de le faire? – rebnoob

+0

Ça marche, merci Dirk! – rebnoob