feat: 实现 internal/protocol 帧类型、编解码、校验与请求指纹
This commit is contained in:
@@ -0,0 +1,393 @@
|
||||
package protocol
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Target 是发送目标。
|
||||
type Target struct {
|
||||
Kind string `json:"kind"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Body 是消息正文。
|
||||
type Body struct {
|
||||
Enc string `json:"enc"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
// OfflineOpts 是离线保留选项。
|
||||
type OfflineOpts struct {
|
||||
Keep bool `json:"keep"`
|
||||
TTLSeconds *int64 `json:"ttl_seconds,omitempty"`
|
||||
}
|
||||
|
||||
// Limits 是与服务器配置相关的校验上限。
|
||||
type Limits struct {
|
||||
MaxBodyBytes int
|
||||
MaxMetaBytes int
|
||||
MaxFrameBytes int
|
||||
}
|
||||
|
||||
// DefaultLimits 返回 DEVELOPMENT 示例中的默认上限。
|
||||
func DefaultLimits() Limits {
|
||||
return Limits{
|
||||
MaxBodyBytes: DefaultMaxBodyBytes,
|
||||
MaxMetaBytes: DefaultMaxMetaBytes,
|
||||
MaxFrameBytes: DefaultMaxFrameBytes,
|
||||
}
|
||||
}
|
||||
|
||||
func (l Limits) withDefaults() Limits {
|
||||
if l.MaxBodyBytes <= 0 {
|
||||
l.MaxBodyBytes = DefaultMaxBodyBytes
|
||||
}
|
||||
if l.MaxMetaBytes <= 0 {
|
||||
l.MaxMetaBytes = DefaultMaxMetaBytes
|
||||
}
|
||||
if l.MaxFrameBytes <= 0 {
|
||||
l.MaxFrameBytes = DefaultMaxFrameBytes
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// Hello 是握手请求(第 6.1 节)。
|
||||
type Hello struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
MaxReceiveBytes *int `json:"max_receive_bytes,omitempty"`
|
||||
Client string `json:"client,omitempty"`
|
||||
}
|
||||
|
||||
// HelloData 是握手成功响应 data。
|
||||
type HelloData struct {
|
||||
ServerTimeMs int64 `json:"server_time_ms"`
|
||||
ServerVersion string `json:"server_version"`
|
||||
MaxBodyBytes int `json:"max_body_bytes"`
|
||||
MaxMetaBytes int `json:"max_meta_bytes"`
|
||||
MaxFrameBytes int `json:"max_frame_bytes"`
|
||||
MaxTTLSeconds int64 `json:"max_ttl_seconds"`
|
||||
MaxScheduleSeconds int64 `json:"max_schedule_seconds"`
|
||||
AckTimeoutSeconds int64 `json:"ack_timeout_seconds"`
|
||||
SessionToken string `json:"session_token,omitempty"`
|
||||
}
|
||||
|
||||
// Resp 是通用响应帧。
|
||||
type Resp struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
OK bool `json:"ok"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
Error *ErrorBody `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Send 是发送请求(第 6.2 节)。
|
||||
type Send struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
ID string `json:"id"`
|
||||
To Target `json:"to"`
|
||||
Body Body `json:"body"`
|
||||
Meta map[string]any `json:"meta,omitempty"`
|
||||
DelayMs *int64 `json:"delay_ms,omitempty"`
|
||||
SendAtMs *int64 `json:"send_at_ms,omitempty"`
|
||||
Offline *OfflineOpts `json:"offline,omitempty"`
|
||||
Receipt *bool `json:"receipt,omitempty"`
|
||||
TalkPassword string `json:"talk_password,omitempty"`
|
||||
}
|
||||
|
||||
// SendData 是发送成功响应 data。
|
||||
type SendData struct {
|
||||
ID string `json:"id"`
|
||||
SendAtMs int64 `json:"send_at_ms"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// Msg 是下行消息(第 6.3 节)。
|
||||
type Msg struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
From string `json:"from"`
|
||||
To Target `json:"to"`
|
||||
Body Body `json:"body"`
|
||||
Meta map[string]any `json:"meta,omitempty"`
|
||||
SendAtMs int64 `json:"send_at_ms"`
|
||||
}
|
||||
|
||||
// Ack 是确认请求。
|
||||
type Ack struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
From string `json:"from"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// Recall 是撤回请求。
|
||||
type Recall struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// RecallData 是撤回响应 data。
|
||||
type RecallData struct {
|
||||
Result string `json:"result"`
|
||||
Recalled int `json:"recalled"`
|
||||
Accepted int `json:"accepted"`
|
||||
Other int `json:"other"`
|
||||
}
|
||||
|
||||
// Status 是状态查询请求。
|
||||
type Status struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
ID string `json:"id"`
|
||||
Cursor string `json:"cursor,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// Receipt 是回执下行。
|
||||
type Receipt struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
ReceiptID string `json:"receipt_id"`
|
||||
ID string `json:"id"`
|
||||
EndpointID string `json:"endpoint_id"`
|
||||
State string `json:"state"`
|
||||
Reason string `json:"reason"`
|
||||
AtMs int64 `json:"at_ms"`
|
||||
}
|
||||
|
||||
// ReceiptAck 是回执确认。
|
||||
type ReceiptAck struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
ReceiptID string `json:"receipt_id"`
|
||||
}
|
||||
|
||||
// Revoked 是已推送消息作废通知。
|
||||
type Revoked struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
From string `json:"from"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// PresenceGet 查询在线状态。
|
||||
type PresenceGet struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
IDs []string `json:"ids"`
|
||||
}
|
||||
|
||||
// DirectoryList 列目录。
|
||||
type DirectoryList struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
Cursor string `json:"cursor,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Query string `json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// PresenceWatch 订阅上下线。
|
||||
type PresenceWatch struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
IDs []string `json:"ids,omitempty"`
|
||||
All bool `json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// Presence 是上下线通知。
|
||||
type Presence struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
Online bool `json:"online"`
|
||||
AtMs int64 `json:"at_ms"`
|
||||
}
|
||||
|
||||
// Unlock 解锁对话密码。
|
||||
type Unlock struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
EndpointID string `json:"endpoint_id"`
|
||||
TalkPassword string `json:"talk_password"`
|
||||
}
|
||||
|
||||
// SelfGet 读取自己的资料。
|
||||
type SelfGet struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
}
|
||||
|
||||
// SelfUpdate 更新自己的资料。
|
||||
type SelfUpdate struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
Name string `json:"name,omitempty"`
|
||||
DefaultDelayMs *int64 `json:"default_delay_ms,omitempty"`
|
||||
}
|
||||
|
||||
// SelfTalkPassword 设置对话密码。
|
||||
type SelfTalkPassword struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
TalkPassword string `json:"talk_password"`
|
||||
}
|
||||
|
||||
// SelfLoginPassword 修改登录密码。
|
||||
type SelfLoginPassword struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
OldPassword string `json:"old_password"`
|
||||
NewPassword string `json:"new_password"`
|
||||
}
|
||||
|
||||
// SelfLogout 退出登录并作废会话令牌。
|
||||
type SelfLogout struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
}
|
||||
|
||||
// GroupMemberIn 是建群/加群时的成员项。
|
||||
type GroupMemberIn struct {
|
||||
ID string `json:"id"`
|
||||
TalkPassword string `json:"talk_password,omitempty"`
|
||||
}
|
||||
|
||||
// GroupCreate 建群。
|
||||
type GroupCreate struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Members []GroupMemberIn `json:"members"`
|
||||
}
|
||||
|
||||
// GroupAdd 加成员。
|
||||
type GroupAdd struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
Members []GroupMemberIn `json:"members"`
|
||||
}
|
||||
|
||||
// GroupRemove 移除成员。
|
||||
type GroupRemove struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
EndpointID string `json:"endpoint_id"`
|
||||
}
|
||||
|
||||
// GroupLeave 退群。
|
||||
type GroupLeave struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// GroupTransfer 转让群主。
|
||||
type GroupTransfer struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
EndpointID string `json:"endpoint_id"`
|
||||
}
|
||||
|
||||
// GroupRename 改群名。
|
||||
type GroupRename struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// GroupDissolve 解散群。
|
||||
type GroupDissolve struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
}
|
||||
|
||||
// GroupList 列出我的群。
|
||||
type GroupList struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
Cursor string `json:"cursor,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// GroupGet 获取群详情。
|
||||
type GroupGet struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
RID string `json:"rid"`
|
||||
GroupID string `json:"group_id"`
|
||||
Cursor string `json:"cursor,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// GroupEvent 是群事件下行。
|
||||
type GroupEvent struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
GroupID string `json:"group_id"`
|
||||
Event string `json:"event"`
|
||||
EndpointID string `json:"endpoint_id,omitempty"`
|
||||
AtMs int64 `json:"at_ms"`
|
||||
}
|
||||
|
||||
// Fatal 是致命错误下行。
|
||||
type Fatal struct {
|
||||
V int `json:"v"`
|
||||
Type string `json:"type"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
// RegisterRequest 是 HTTP 注册请求(第 6.9 节)。
|
||||
type RegisterRequest struct {
|
||||
RegistrationCode string `json:"registration_code"`
|
||||
ID string `json:"id"`
|
||||
LoginPassword string `json:"login_password"`
|
||||
Name string `json:"name,omitempty"`
|
||||
TalkPassword string `json:"talk_password,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterData 是注册成功 data。
|
||||
type RegisterData struct {
|
||||
ID string `json:"id"`
|
||||
LoginPassword string `json:"login_password,omitempty"`
|
||||
}
|
||||
|
||||
// RegisterResponse 是注册 HTTP 响应。
|
||||
type RegisterResponse struct {
|
||||
OK bool `json:"ok"`
|
||||
Data RegisterData `json:"data,omitempty"`
|
||||
Error *ErrorBody `json:"error,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user