【问题标题】:How to make a web server using Erlang如何使用 Erlang 制作 Web 服务器
【发布时间】:2017-12-22 17:35:03
【问题描述】:

我是 Erlang 新手

我尝试用 Erlang 创建一个 Web 服务器。如何用 Erlang 做到这一点? 我正在使用此代码制作本地代码:

-module(test). 
-export([start/0,service/3]). 

start() ->
   inets:start(httpd, [ 
      {modules, [ 
         mod_auth, 
         mod_esi, 
         mod_actions, 
         mod_cgi, 
         mod_dir,
         mod_get, 
         mod_head, 
         mod_log, 
         mod_disk_log 
      ]}, 

      {port,8082}, 
      {server_name,"helloworld"}, 
      {server_root,"C://xampp//tmp"}, 
      {document_root,"C://xampp//htdocs"}, 
      {erl_script_alias, {"/erl", [test]}}, 
      {error_log, "error.log"}, 
      {security_log, "security.log"}, 
      {transfer_log, "transfer.log"}, 

      {mime_types,[ 
         {"html","text/html"}, {"css","text/css"}, {"js","application/x-javascript"} ]} 
   ]). 

service(SessionID, _Env, _Input) -> mod_esi:deliver(SessionID, [ 
   "Content-Type: text/html\r\n\r\n", 
   "<DOCTYPE html>
   <head>
   <meta charset='utf-8'>
   <meta http-equiv='X-UA-Compatible' content='IE=edge'>
   <meta name='viewport' content='width=device-width, initial-scale=1'>
   <title>HTML1</title>
   <script
     src='https://code.jquery.com/jquery-3.2.1.js'
     integrity='sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE='
     crossorigin='anonymous'></script>
   <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet'/>
   <link href='css/test1.css' rel='stylesheet'/>
   <script src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'></script>
   </head>
      <html>
      <body>Ham oc cho!
         <div class='header'>
            <ul class='first'>
               <li class='col-md-4'><a href='#' >Tai khoan cua toi</a></li>
               <li class='col-md-4'><a href='#' >Trang thai don hang</a></li>
               <li class='col-md-4'><a href='#' >Danh sach ua thich</a></li>
               <li class='col-md-4'><a href='#' >Gio hang</a></li>
               <li class='col-md-4'><a href='#' >Dang nhap</a></li>
               <li class='col-md-4'><a href='#' >Dang ky</a></li>
            </ul>
         </div>
      </body>
      </html>" ]).

但我没有看到任何添加 css-js 文件的方法,也不知道如何为此编写后端。

如果你有一些例子或文档请分享给我

【问题讨论】:

    标签: mysql web erlang backend


    【解决方案1】:

    有一些有用的 Erlang 工具,例如 CowboyMochiwebChicagobossYAWS 用于处理 Web 协议。

    【讨论】:

    • 泰。我有一个问题:Erlang 可以代替 php 吗?听说Erlang可以支持百万访问,php只支持千访问。是吗?
    • 比较 Erlang (Toolbox) 和 PHP (Wrench) 是错误的。
    • ty 回答我的问题。真的是帮我
    • 我认为 Erlang 可以直接使用的另一个不错的 http 服务器是 httpd
    【解决方案2】:

    您可能会发现通过sws,我的Erlang simple web server 工作很有启发性。它展示了如何使用 Erlang 的内置套接字支持和 HTTP 支持来处理连接、从套接字读取 HTTP 请求以及发送回复。

    Web 服务器通过接受传入连接和使用 Erlang 对 HTTP 请求解析的内置支持来解析传入请求来工作——见第 29 行:

    ok = inet:setopts(S, [{packet,http_bin}]),
    

    {packet, http_bin} socket option 告诉 Erlang 尝试将传入的套接字数据解析为 HTTP。在第 36 行的 serve/3 函数中,出于流量控制和背压目的,我们将套接字保持在 {active, once} 模式,这也意味着 sws 接收来自 Erlang 的传入数据作为消息 - 参见第 37-41 行:

    ok = inet:setopts(S, [{active, once}]),
    HttpMsg = receive
                  {http, S, Msg} -> Msg;
                  _ -> gen_tcp:close(S)
              end,
    

    serve/3 函数是递归的,接收 HTTP 请求数据,直到我们收到完整的请求或错误。一旦serve/3 有一个完整的请求,它就会将它传递给一个处理函数,当你调用sws:start/1,2 时你应该提供它。处理程序应返回 HTTP 状态、HTTP 回复标头和 HTTP 回复正文的 3 元组,其中标头或正文可以为空,具体取决于返回状态。

    例如,这里有一个简单的“Hello, World!”在 Erlang shell 中运行的应用程序:

    1> c(sws).
    {ok,sws}
    2> Sws = spawn(sws, start, [fun(_,_) -> {200, [], <<"Hello, World!">>} end]).
    <0.73.0>
    

    在这里,作为处理程序传递的fun 始终返回 HTTP 状态 200、没有回复标头和回复正文的字符串二进制文件。从 Unix shell 通过 curl 访问服务器会显示预期的回复:

    $ curl http://localhost:8000
    Hello, World!
    

    如果我们将-v 传递给 curl 以显示更多细节,我们会看到:

    $ curl -v http://localhost:8000
    * Rebuilt URL to: http://localhost:8000/
    *   Trying ::1...
    * TCP_NODELAY set
    * Connection failed
    * connect to ::1 port 8000 failed: Connection refused
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to localhost (127.0.0.1) port 8000 (#0)
    > GET / HTTP/1.1
    > Host: localhost:8000
    > User-Agent: curl/7.51.0
    > Accept: */*
    >
    * HTTP 1.0, assume close after body
    < HTTP/1.0 200
    <
    * Curl_http_done: called premature == 0
    * Closing connection 0
    Hello, World!
    

    首先 curl 尝试通过 IPv6 进行连接,但由于 sws 不支持它而失败(尽管它可以),因此它通过 IPv4 重试,成功。然后,Curl 发送 GET 请求以获取 / 资源。当 curl 看到回复时,它会显示 200 状态码,并且还要注意它看到回复是 HTTP 1.0,因此正确地假设连接将在发送正文后关闭,因此在收到回复后它也会关闭它的一侧.

    您提供的处理函数有两个参数:客户端套接字和请求对象,它是一个由 2 元组组成的属性列表,其中第一个元组元素是标识其关联数据的原子。例如,处理程序可以通过使用lists:keyfind/3Request 参数中查找method 元组来确定调用的HTTP 方法:

    {method, Method} = lists:keyfind(method, 1, Request),
    

    对于我们上面的示例,Method 的值将是 'GET'(一个原子)。可以像这样发现的请求的其他属性是:

    • uri 请求的资源
    • version 用于客户端 HTTP 版本
    • headers 获取请求中的 HTTP 标头列表

    您提供的处理函数可以根据您的需要简单或复杂。请注意,如果您的处理程序失败并导致异常,sws 会捕获它并返回 HTTP 状态代码 500。

    要停止 Web 服务器,回到 Erlang shell,我们向生成的 sws 进程发送 stop 消息:

    3> Sws ! stop.
    stop
    =ERROR REPORT==== 19-Jul-2017::11:17:05 ===
    Error in process <0.77.0> with exit value:
    {{badmatch,{error,closed}},[{sws,accept,2,[{file,"sws.erl"},{line,28}]}]}
    

    这里显示的错误可以忽略,只是因为sws 总是假定gen_tcp:accept/1 成功——见第 28 行:

    {ok, S} = gen_tcp:accept(LS),
    

    将其设为case 表达式并同时处理错误返回会很容易。

    请注意,sws 用于演示和学习,因此它故意不是特别有效,因为它仅支持 HTTP 1.0 并且每个连接仅处理一个请求。

    【讨论】:

      【解决方案3】:

      考虑使用http://phoenixframework.org/ 它使用在 Erlang VM 上运行的 elixir。

      【讨论】:

        猜你喜欢
        • 2012-06-25
        • 2013-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-24
        • 1970-01-01
        • 2012-05-03
        • 2014-02-03
        相关资源
        最近更新 更多