api.ApplicationRealtime(appID) 打开一个 Server-Sent Events 流并返回 *rest.RealtimeStream。使用 stream.Next() 迭代它,直到 io.EOF。
client := rest.NewClient(os.Getenv("SQUARECLOUD_API_KEY"))
defer client.Close()
api := rest.New(client)
消费流
stream, err := api.ApplicationRealtime("abc123def456abc123def456")
if err != nil {
panic(err)
}
defer stream.Close()
for {
event, err := stream.Next()
if err == io.EOF {
break // stream ended (e.g. 10-minute TTL reached)
}
if err != nil {
panic(err)
}
fmt.Println(event.Name, string(event.Data))
}
始终 defer stream.Close() —— 未关闭的流会一直占用你账户的一个连接槽位。
事件形态
流会发出两类帧:
- 系统事件 —— 连接生命周期消息:
REALTIME_CONNECTING、REALTIME_TIMEOUT、REALTIME_DISCONNECTED、REALTIME_RECONNECT 和 REALTIME_ERROR。
message 事件 —— 应用载荷。Data 对 SDK 来说是不透明的,通常是 JSON —— 需要你自己反序列化:
if event.Name == "message" {
var payload map[string]any
if err := json.Unmarshal(event.Data, &payload); err == nil {
fmt.Println(payload)
}
}
连接限制
单个账户最多可同时保持 5 个连接,每个连接最长持续 10 分钟(其 TTL)。达到 TTL 时流以 io.EOF 结束 —— 在循环中重连以保持订阅。
for {
stream, err := api.ApplicationRealtime("abc123def456abc123def456")
if err != nil {
panic(err)
}
for {
event, err := stream.Next()
if err != nil {
break // io.EOF on TTL — reconnect
}
fmt.Println(event.Name, string(event.Data))
}
stream.Close()
}
使用 rest.WithContext 附加一个 context.Context,以便从外部停止流:
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
stream, err := api.ApplicationRealtime("abc123def456abc123def456", rest.WithContext(ctx))
if err != nil {
panic(err)
}
defer stream.Close()
// cancel() from another goroutine ends the stream