diff --git a/onebot_action.go b/onebot_action.go index 20d4b7a..bc6785d 100644 --- a/onebot_action.go +++ b/onebot_action.go @@ -1,6 +1,7 @@ package libonebot import ( + "context" "fmt" ) @@ -22,8 +23,9 @@ func (ob *OneBot) Handle(handler Handler) { // CallAction 调用指定动作. // // 参数: -// action: 要调用的动作名称 -// params: 动作参数, 若传入 nil 则实际动作参数为空 map +// +// action: 要调用的动作名称 +// params: 动作参数, 若传入 nil 则实际动作参数为空 map func (ob *OneBot) CallAction(action string, params map[string]interface{}) Response { if params == nil { params = make(map[string]interface{}) @@ -54,7 +56,22 @@ func (ob *OneBot) handleRequest(r *Request) (resp Response) { } ob.Logger.Debugf("动作请求 `%v` 开始处理", r.Action) - ob.actionHandler.HandleAction(w, r) + ctx, cancelFunc := context.WithCancel(context.Background()) + r.Ctx = ctx + go func() { + defer cancelFunc() + defer func() { + err := recover() + if err != nil { + if _, ok := err.(error); ok { + w.WriteFailed(RetCodeInternalHandlerError, err.(error)) + } + ob.Logger.Errorf("处理%v时出现异常:%#v", r.Action, err) + } + }() + ob.actionHandler.HandleAction(w, r) + }() + <-ctx.Done() if resp.Status == statusOK { ob.Logger.Infof("动作请求 `%v` 处理成功", r.Action) } else if resp.Status == statusFailed { diff --git a/onebot_event.go b/onebot_event.go index df24194..dbbb7b2 100644 --- a/onebot_event.go +++ b/onebot_event.go @@ -41,7 +41,16 @@ type marshaledEvent struct { } func (ob *OneBot) openEventListenChan() <-chan marshaledEvent { - ch := make(chan marshaledEvent) // TODO: channel size + ch := make(chan marshaledEvent, 1) // 设置缓冲区为1,因为需要先放入一个连接事件 + connectMetaEvent := MakeConnectMetaEvent(ob.Impl, Version, OneBotVersion) + ob.Logger.Debugf("事件: %#v", connectMetaEvent) + ob.Logger.Infof("事件 `%v` 开始推送", connectMetaEvent.Name()) + eventBytes, _ := json.Marshal(connectMetaEvent) + ch <- marshaledEvent{ + name: connectMetaEvent.Name(), + bytes: eventBytes, + raw: &connectMetaEvent, + } ob.eventListenChansLock.Lock() ob.eventListenChans = append(ob.eventListenChans, ch) ob.eventListenChansLock.Unlock() diff --git a/proto_action_request.go b/proto_action_request.go index 90bc354..3dbef9f 100644 --- a/proto_action_request.go +++ b/proto_action_request.go @@ -4,6 +4,7 @@ package libonebot import ( + "context" "errors" "github.com/botuniverse/go-libonebot/utils" @@ -28,11 +29,12 @@ type RequestComm struct { // Request 表示一个动作请求. type Request struct { - Comm RequestComm // 接收动作请求的通信方式 - Action string // 动作名称 - Params EasierMap // 动作参数 - Echo string // 动作请求的 echo 字段, 用户未指定时为空字符串 - Self *Self // 机器人自身标识, 用户未指定时为 nil + Comm RequestComm // 接收动作请求的通信方式 + Action string // 动作名称 + Params EasierMap // 动作参数 + Echo string // 动作请求的 echo 字段, 用户未指定时为空字符串 + Self *Self // 机器人自身标识, 用户未指定时为 nil + Ctx context.Context // 上下文控制 } func parseRequestFromMap(m map[string]interface{}, reqComm RequestComm) (r Request, err error) { diff --git a/proto_event.go b/proto_event.go index 7d2cf9f..484670b 100644 --- a/proto_event.go +++ b/proto_event.go @@ -92,6 +92,21 @@ func MakeMetaEvent(time time.Time, detailType string) MetaEvent { } } +type VersionStruct struct { + Impl string `json:"impl"` + Version string `json:"version"` + OnebotVersion string `json:"onebot_version"` +} + +type ConnectMetaEvent struct { + MetaEvent + Version VersionStruct `json:"version"` +} + +func MakeConnectMetaEvent(impl, v, onebotVersion string) ConnectMetaEvent { + return ConnectMetaEvent{MetaEvent: MakeMetaEvent(time.Now(), "connect"), Version: VersionStruct{impl, v, onebotVersion}} +} + // MessageEvent 表示一个消息事件. type MessageEvent struct { Event