0

我想使用牛仔 websocket 接口与使用 webflow 生成的网页进行交互。我想有一个简单的例子,如何添加实现连接到 webflow HTML 的 websocket 的 javascript。

4

1 回答 1

0

这应该让你开始:

  1. 将 a Container(即 a div)拖到您的页面上。给它 ID server_info

  2. 将 aButton拖到您的页面上。给它 ID get_server_info

  3. Page Settings允许您将javascript 添加到页面使用 websocket 连接到服务器的js将如下所示:

       <script>
        var ws = new WebSocket("ws://localhost:8080/please_upgrade_to_websocket");
    
        ws.onerror = function(event) {
            console.error("[ME]WebSocket error observed:", event);
        };
        ws.onclose = function(event) {
            console.log("[ME]WebSocket is closed now.");
        };
    
        $("#get_server_info").click(function() {
            if(ws.readyState == 1) {               
                ws.send("My data");
            }
            else {
                alert("Websocket not open! readyState: " + ws.readyState);
           }
        });
    
        ws.onmessage = function (event) {
            alert("Data was retrieved from server and will be inserted in page.");
            $("#server_info").text(event.data);
    
        };
    
       </script>
    
  4. 创建一个名为hello_erlang.

  5. 创建一些路由并指定它们的处理函数,方法是将以下内容放入hello_erlang/src/hello_erlang_app.erl

     -module(hello_erlang_app).
     -behaviour(application).
    
     -export([start/2]).
     -export([stop/1]).
    
     start(_Type, _Args) ->
         HelloRoute = { "/", hello_handler, [] },
         WebSocketRoute = {"/please_upgrade_to_websocket", myws_handler, []},
         CatchallRoute = {"/[...]", no_matching_route_handler, []},
    
         Dispatch = cowboy_router:compile([
             {'_', [HelloRoute, WebSocketRoute, CatchallRoute]}
         ]),
    
    
         {ok, _} = cowboy:start_clear(my_http_listener,
             [{port, 8080}],
             #{env => #{dispatch => Dispatch} }
         ),
    
         hello_erlang_sup:start_link().
    
     stop(_State) ->
         ok.
    
  6. 为了使用按钮提供简单的 html 页面,我使用了hello_erlang/src/hello_handler.erl

     -module(hello_handler).
     -behavior(cowboy_handler).
    
     -export([init/2]).
    
     init(Req0, State) ->
         io:format("[ME]Entered hello_handler~n"),
         Body = my_get_file("html/form.htm"),  %% Body can be a binary() or an iolist() (which is a list containing integers, strings, or binaries)
         Req = cowboy_req:reply(200,
             #{<<"content-type">> => <<"text/html">>},
             Body,
             Req0),
    
         {ok, Req, State}.
    
     my_get_file(Path) ->
         PrivDir = code:priv_dir(hello_erlang),  %% Finds the path of an application's priv directory
         AbsPath = filename:join([PrivDir, Path]),
    
         case file:read_file(AbsPath) of 
             {ok, Bin} -> Bin;
             _  -> ["<div>Cannot read file: ", Path, "</div>"]  %% iolist()
         end.
    

根据erlang docs,该priv目录是应用程序特定文件应该去的地方。下面是form.htm页面,我把它放在目录中hello_erlang/priv/html/(我创建了html目录)。在<head>html 页面的部分有一个<script>链接到jquery库的标签,由 javascript 使用:

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"   
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" 
            crossorigin="anonymous">
    </script>
  </head>
  <body>
    <div id="server_info">Server info</div>
    <button type="button" id="get_server_info">Get sever info</button>

    <script>
     var my_websocket = new WebSocket("ws://localhost:8080/please_upgrade_to_websocket");

     my_websocket.onerror = function(event) {
         console.error("[ME]WebSocket error observed:", event);
     };
     my_websocket.onclose = function(event) {
         console.log("[ME]WebSocket is closed now.");
     };

     $("#get_server_info").click(function() {
         if(my_websocket.readyState == 1) {               
             my_websocket.send("My data");
         }
         else {
             alert("Websocket not open! readyState: " + my_websocket.readyState );
        }
     });

     my_websocket.onmessage = function (event) {
         $("#server_info").text(event.data);
         alert("Data was retrieved from server and will be inserted in page.");
     };

    </script>


  </body>
</html>

编辑:提供 html 文件的另一种方法是取消hello_handler.erl并设置如下路线:

HelloRoute = { "/", cowboy_static, {priv_file, hello_erlang, "html/form.htm"} },

您将放入form.htm目录hello_erlang/priv/html/(我创建了 html 目录)。请参阅关于静态文件的牛仔文档。当您在将 html 文件发送到客户端之前不需要使用 erlang 以某种方式更改 html 文件时,这是提供文件的最简单方法。

  1. hello_erlang/src/myws_handler.erl

     -module(myws_handler).
     -export([init/2, websocket_init/1, websocket_handle/2, websocket_info/2]).
    
    
     init(Req, State) ->
         {cowboy_websocket, Req, State}.  %Perform websocket setup
    
     websocket_init(State) ->
         io:format("[ME]: Inside websocket_init()~n"),
         {ok, State}.
    
     websocket_handle({text, Msg}, State) ->
         {Hours, Minutes, Secs} = time(),
    
         {
              reply, 
              {text, io_lib:format("[~w:~w:~w]: Server received: ~s", [Hours, Minutes, Secs, Msg]) },
              State
         };
     websocket_handle(_Other, State) ->  %Ignore
         {ok, State}.
    
    
     websocket_info({text, Text}, State) ->
         {reply, {text, Text}, State};
     websocket_info(_Other, State) ->
         {ok, State}.
    
  2. hello_erlang/src/no_matching_route_handler.erl

     -module(no_matching_route_handler).
     -behavior(cowboy_handler).
    
     -export([init/2]).
    
     init(Req0, State) -> %State comes from last argument of route
         Req = cowboy_req:reply(404,
             #{<<"content-type">> => <<"text/plain">>},
             <<"[ME] 404. Whoops! (No matching route!)">>,
             Req0),
         {ok, Req, State}.
    

然后,在您的应用程序的顶级目录中,hello_erlang在这种情况下,启动您的牛仔服务器:

...cowboy_apps/hello_erlang$ make run

然后,在浏览器中输入以下网址:

http://localhost:8080/

这将导致牛仔提供包含该按钮的 html 页面。点击按钮会使用websocket向服务器发送一些数据,服务器会响应,然后js会在网页中插入响应。

Webflow与答案无关:无论您如何或使用什么来创建 html 和 javascript,最终产品都是一个 html 页面,您将其放在服务器目录的某个位置。当浏览器从您的服务器请求 html 文件时,服务器将 html 文件发送给浏览器,然后浏览器读取该文件并生成您看到的漂亮文本和图片,然后浏览器在适当的时间执行 javascript。浏览器不知道是谁在文件中创建了 html 和 javascript。

于 2021-03-18T16:56:39.643 回答