socket 长连接

socket是双向实时的持久连接,可以让客户端和服务器主动推送数据给对方,实现多个在线用户之间及时传递消息

前端

$socket.open(频道, 事件响应, 选项) 打开长连接

频道:字符串或数组,希望订阅哪些频道/群组的消息。
事件响应:事件响应对象可包含如下表达式
onConn:连接上(connect)服务器后执行的表达式。重连或订阅新频道也会再次执行。
onData:收到消息后执行的表达式。
onHeartbeat:响应心跳表达式。为了保持长连接,客户端和服务器每30秒内就会同步一次心跳。变量connected表示连接状态,date表示心跳时间,date() - date - 30000表示断开连接多久了。
onError:发生错误后执行的表达式。
选项

db:是否把消息保存到数据库*
login0:无需登录(将忽略db选项);1:要登录且只能有一个会话(session),多处登录会断开前面的连接;2:要登录并允许多个会话(可多端登录的同一用户能接受到相同的消息)。默认为1。
self:是否要给发送人也发送消息,方便在onData统一接收消息。
resend:重连后是否自动重发断连期间未能发送的消息。
online:是否响应用户上线消息,有用户上线时将收到{ type: "online", session: id, x: 用户id }
offline:是否响应用户下线消息,有用户下线时将收到{ type: "offline", session: id, x: 用户id }

$socket.send(to, 消息类型, 消息内容) 发送消息

可以发给某人(当to是用户id时)或广播给某个频道里的所有人(当to是频道时)。
它是异步接口,不等待发送结果就执行下一表达式(因此无$r),发送结果转而由onData接收,格式如下:

{ 
    type: text,          // 消息类型 
    to: User/text,       // 接收人ID或频道名
    auth: User,          // 发送人ID
    session: bigint,     // 发送人会话ID
    x: {},               // 消息内容
    id: bigint,          // 物理主键 db开启后才有
    grp: text            // 分组group db开启后才有
}

zchannel是特殊消息类型,用在已打开连接要订阅新频道时,比如加入新群聊,在新群发消息前先订阅一下$socket.send(群id, "zchannel")才能收到此群的消息。如果不想再收到此群消息则可通过$socket.send(群id, "zchannel", -1)退订。

$socket.online(频道) 在线用户

查询当前指定频道的在线用户,返回用户会话id和用户id的映射对象:{ [session]: user }
可通过.keys()获取会话数组;通过.values()获取用户数组,如果选项login传入的是0(允许用户未登录),则用户可能为空,加上.filter("$x")可过滤掉未登录用户。

db开启后首次发消息时会创建socket

{
    id: bigint,
    type: text,     // 消息类型
    auth: bigint,   // 发送人ID
    grp: text,      // 分组group
    x: {}           // 消息内容
}

群聊的话它的grp为频道ID,私聊的话它的grp是由双方用户ID排序拼接而成,x是消息内容。

它也具有业务表的一些通用接口:
$socket.find(Q, O, 缓存, 回调)
$socket.count(Q, 缓存)
$socket.get(id, 缓存)
$socket.delete(id)
$socket.clear()

例如,查找"我的"私聊消息历史:$socket.find({ grp: { $regex: $me.id } });查找某个群聊消息历史:$socket.find({ grp: 群ID })

后端

$socket.send(to, 消息类型, 消息内容, 选项)
可用选项:{ auth: 发送人, db: true, self: true }。默认发送人是me.id,可指定发送人,比如系统定时触发时。

$socket.find(Q, O, 缓存)
$socket.count(Q, 缓存)
$socket.get(id)
$socket.delete(id)
$socket.clear()

由众触低代码平台生成和驱动