帮我用erlang的cowboy写个websocket聊天室
时间: 2023-12-16 08:06:39 浏览: 280
基于websocket的聊天室
好的,以下是一个简单的使用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!"
```
阅读全文