forked from ProjectWIND/ProjectWIND
192 lines
4.9 KiB
Go
192 lines
4.9 KiB
Go
package core
|
||
|
||
import (
|
||
"ProjectWIND/LOG"
|
||
"ProjectWIND/typed"
|
||
"ProjectWIND/wba"
|
||
"encoding/json"
|
||
"fmt"
|
||
"github.com/gorilla/websocket"
|
||
"net/http"
|
||
"net/url"
|
||
)
|
||
|
||
var gProtocol typed.Protocol
|
||
|
||
// WebSocketHandler 接收WebSocket连接处的消息并处理
|
||
func WebSocketHandler(protocol typed.Protocol) error {
|
||
// 保存全局变量
|
||
gProtocol = protocol
|
||
// 解析连接URL
|
||
u, err := url.Parse(protocol.Addr)
|
||
if err != nil {
|
||
LOG.Error("Parse URL error: %v", err)
|
||
return err
|
||
}
|
||
|
||
// 创建一个带有Authorization头的HTTP请求
|
||
req, err := http.NewRequest("GET", u.String(), nil)
|
||
if err != nil {
|
||
LOG.Fatal("创建请求出错:%v", err)
|
||
}
|
||
req.Header.Set("Authorization", "Bearer "+protocol.Token)
|
||
// 配置WebSocket连接升级器
|
||
dialer := websocket.DefaultDialer
|
||
// 使用升级器建立WebSocket连接
|
||
conn, _, err := dialer.Dial(req.URL.String(), req.Header)
|
||
if err != nil {
|
||
LOG.Fatal("建立WebSocket连接出错:%v", err)
|
||
}
|
||
defer func(conn *websocket.Conn) {
|
||
err := conn.Close()
|
||
if err != nil {
|
||
LOG.Error("Close error: %v", err)
|
||
}
|
||
}(conn)
|
||
LOG.Info("已连接到WebSocket服务器: %v", u.String())
|
||
ProtocolInfo := AppApi.GetVersionInfo()
|
||
LOG.Info("协议端信息: %v-%v", ProtocolInfo.Data.AppName, ProtocolInfo.Data.AppVersion)
|
||
logInfo := AppApi.GetLoginInfo()
|
||
LOG.Info("连接到账号: %v(%v)", logInfo.Data.Nickname, logInfo.Data.UserId)
|
||
|
||
// 定义通道,缓存消息和消息类型,防止消息处理阻塞
|
||
messageChan := make(chan []byte, 32)
|
||
messageTypeChan := make(chan int, 32)
|
||
for {
|
||
// 接收消息并放入通道
|
||
messageType, message, err := conn.ReadMessage()
|
||
if err != nil {
|
||
LOG.Error("ReadMessage error: %v", err)
|
||
return err
|
||
}
|
||
messageChan <- message
|
||
messageTypeChan <- messageType
|
||
|
||
// 启动一个新的goroutine来处理消息
|
||
go func() {
|
||
defer func() {
|
||
// 处理完成后从通道中移除消息
|
||
<-messageChan
|
||
<-messageTypeChan
|
||
}()
|
||
processMessage(messageType, message)
|
||
}()
|
||
}
|
||
}
|
||
|
||
// processMessage 处理接收到的消息
|
||
func processMessage(messageType int, message []byte) {
|
||
if messageType != websocket.TextMessage {
|
||
LOG.Error("Invalid message type: %v", messageType)
|
||
return
|
||
}
|
||
//message json解析
|
||
var messageMap map[string]interface{}
|
||
err := json.Unmarshal(message, &messageMap)
|
||
if err != nil {
|
||
LOG.Error("Unmarshal error: %v", err)
|
||
return
|
||
}
|
||
// 处理接收到的消息
|
||
messageTypeStr := messageMap["post_type"]
|
||
switch messageTypeStr {
|
||
case "message":
|
||
{
|
||
// 处理message消息
|
||
HandleMessage(message)
|
||
return
|
||
}
|
||
case "notice":
|
||
{
|
||
// 处理notice消息
|
||
HandleNotice(message)
|
||
return
|
||
}
|
||
case "request":
|
||
{
|
||
// 处理request消息
|
||
HandleRequest(message)
|
||
return
|
||
}
|
||
case "meta_event":
|
||
{
|
||
// 处理meta_event消息
|
||
HandleMetaEvent(message)
|
||
return
|
||
}
|
||
}
|
||
}
|
||
|
||
// wsSendMessage 向WebSocket服务器发送消息并返回发送状态
|
||
func wsAPI(body wba.APIRequestInfo) (Response wba.APIResponseInfo, err error) {
|
||
// 序列化请求体
|
||
bodyBytes, err := json.Marshal(body)
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, err
|
||
}
|
||
// 解析连接URL
|
||
u, err := url.Parse(gProtocol.Addr)
|
||
if err != nil {
|
||
LOG.Error("Parse URL error: %v", err)
|
||
return wba.APIResponseInfo{}, err
|
||
}
|
||
// 创建一个带有Authorization头的HTTP请求
|
||
req, err := http.NewRequest("GET", u.String(), nil)
|
||
if err != nil {
|
||
LOG.Fatal("创建请求出错:%v", err)
|
||
}
|
||
req.Header.Set("Authorization", "Bearer "+gProtocol.Token)
|
||
// 配置WebSocket连接升级器
|
||
dialer := websocket.DefaultDialer
|
||
// 使用升级器建立WebSocket连接
|
||
conn, _, err := dialer.Dial(req.URL.String(), req.Header)
|
||
if err != nil {
|
||
LOG.Fatal("建立WebSocket连接出错:%v", err)
|
||
}
|
||
defer func(conn *websocket.Conn) {
|
||
err := conn.Close()
|
||
if err != nil {
|
||
LOG.Error("Close error: %v", err)
|
||
}
|
||
}(conn)
|
||
err = conn.WriteMessage(websocket.TextMessage, bodyBytes)
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, fmt.Errorf("请求发送失败: %v", err)
|
||
}
|
||
if body.Action == "get_group_list" || body.Action == "get_member_list" {
|
||
for {
|
||
_, message, err := conn.ReadMessage()
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, fmt.Errorf("响应接收失败: %v", err)
|
||
}
|
||
var Response wba.APIResponseInfo
|
||
err = json.Unmarshal(message, &Response)
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, fmt.Errorf("unmarshal error: %v", err)
|
||
}
|
||
if Response.Echo == body.Echo {
|
||
return Response, nil
|
||
}
|
||
}
|
||
}
|
||
//检查是否含有echo字段
|
||
if body.Echo != "" {
|
||
// 接收响应消息,直到收到echo字段一致的消息
|
||
for {
|
||
_, message, err := conn.ReadMessage()
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, fmt.Errorf("响应接收失败: %v", err)
|
||
}
|
||
var Response wba.APIResponseInfo
|
||
err = json.Unmarshal(message, &Response)
|
||
if err != nil {
|
||
return wba.APIResponseInfo{}, fmt.Errorf("unmarshal error: %v", err)
|
||
}
|
||
if Response.Echo == body.Echo {
|
||
return Response, nil
|
||
}
|
||
}
|
||
}
|
||
return wba.APIResponseInfo{}, nil
|
||
}
|