Cowboy 用户指南 (一) - The modern Web

现代网络

Cowboy是一个现代网络服务器. 这一章解释了它的含义,并详细介绍了所有涉及的标准。Cowboy支持本文档中列出的所有标准。

HTTP/2

HTTP/2是消费Web服务最有效的协议。它允许clients保持一个长时间打开的(connection),为了并发的发送requests;还可以通过压缩HTTP headers来减少requests的size;等等。该协议是binary(二进制)的,大大减少了解析它所需的资源。

HTTP/2也允许Server向Client推送消息。这可以用于各种目的,包括在Client请求相关资源之前发送相关资源,以减少延迟。这也可以用来启用双向通信。

Cowboy提供了对HTTP/2的透明支持。支持它的客户端可以使用它;其他的则自动使用HTTP/1.1。

HTTP/2兼容HTTP/1.1语义。

HTTP/2由RFC 7540和RFC 7541定义。

HTTP/1.1

HTTP/1.1是HTTP协议的前一个版本。协议本身是基于文本的,存在许多问题和限制。特别是不能并发地执行请求(尽管有时可以使用管道),而且有时很难检测到client是否断开连接。

HTTP/1.1确实为与Web服务交互提供了非常好的语义。它定义了HTTP/1.1和HTTP/2客户端和服务器使用的标准方法、头部和状态码。

HTTP/1.1兼容旧版本的HTTP/1.0协议(该版本从未真正实现跨标准化)。

HTTP/1.1的核心由RFC 7230、RFC 7231、RFC 7232、RFC 7233、RFC 7234和RFC 7235定义。大量的rfc和其他规范定义了附加的HTTP方法、状态代码、头部或语义。

Websocket

Websocket是一个建立在HTTP/1.1之上的协议,它提供了客户端和服务器之间的双向通信通道。通信是异步的,可以并发进行。

它包括一个Javascript对象,允许设置到服务器的Websocket连接,以及一个基于二进制的协议,用于向服务器或客户端发送数据。

Websocket连接可以传输UTF-8编码的文本数据或二进制数据。该协议还包括对实现ping/pong机制的支持,允许服务器和客户端有更多的信心,相信连接仍然是存活的。

Websocket连接可以用来传输任何类型的数据,大小、文本或二进制数据。因此,Websocket有时被用于系统之间的通信。

Websocket消息本身没有语义。Websocket在这方面更接近于TCP,需要你在它的基础上设计和实现自己的协议;或者将现有协议适配到Websocket。

Cowboy提供了一个称为Websocket处理程序的接口,它可以完全控制Websocket连接。

Websocket协议由RFC 6455定义。

Long-lived requests

Cowboy提供了一个接口,可用于支持Long-polling(长轮询)或可靠地传输大量数据,包括使用 Server-Sent Events (服务器发送的事件)。

(Long-polling) 长轮询是一种机制,在这种机制中,客户机执行的请求可能不会被服务器立即响应。它允许客户机请求可能当前不存在的资源,但预计很快就会创建,并且一旦它们存在就会返回。

长轮询本质上是一种hack,但它被广泛用于克服老客户机和服务器上的限制。

(Server-Sent Events) 服务器发送事件是一个小协议,被定义为一种媒体类型,文本/事件流,以及一个新的HTTP头,Last-Event-ID。它在EventSource W3C规范中定义。

Cowboy提供了一个称为循环处理程序的接口,用于支持长轮询或流机制的实现。它的运行与底层协议无关。

REST

REST,或REpresentational State Transfer(表现层状态转移),是一种用于松散连接的分布式系统的体系结构风格。它可以很容易地在HTTP上实现。

REST本质上是一组需要遵循的约束。许多约束都是纯架构性的,可以通过简单地使用HTTP来解决。开发人员必须显式地遵循一些约束。

Cowboy提供了一个称为REST处理程序的接口,该接口在HTTP协议之上简化了REST API的实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的使用erlang的cowboy框架编写的websocket聊天室代码示例。 ```erlang %% 定义路由和处理函数 -module(chat_router). -behaviour(cowboy_router). -export([init/3]). -export([routes/2]). init(_Transport, _Req, _Opts) -> {ok, [], undefined}. routes(_Req, _State) -> {[ {'_', [ {"/websocket", cowboy_websocket_handler, [ {callback, chat_handler}, {origin, "*"} ]} ]} ], _Req, _State}. %% 定义websocket处理函数 -module(chat_handler). -behaviour(cowboy_websocket_handler). -export([init/3]). -export([websocket_init/3]). -export([websocket_handle/3]). -export([websocket_info/3]). -export([websocket_terminate/3]). init(_TransportName, Req, _Opts) -> {ok, Req, undefined}. websocket_init(_TransportName, Req, _Opts) -> {cowboy_websocket, Req, undefined}. websocket_handle({text, Message}, Req, _State) -> %% 处理收到的文本消息 cowboy_websocket:broadcast(Message, Req), {ok, Req, undefined}; websocket_handle(_Data, Req, _State) -> {ok, Req, undefined}. websocket_info({join, _Pid, _Ref}, Req, _State) -> %% 处理新用户加入聊天室 cowboy_websocket:broadcast("New user joined", Req), {ok, Req, undefined}; websocket_info({leave, _Pid, _Ref}, Req, _State) -> %% 处理用户离开聊天室 cowboy_websocket:broadcast("User left", Req), {ok, Req, undefined}; websocket_info(_Info, Req, _State) -> {ok, Req, undefined}. websocket_terminate(_Reason, Req, _State) -> {ok, Req, undefined}. ``` 以上代码定义了一个路由模块`chat_router`,其中`routes/2`函数指定了处理`/websocket`路径的`cowboy_websocket_handler`处理函数,并将其回调函数指定为`chat_handler`。`chat_handler`模块中的`websocket_handle/3`函数用于处理接收到的文本消息,并使用`cowboy_websocket:broadcast/2`函数将消息广播给所有连接的客户端。`websocket_info/3`函数用于处理新用户加入和离开聊天室的事件,同样使用`cowboy_websocket:broadcast/2`函数将事件广播给所有连接的客户端。 您可以将以上代码保存为`chat.erl`文件,并使用cowboy框架启动websocket服务器,例如: ```erlang %% 启动websocket服务器 -module(chat). -behaviour(application). -export([start/2, stop/1]). start(_Type, _Args) -> Dispatch = cowboy_router:compile([ {'_', [{"/websocket", chat_handler, []}]} ]), {ok, _} = cowboy:start_clear(http, [{port, 8080}], #{env => #{dispatch => Dispatch}}), chat_sup:start_link(). stop(_State) -> ok. ``` 以上代码定义了一个应用模块`chat`,其中`start/2`函数启动了一个cowboy服务器,监听8080端口,并将路由配置为处理`/websocket`路径,使用`chat_handler`处理函数。您可以将以上代码保存为`chat_app.erl`文件,并使用`rebar3`编译和启动应用程序: ```sh $ rebar3 compile $ rebar3 shell ``` 在erlang shell中,您可以使用以下命令连接到websocket服务器并发送消息: ```erlang %% 连接到websocket服务器 1> {ok, Conn} = websocket:connect("ws://localhost:8080/websocket"). {ok,{websocket,#Port<0.7>,<0.198.0>}} %% 发送消息 2> websocket:send_text(Conn, "Hello, World!"). ok ``` 在另一个erlang shell中,您可以使用以下命令连接到相同的websocket服务器并接收消息: ```erlang %% 连接到websocket服务器 1> {ok, Conn} = websocket:connect("ws://localhost:8080/websocket"). {ok,{websocket,#Port<0.7>,<0.203.0>}} %% 接收消息 2> websocket:recv_text(Conn). "New user joined" 3> websocket:recv_text(Conn). "Hello, World!" ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值