5

一个在 Boot.scala 中启动 ssh 守护程序的 Lift 应用程序。这是问题所在:当我container:restart /在 sbt 会话中运行时,我得到Address alread in use异常。现在有两个问题:

  1. 在 Boot.scala 中启动依赖服务是否正确?
  2. 无论如何如何处理容器:停止事件?
4

2 回答 2

10

我认为 Lift-y 的做法是使用LiftRules.unloadHooks.

它没有很好的文档记录(AFAIK),但是如果您查看 Lift 源代码,您会看到当edLiftServletdestroy(),其中定义的函数LiftRules.unloadHooks被执行。

您可以unloadHooks RulesSeq使用appendorprepend方法将函数添加到 ,具体取决于您希望它们执行的顺序。因此,在您的bootstrap.liftweb.Boot.boot方法中,您可能会执行以下操作:

sshDaemon.start()
LiftRules.unloadHooks.append( () => sshDaemon.stop() )

(假设这就是您启动和停止 SSH 守护程序的方式。)

我不是 100% 确定在运行LiftServlet.destroy()sbt web-plugin 的命令时调用该方法container:restart- 这是由插件及其与 Jetty 的交互决定的,而不是由 Lift 决定的 - 但该container:stop命令绝对可以解决问题。

于 2012-01-31T02:24:06.540 回答
4

我不熟悉 Lift,但这个建议应该适用于任何基于 Servlet 的 Web 应用程序。

ServletContextListener在你的 中注册 a web.xml,并释放contextDestroyed方法中的任何资源。(启动应该在contextCreated方法中完成。)

您可以使用setAttribute/getAttribute来存储和稍后检索服务器。

把这一切放在一起:

import javax.servlet.{ServletContextEvent, ServletContextListener}


final class SshListener extends ServletContextListener{
  val attributeKey = "sshServer"

  def contextInitialized(sce: ServletContextEvent) {
    val server = new Server()
    server.start()
    sce.getServletContext.setAttribute(attributeKey, server)
  }

  def contextDestroyed(sce: ServletContextEvent) {
    Option(sce.getServletContext.getAttribute(attributeKey)).foreach(_.asInstanceOf[Server].stop())
  }
}

class Server {
  def start()
  def stop()
}
于 2012-01-29T20:03:57.597 回答