【问题标题】:Scala: how to embed a small web server into a scala app?Scala:如何将小型 Web 服务器嵌入到 Scala 应用程序中?
【发布时间】:2012-03-29 20:42:18
【问题描述】:

对于一个旨在作为社区资源帮助人们学习 Scala 的小型教育项目,我正在寻找一种在后台线程中提供和处理网页的简单方法。

基本背景:Scalatron 是一款多人游戏,玩家可以在其中让机器人程序(用 Scala 编写)相互对抗。它附有一步一步的 Scala 教程。目前玩家需要在本地机器上使用 IDE 来编译机器人,然后通过将它们复制到共享网络目录中来发布到游戏中。这很麻烦。对于下一个版本,最好提供基于浏览器的机器人编辑和发布,以最大限度地简化组织者和玩家的设置。

我已经有一个后台线程正在运行,它将即时编译到达服务器的 Scala 源代码(无需完整的 IDE)。接下来,我必须运行一个小型 Web 服务器来为玩家提供访问点并处理 bot 上传(这摆脱了网络共享)。

要求非常基本:最初我设想提供带有编辑框和“开始”按钮的单个页面(= 上传到服务器,编译并发布到游戏中);我预计不超过 20 个并发用户,每 5 或 10 秒在所有用户中上传不超过一个机器人;我需要为每个用户保持最小状态(只是一个名称),并且我需要将编译器错误消息返回给用户。请注意,游戏屏幕更新不会显示在浏览器中,而是显示在连接到服务器计算机的投影仪上。主要是为了实现最简单的设置(双击游戏服务器 .jar),我认为在现有游戏服务器的后台线程中运行 Web 服务器会很好。

最合适的方法是什么?我应该使用一些现有的框架,比如 Play 或 Lift 吗?是否有现有的代码可以做与此非常相似的事情?计划在这样的后台线程中运行 Web 服务器是否合理? 任何建议都值得赞赏。

【问题讨论】:

    标签: scala playframework webserver lift


    【解决方案1】:

    嵌入式 Web 服务器正是 Unfiltered 的用途。 Unfiltered 的基本理念是,Web 服务器只是您从代码中调用的库,而不是 Web 框架调用的代码。

    【讨论】:

    • 谢谢,听起来不错。我会看的。
    • 这太完美了,希望我能给予额外的支持。我必须组成一个项目,用它来学习 Scala。
    • 对于非常小的用例,我认为它似乎比避免轻度嵌套的if 更复杂,尤其是因为无论如何我都需要 Jetty 或类似的东西。让 Jetty 集成并在大约一个小时内工作。当事情变得更多时,也许未过滤会得到回报。
    【解决方案2】:

    Embedding Jetty 相当简单,是 Jetty 项目的主要目标之一。如果您的需求很简单,这是最快的路线。我怀疑您很快就会需要一个更强大的解决方案(模型、路由、模板等),因此使用像 LiftPlay Framework 这样的框架会是一个更好的主意。

    【讨论】:

      【解决方案3】:

      Java 世界中最常用的小型嵌入式 Web 服务器/servlet 容器之一是 Jetty。由于 Scala 可以轻松使用 Java 库,因此从 Scala 中使用它应该很容易。

      This page 展示了一些简单示例(Java 语言),说明如何将其作为嵌入式 HTTP 服务器启动。

      【讨论】:

        【解决方案4】:

        以下是嵌入 Java 容器和 Scala 框架的几个不同示例:

        虽然这两个都谈到在 Heroku 上运行应用程序,但您可以将它们作为 Scala 应用程序独立运行。

        【讨论】:

          【解决方案5】:
          val webServer = new Thread("Web Server") {
            def response(text: String, code: String = "200 OK") =
              """HTTP/1.0 """ + code + """
            Content-Type: text/html
            Content-Length: """ + text.length + """
          
            """ + text
          
            override def run {
              for(port <- env.webPort) {
                val ss = new ServerSocket(port)
                while (true) try {
                  val s = ss.accept
                  try { s.getOutputStream.write(response(someStuff.toString).getBytes)
                  } finally { s.close }
                } catch { case ie: InterruptedException => return }
              }
            }
          }
          

          另见scala kittens

          【讨论】:

            【解决方案6】:

            由于您想提供一个框架,我认为最好的解决方案是使用现有的框架,这样您就不必费心重新发明一些东西。

            根据我个人的经验,这是非常主观的,我建议你使用 Lift,因为我知道它对于会话、全局 sn-ps 和其他东西的支持非常强大。您可以尝试扩展经典的chat app,它用作电梯工作原理的示例,测试它是否对您的使用有用或不应该很长。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2014-08-17
              • 2015-08-25
              • 2011-03-03
              • 1970-01-01
              • 2011-04-25
              • 1970-01-01
              • 2012-07-29
              相关资源
              最近更新 更多