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

如何在Ballerina隔离函数中访问WebSocket连接

解决Ballerina WebSocket服务中Isolated函数无法访问客户端连接的问题

要实现WebSocket消息广播,核心是解决isolated函数对连接集合的并发安全访问问题。你原来的代码中全局connections是非isolated变量,而isolated函数不允许访问非isolated状态,同时全局变量也存在并发修改的风险。以下是修正后的实现方案:

修正后的代码

service class ASB {
    *websocket:Service;
    // 将连接集合作为服务类的isolated成员变量,确保并发安全基础
    isolated map<websocket:Caller> connections = {};

    // 使用@locked注解保证对connections的修改操作线程安全
    @locked
    remote function onOpen(websocket:Caller caller) returns error? {
        connections[caller.getConnectionId()] = caller;
    }

    // 同样用@locked确保遍历连接集合时的并发安全
    @locked
    isolated remote function onMessage(string message) returns error? {
        foreach websocket:Caller caller in connections.values() {
            check caller->writeTextMessage(message);
        }
    }

    // 可选:如果需要单独的广播函数,也可以定义为类的@locked方法
    @locked
    isolated function broadcast(string text) returns error? {
        foreach websocket:Caller caller in connections.values() {
            check caller->writeTextMessage(text);
        }
    }
}

关键改动说明

  • 将连接集合移至服务类内部:全局变量无法被isolated函数访问,而服务类的isolated成员可以被isolated方法直接访问,符合Ballerina的并发安全规则。
  • 使用@locked注解:当多个客户端同时触发onOpen或onMessage时,@locked会保证同一时间只有一个线程能修改或遍历connections,避免竞态条件(比如在遍历过程中连接被添加/移除导致的异常)。
  • 简化广播逻辑:无需单独传递connections参数,直接访问类成员即可,代码更简洁。

额外优化建议

如果需要处理客户端断开连接的场景,记得在onClose方法中移除对应连接,同样要加上@locked注解:

@locked
remote function onClose(websocket:Caller caller, int statusCode, string reason) returns error? {
    connections.remove(caller.getConnectionId());
}

内容的提问来源于stack exchange,提问作者MOHAMED SABTHAR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:37:38