一个在 Boot.scala 中启动 ssh 守护程序的 Lift 应用程序。这是问题所在:当我container:restart /
在 sbt 会话中运行时,我得到Address alread in use异常。现在有两个问题:
- 在 Boot.scala 中启动依赖服务是否正确?
- 无论如何如何处理容器:停止事件?
一个在 Boot.scala 中启动 ssh 守护程序的 Lift 应用程序。这是问题所在:当我container:restart /
在 sbt 会话中运行时,我得到Address alread in use异常。现在有两个问题:
我认为 Lift-y 的做法是使用LiftRules.unloadHooks
.
它没有很好的文档记录(AFAIK),但是如果您查看 Lift 源代码,您会看到当edLiftServlet
时destroy()
,其中定义的函数LiftRules.unloadHooks
被执行。
您可以unloadHooks
RulesSeq
使用append
orprepend
方法将函数添加到 ,具体取决于您希望它们执行的顺序。因此,在您的bootstrap.liftweb.Boot.boot
方法中,您可能会执行以下操作:
sshDaemon.start()
LiftRules.unloadHooks.append( () => sshDaemon.stop() )
(假设这就是您启动和停止 SSH 守护程序的方式。)
我不是 100% 确定在运行LiftServlet.destroy()
sbt web-plugin 的命令时调用该方法container:restart
- 这是由插件及其与 Jetty 的交互决定的,而不是由 Lift 决定的 - 但该container:stop
命令绝对可以解决问题。
我不熟悉 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()
}