Common lisp Hunchentoot调度员

Common lisp Hunchentoot调度员,common-lisp,hunchentoot,Common Lisp,Hunchentoot,我对CommonLisp(SBCL)和Hunchentoot(使用Quicklisp)比较陌生。有人能告诉我怎么才能让它工作吗?我试图将Hunchentoot服务器和一些路径作为一个单元封装在函数中。当我运行此命令时,只有Hunchentoot的索引页可用,路径/a和/b不可用 (defun app0 (port) (let ((*dispatch-table* nil) (server (make-instance 'hunchentoot:acceptor :port port)))

我对CommonLisp(SBCL)和Hunchentoot(使用Quicklisp)比较陌生。有人能告诉我怎么才能让它工作吗?我试图将Hunchentoot服务器和一些路径作为一个单元封装在函数中。当我运行此命令时,只有Hunchentoot的索引页可用,路径/a和/b不可用

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

据我所知,有很多问题。首先,通过
*调度表*
处理请求时,要求接受方类型为
易接受方
,即您必须

(make-instance 'easy-acceptor ...)
报告中有细节

第二个问题是,在设置代码期间重新绑定
*调度表*
,并将新值推送到该绑定中。由于绑定在
let
完成后恢复(并且
hunchentoot:start
异步工作),因此当服务器运行时,
*调度表*
中的条目实际上会丢失。试一试

(push (hunchentoot:create-prefix-dispatcher "/a" (lambda () "a")) *dispatch-table*)
(push (hunchentoot:create-prefix-dispatcher "/b" (lambda () "b")) *dispatch-table*)
在顶层(或在专用设置功能中执行类似操作)。如果您不喜欢全局
*分派表*
方法,还可以创建
接受者
的子类,并覆盖
接受者分派请求
(从而实现您喜欢的任何分派)

作为旁注:您不在
*调度表*
前面加前缀,而实际上在
hunchentoot
的包中的任何其他符号前面加前缀。这只是一个复制/粘贴错误,还是在实际代码中也是如此?如果不
:在代码所在的包中使用
hunchentoot
包,则还必须将分派表限定为
hunchentoot:*分派表*

编辑(要解决评论部分中的问题)有一个,似乎正是您想要做的:

(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
的预定义昵称。虽然我建议你选择一个并坚持使用,但你可以互换使用这两个。两者混合可能会产生混淆。

*调度表*
已经是一个全局变量。感谢您的回复。第一个问题是我的代码输入错误,我把它设置为easy acceptor,我会很快更新我的帖子。第二部分确实有助于澄清一些困惑,我确实有周围的绑定,hunchentoot没有看到这些路由。我没有意识到绑定正在被重置。另外,谢谢你的补充说明,恐怕我还没有在dispatch table前面加上包名。我不是真的在寻找花哨的分派,所以我想避免子类化acceptor,并在这个过程中引入错误。我希望实现的是能够使用一些特定于实例的数据(如db连接)创建在不同端口上运行的服务器的多个实例。你能推荐最好的方法吗?