2017-02-28 53 views
0

我是Common Lisp(SBCL)和Hunchentoot(使用Quicklisp)的新手。有人能告诉我如何让这个工作?我试图将一个Hunchentoot服务器和一些路径包含在一个函数中作为一个单元。当我运行这个时,只有Hunchentoot的索引页面可用,路径/ a和/ b不是。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 *'已经是一个全局变量。 –

回答

3

据我所见,存在多个问题。首先,请求处理通过*dispatch-table*要求,该受体为easy-acceptor类型,即,你将不得不

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

documentation有细节。

第二个问题是,您在设置代码期间重新绑定*dispatch-table*,并将新值插入此绑定。由于绑定在let完成后恢复(并且由于hunchentoot:start异步工作),因此在服务器运行时,*dispatch-table*中的条目实际上会丢失。尝试

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

在顶层(或者在专门的设置功能中做类似的事情)。如果您不喜欢全球*dispatch-table*的方法,您还可以创建acceptor的子类,并覆盖acceptor-dispatch-request(从而实现您喜欢的任何类型的调度)。

正如一个侧面说明:你不加前缀*dispatch-table*,而你从hunchentoot的包装几乎任何其他符号。这只是一个复制/粘贴错误,或者在你的实际代码中也是这样吗?如果您的代码恰好位于您的代码所在的位置,则不需要:usehunchentoot程序包,那么您还必须将调度表限定为hunchentoot:*dispatch-table*

编辑(以解决在评论部分的问题)有一个example in the hunchentoot documentation,这似乎做你想要做什么:

(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) 

(注释本作简洁,删除文档中) 。 tbnl是包hunchentoot的预定义昵称。尽管我会推荐你​​可以互换使用,你可以选择一个并坚持下去。将两者混合可能会产生混淆。

+0

感谢您的回复。第一个问题是我的代码中有一个错字,我将它设置为easy-acceptor,稍后我会更新我的文章。第二部分确实有助于澄清我对绑定的一些困惑,而hunchentoot没有看到这些路线。我没有意识到绑定正在重置。另外,谢谢你的注意事项,恐怕我没有在包名称前面加上* dispatch-table *。 – rebnoob

+0

我并不是在寻找花哨的调度方式,所以我想避免继承接受者,并在过程中引入错误。我希望能够实现的是能够创建运行在不同端口上的服务器的多个实例,并使用一些实例特定的数据(如db连接)。你会推荐最好的方法来做到这一点? – rebnoob

+0

这很有效,谢谢德克! – rebnoob