package main import ( "context" "log/slog" "git.asio.asia/nixevol/NixMsg/internal/app/message" "git.asio.asia/nixevol/NixMsg/internal/app/port" ) // appUplink 把 broker 生命周期接到消息连接表与投递推送。 // 其余业务上行帧暂转交 next(可为空 Stub);完整 HandleUplink 分发留后续波次。 type appUplink struct { msg *message.App conns *message.MemoryConns next port.UplinkHandler log *slog.Logger } func (u *appUplink) OnSessionEstablished(ctx context.Context, conn port.ConnInfo) error { u.conns.Set(conn.EndpointID, message.LiveConn{ ConnID: conn.ConnID, MaxPacketSize: conn.MaxPacketSize, }) if u.next != nil { return u.next.OnSessionEstablished(ctx, conn) } return nil } func (u *appUplink) OnHandshakeComplete(ctx context.Context, hs port.HandshakeInfo) error { live := message.LiveConn{ ConnID: hs.ConnID, MaxReceiveBytes: hs.MaxReceiveBytes, MaxPacketSize: hs.MaxPacketSize, } u.conns.Set(hs.EndpointID, live) if err := u.msg.OnHandshakeComplete(ctx, hs.EndpointID, live); err != nil { u.log.Error("message handshake", "endpoint", hs.EndpointID, "err", err) return err } if u.next != nil { return u.next.OnHandshakeComplete(ctx, hs) } return nil } func (u *appUplink) OnDisconnect(ctx context.Context, conn port.ConnInfo, reason port.DisconnectReason) { live, ok := u.conns.Current(conn.EndpointID) isCurrent := ok && live.ConnID == conn.ConnID if err := u.msg.OnDisconnect(ctx, conn.EndpointID, conn.ConnID, isCurrent); err != nil { u.log.Error("message disconnect", "endpoint", conn.EndpointID, "err", err) } u.conns.Clear(conn.EndpointID, conn.ConnID) if u.next != nil { u.next.OnDisconnect(ctx, conn, reason) } } func (u *appUplink) HandleUplink(ctx context.Context, conn port.ConnInfo, payload []byte) error { if u.next != nil { return u.next.HandleUplink(ctx, conn, payload) } return nil } // presenceConnTable 把消息连接表暴露给 presence.ConnTable。 type presenceConnTable struct { conns *message.MemoryConns } func (p *presenceConnTable) IsOnline(endpointID string) bool { _, ok := p.conns.Current(endpointID) return ok } func (p *presenceConnTable) CurrentConn(endpointID string) (port.ConnID, bool) { live, ok := p.conns.Current(endpointID) if !ok { return "", false } return live.ConnID, true }