You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cowboy框架websocket_send函数参数错误问题排查求助

问题分析与解决方案

核心错误点

  1. 错误保存连接标识:你在init中将Req保存为socket,但Req只是HTTP升级请求的上下文,并非websocket连接的有效状态载体,正确的状态应该是Cowboy websocket handler维护的#state{}记录。
  2. 参数顺序与类型错误:从你提供的websocket_send实现的spec可以看到,函数定义是websocket_send(cow_ws:frame(), #state{}),即第一个参数是websocket帧(如{text, Msg}),第二个参数是handler的#state{}记录。但你调用时传反了参数,且第一个参数是无效的Req map,导致undef错误。
  3. 调用场景错误:cowboy_websocket:websocket_send是websocket handler进程内部的函数,不能直接在外部进程通过传入"socket"调用,因为外部无法获取到包含传输信息的#state{}记录。

正确实现步骤

1. 维护连接的进程PID

首先需要在全局存储(比如ETS表)中记录每个websocket连接的进程PID,这是跨进程发送消息的基础:

% 初始化ETS表(在应用启动时执行)
init_ets() ->
    ets:new(connected_clients, [named_table, public, set]).

% websocket handler的init函数
init(Req, _Opts) ->
    ?LOG_INFO("New client"),
    % 记录当前websocket进程的PID
    Self = self(),
    ets:insert(connected_clients, {Self}),
    % 不需要保存Req到state,Cowboy会维护必要的连接状态
    {cowboy_websocket, Req, #state{}}.

2. 在handler中处理消息发送指令

让websocket进程自己处理发送消息的请求,通过进程间消息传递触发:

% websocket handler的handle_info回调
handle_info({broadcast_msg, Msg}, State) ->
    % 正确调用websocket_send:帧在前,state在后
    cowboy_websocket:websocket_send({text, Msg}, State),
    {ok, State};
handle_info(_OtherMsg, State) ->
    {ok, State}.

% 处理连接断开,移除PID
terminate(_Reason, _Req, _State) ->
    ets:delete(connected_clients, self()),
    ok.

3. 实现广播函数

遍历所有连接的PID,发送消息指令让每个进程自行调用websocket_send:

send_message_to_all_clients(Msg) ->
    % 获取所有连接的进程PID
    Pids = [Pid || {Pid} <- ets:tab2list(connected_clients)],
    % 给每个进程发送消息指令
    lists:foreach(fun(Pid) ->
        Pid ! {broadcast_msg, Msg}
    end, Pids).

关于websocket_send的正确参数说明

从你提供的实现代码的spec定义:

-spec websocket_send(cow_ws:frame(), #state{}) -> ok | stop | {error, atom()}.
  • 第一个参数:websocket帧,支持的格式包括{text, binary()}、{binary(), binary()}、{close, integer(), binary()}等
  • 第二个参数:websocket handler的#state{}记录,必须是当前进程维护的state(包含socket和transport信息)
  • 调用场景:只能在websocket handler进程内部调用,不能跨进程直接传入外部获取的"socket"值

内容的提问来源于stack exchange,提问作者N-K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 14:25:46