简体   繁体   中英

How to Connect Cowboy (Erlang) websocket to webflow.io generated webpage

I'm want to use cowboy websocket Interface to interact with a webpage generated with webflow. I would like to have an simple example how to add javascript implementing websocket connected to webflow HTML.

This should get you started:

  1. Drag a Container , which is a div , onto your page. Give it the ID server_info .

  2. Drag a Button onto your page. Give it the ID get_server_info .

  3. The Page Settings allow you to add javascript to a page . The js for connecting to a server with a websocket will look something like this:

     <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. Create a new cowboy app called hello_erlang .

  5. Create some routes and and specify their handler functions by putting the following in 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. To serve the simple html page with the button, I used 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.

According to the erlang docs , the priv directory is where application specific files should go. Below is the form.htm page, which I put it in the directory hello_erlang/priv/html/ (I created the html directory). In the <head> section of the html page there is a <script> tag which links to the jquery library, which is used by the 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>

Edit: Another way to serve the html file is to do away with hello_handler.erl and set the route like this:

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

You would put form.htm in the directory hello_erlang/priv/html/ (I created the html directory). See the cowboy docs on static files . When you don't need to use erlang to alter the html file in some way before sending it to the client, that is the simplest way to serve the file.

  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}.

Then, in the top level directory of your app, hello_erlang in this case, start your cowboy server:

...cowboy_apps/hello_erlang$ make run

Then, enter the following url in your browser:

http://localhost:8080/

That will cause cowboy to serve up the html page containing the button. Clicking on the button will send some data to the server using the websocket, and the server will respond, then the js will insert the response in the web page.

Webflow is really irrelevant to the answer: it doesn't matter how or what you use to create html and javascript, the end product is an html page, which you put somewhere in your server's directory. When a browser requests the html file from your server, the server sends the html file to the browser, then the browser reads the file and produces the pretty text and pictures you see, and the browser executes the javascript at the appropriate time. A browser has no idea who are what created the html and javascript in the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM