package wsclient import ( "encoding/json" "fmt" "log" "net/url" "git.lxtend.com/qqbot/action" "git.lxtend.com/qqbot/constants" "git.lxtend.com/qqbot/handler" "git.lxtend.com/qqbot/model" "github.com/gorilla/websocket" ) type WebSocketClient struct { conn *websocket.Conn done chan struct{} } func NewWebSocketClient(scheme, host, path string) (*WebSocketClient, error) { u := url.URL{Scheme: scheme, Host: host, Path: path} log.Printf("Connecting to %s", u.String()) conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { return nil, err } client := &WebSocketClient{ conn: conn, done: make(chan struct{}), } defer func() { if r := recover(); r != nil { log.Print("Recovered in NewWebSocketClient:", r) go client.receiveMessages() } }() go client.receiveMessages() return client, nil } func (c *WebSocketClient) receiveMessages() { defer close(c.done) for { _, message, err := c.conn.ReadMessage() if err != nil { log.Println("Error reading message:", err) return } var event model.EventMessage if err = json.Unmarshal(message, &event); err != nil { log.Println("Error unmarshalling message:", err) return } msg := model.Message{ UserId: event.UserID, OriginMsgId: event.MessageID, RawMsg: event.RawMessage, UserNickName: event.Sender.Nickname, } if event.MessageType == constants.GROUP_MSG { msg.GroupInfo = model.GroupInfo{ IsGroupMsg: true, GroupId: event.GroupID, UserCard: event.Sender.Card, } } else { msg.GroupInfo = model.GroupInfo{ IsGroupMsg: false, GroupId: event.Sender.GroupID, } } go func() { reply := handler.MsgInHandler(msg) if reply.ReplyMsg != "" { if reply.ReferOriginMsg { reply.ReplyMsg = fmt.Sprintf("%s%s", action.GenReply(reply.FromMsg.OriginMsgId, "", 0, 0, 0), reply.ReplyMsg) } sendPkg := model.GenSendPkg(reply.FromMsg.UserId, reply.FromMsg.GroupInfo.GroupId, reply.ReplyMsg, false) sendPkgJson, err := json.Marshal(sendPkg) if err != nil { log.Println("Error marshalling sendPkg:", err) return } if err = c.SendMessage(websocket.TextMessage, sendPkgJson); err != nil { log.Println("Error sending message:", err) return } } }() } } func (c *WebSocketClient) SendMessage(messageType int, message []byte) error { return c.conn.WriteMessage(messageType, message) } func (c *WebSocketClient) Close() error { err := c.conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { return err } <-c.done return c.conn.Close() }