如何将 Cowboy (Erlang) websocket 连接到 webflow.io 生成的网页
Posted
技术标签:
【中文标题】如何将 Cowboy (Erlang) websocket 连接到 webflow.io 生成的网页【英文标题】:How to Connect Cowboy (Erlang) websocket to webflow.io generated webpage 【发布时间】:2021-06-15 08:22:11 【问题描述】:我想使用牛仔 websocket 接口与使用 webflow 生成的网页进行交互。我想举一个简单的例子,如何添加实现连接到 webflow html 的 websocket 的 javascript。
【问题讨论】:
【参考方案1】:这应该让你开始:
将Container
(即div
)拖到您的页面上。给它 ID server_info
。
将Button
拖到您的页面上。给它 ID get_server_info
。
Page Settings
允许您使用add javascript to a page。 js for connecting to a server with a websocket 看起来像这样:
<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>
Create a new cowboy app 调用了hello_erlang
。
通过将以下内容放入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.
为了提供带有按钮的简单 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
目录)。在 html 页面的 <head>
部分有一个 <script>
标记,它链接到 javascript 使用的 jquery
库:
<!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 目录)。请参阅static files 上的牛仔文档。当您在将 html 文件发送到客户端之前不需要使用 erlang 以某种方式更改 html 文件时,这是提供文件的最简单方法。
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.
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/
这将导致cowboy 提供包含该按钮的html 页面。点击按钮会使用websocket向服务器发送一些数据,服务器会响应,然后js会在网页中插入响应。
Webflow
确实与答案无关:无论您如何或使用什么来创建 html 和 javascript,最终产品都是一个 html 页面,您将其放在服务器目录的某个位置。当浏览器从您的服务器请求 html 文件时,服务器将 html 文件发送给浏览器,然后浏览器读取该文件并生成您看到的漂亮文本和图片,然后浏览器在适当的时间执行 javascript。浏览器不知道是谁在文件中创建了 html 和 javascript。
【讨论】:
以上是关于如何将 Cowboy (Erlang) websocket 连接到 webflow.io 生成的网页的主要内容,如果未能解决你的问题,请参考以下文章