以下是一个简单的 Erlang demo,用于实现 WebSocket 支持:

-module(websocket).
-export([start/0]).

start() ->
    {ok, Listen} = gen_tcp:listen(8080, [{active, false}, {reuseaddr, true}]),
    loop(Listen).

loop(Listen) ->
    {ok, Socket} = gen_tcp:accept(Listen),
    spawn(fun() -> handle(Socket) end),
    loop(Listen).

handle(Socket) ->
    {ok, Request} = gen_tcp:recv(Socket, 0),
    {_, Headers, _} = httpd:parse_request(Request),
    case lists:member({'Upgrade', 'websocket'}, Headers) of
        true ->
            Key = get_key(Headers),
            Response = build_response(Key),
            gen_tcp:send(Socket, Response),
            loop(Socket);
        false ->
            gen_tcp:close(Socket)
    end.

loop(Socket) ->
    {ok, Data} = gen_tcp:recv(Socket, 0),
    case Data of
        [<<129:8, Length:7, Mask:1>>|Payload] ->
            PayloadData = unmask(Payload, Mask),
            handle_message(Socket, PayloadData),
            loop(Socket);
        _ ->
            gen_tcp:close(Socket)
    end.

get_key(Headers) ->
    {_, Key} = lists:keyfind('Sec-WebSocket-Key', 1, Headers),
    sha1_base64(Key ++ "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").

build_response(Key) ->
    Response = << "HTTP/1.1 101 Switching Protocols\r\n">>,
    Response = << Response/binary, "Upgrade: websocket\r\n">>,
    Response = << Response/binary, "Connection: Upgrade\r\n">>,
    Response = << Response/binary, "Sec-WebSocket-Accept: ">>,
    Response = << Response/binary, Key/binary>>,
    Response = << Response/binary, "\r\n\r\n">>,
    Response.

unmask(Payload, Mask) ->
    unmask(Payload, Mask, 0, []).

unmask([], _, _, Acc) ->
    lists:reverse(Acc);
unmask([Byte|Tail], Mask, Index, Acc) ->
    MaskByte = element((Index rem 4) + 1, Mask),
    Unmasked = Byte bxor MaskByte,
    unmask(Tail, Mask, Index + 1, [Unmasked|Acc]).

handle_message(Socket, Payload) ->
    io:format("~s~n", [Payload]),
    gen_tcp:send(Socket, <<131:8, 5:1, "hello">>).

这个 demo 实现了一个简单的 WebSocket 服务器,监听本地 8080 端口。当一个新的连接到达时,它会检查是否是 WebSocket 请求。如果是,它会构建一个响应,表示升级到 WebSocket。一旦连接成功升级,它就会进入一个循环,接收和处理消息。在这个 demo 中,它只是简单地将接收到的消息打印到控制台,并回复一个固定的消息。

erlang gen_tcp 实现 websocket支持写一个demo

原文地址: https://www.cveoy.top/t/topic/bkly 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录