Files
wechat_ipad_pro/srv/wxcore/wxconnectmgr.go
2026-02-17 13:06:23 +08:00

223 lines
6.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package wxcore
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
"time"
"xiawan/wx/srv/srvconfig"
"xiawan/wx/srv/websrv"
"xiawan/wx/clientsdk/baseinfo"
"xiawan/wx/srv/wxface"
)
// WXConnectMgr 微信链接管理器
type WXConnectMgr struct {
canUseConnIDList []uint32 // 删掉/回收后的connID
currentWxConnID uint32
wxConnectMap map[string]wxface.IWXConnect //管理的连接信息
wxConnLock sync.RWMutex //读写连接的读写锁
wxConnLockShowConnects sync.RWMutex //读写连接的读写锁
}
// NewWXConnManager 创建一个WX链接管理
func NewWXConnManager() wxface.IWXConnectMgr {
return &WXConnectMgr{
canUseConnIDList: make([]uint32, 0),
currentWxConnID: 0,
wxConnectMap: make(map[string]wxface.IWXConnect),
}
}
// Add 添加链接
func (wm *WXConnectMgr) Add(wxConnect wxface.IWXConnect) {
wm.wxConnLock.Lock()
defer wm.wxConnLock.Unlock()
// newConnID := uint32(0)
// if len(wm.canUseConnIDList) > 0 {
// newConnID = wm.canUseConnIDList[0]
// wm.canUseConnIDList = wm.canUseConnIDList[1:]
// } else {
// newConnID = wm.currentWxConnID
// wm.currentWxConnID++
// }
newConnID := wm.currentWxConnID
wm.currentWxConnID++
wxConnect.SetWXConnID(newConnID)
wm.wxConnectMap[wxConnect.GetWXAccount().GetUserInfo().UUID] = wxConnect
// 打印链接数量
wm.ShowConnectInfo()
}
// GetWXConnectByUserInfoUUID 根据UserInfoUUID获取微信链接
func (wm *WXConnectMgr) GetWXConnectByUserInfoUUID(userInfoUUID string) wxface.IWXConnect {
wm.wxConnLock.Lock()
defer wm.wxConnLock.Unlock()
wxConn, ok := wm.wxConnectMap[userInfoUUID]
if ok {
fmt.Println(fmt.Sprintf("GET Connection locfree success by %s", userInfoUUID))
return wxConn
}
fmt.Println(fmt.Sprintf("GET Connection locfree Failed by %s abandon the conntection get !", userInfoUUID))
return nil
}
// GetWXConnectByWXID 根据WXID获取微信链接
func (wm *WXConnectMgr) GetWXConnectByWXID(wxid string) wxface.IWXConnect {
for _, tryCoon := range wm.wxConnectMap {
tmpUserInfo := tryCoon.GetWXAccount().GetUserInfo()
if tmpUserInfo == nil || strings.Compare(tmpUserInfo.WxId, wxid) != 0 {
continue
}
return tryCoon
}
//保护共享资源Map 加读锁
wm.wxConnLock.RLock()
defer wm.wxConnLock.RUnlock()
//根据WXID获取微信链接
for _, wxConn := range wm.wxConnectMap {
tmpUserInfo := wxConn.GetWXAccount().GetUserInfo()
if tmpUserInfo == nil || strings.Compare(tmpUserInfo.WxId, wxid) != 0 {
continue
}
return wxConn
}
return nil
}
// Remove 删除连接
func (wm *WXConnectMgr) Remove(wxconn wxface.IWXConnect) {
wm.wxConnLock.Lock()
defer wm.wxConnLock.Unlock()
// 在删除连接前确保清理WebSocket连接
currentUserInfo := wxconn.GetWXAccount().GetUserInfo()
if currentUserInfo != nil {
currentTaskMgr := wxconn.GetWXTaskMgr()
if taskMgr, ok := currentTaskMgr.(*WXTaskMgr); ok {
wsTask := taskMgr.SocketMsgTask
userUUID := currentUserInfo.UUID
existingConn := wsTask.GetWebSocket(userUUID)
if existingConn != nil {
fmt.Println("Remove()时清理WebSocket连接:", userUUID)
existingConn.Close()
wsTask.DeleteWebSocket(userUUID)
}
// 禁用WebSocket功能
wsTask.SetWebSocketEnabled(false)
}
}
//删除
delete(wm.wxConnectMap, currentUserInfo.UUID)
//wm.canUseConnIDList = append(wm.canUseConnIDList, wxconn.GetWXConnID())
currentUserInfo = nil
// 打印链接数量
wm.ShowConnectInfo()
}
// Len 获取当前连接
func (wm *WXConnectMgr) Len() int {
return len(wm.wxConnectMap)
}
// ClearWXConn 删除并停止所有链接
func (wm *WXConnectMgr) ClearWXConn() {
//保护共享资源Map 加写锁
wm.wxConnLock.Lock()
defer wm.wxConnLock.Unlock()
//停止并删除全部的连接信息
for uuid, wxConn := range wm.wxConnectMap {
//停止
wxConn.Stop()
//删除
delete(wm.wxConnectMap, uuid)
}
// 打印链接数量
wm.ShowConnectInfo()
}
// ShowConnectInfo 打印链接情况
func (wm *WXConnectMgr) ShowConnectInfo() string {
wm.wxConnLockShowConnects.Lock()
defer wm.wxConnLockShowConnects.Unlock()
totalNum := wm.Len()
noLoginNum := uint32(0)
onlineNum := uint32(0)
offlineNum := uint32(0)
for _, wxConn := range wm.wxConnectMap {
loginState := wxConn.GetWXAccount().GetLoginState()
if loginState == baseinfo.MMLoginStateNoLogin {
noLoginNum = noLoginNum + 1
} else if loginState == baseinfo.MMLoginStateOnLine {
onlineNum = onlineNum + 1
} else if loginState == baseinfo.MMLoginStateOffLine {
offlineNum = offlineNum + 1
}
}
showText := time.Now().Format("2006-01-02 15:04:05")
showText = showText + " 总链接数量: " + strconv.Itoa(totalNum) + " 未登录数量:" + strconv.Itoa(int(noLoginNum))
showText = showText + " 在线数量: " + strconv.Itoa(int(onlineNum)) + " 离线数量: " + strconv.Itoa(int(offlineNum))
fmt.Println(showText)
return showText
}
func (wm *WXConnectMgr) GetConnectInfo() map[string]interface{} {
wm.wxConnLock.Lock()
defer wm.wxConnLock.Unlock()
totalNum := wm.Len()
noLoginNum := int(0)
onlineNum := int(0)
offlineNum := int(0)
var connections = make([]map[string]interface{}, 0)
for _, wxConn := range wm.wxConnectMap {
connections = append(connections, map[string]interface{}{
"loginState": wxConn.GetWXAccount().GetLoginState(),
"userInfo": wxConn.GetWXAccount().GetUserInfo(),
})
loginState := wxConn.GetWXAccount().GetLoginState()
if loginState == baseinfo.MMLoginStateNoLogin {
noLoginNum = noLoginNum + 1
} else if loginState == baseinfo.MMLoginStateOnLine {
onlineNum = onlineNum + 1
} else if loginState == baseinfo.MMLoginStateOffLine {
offlineNum = offlineNum + 1
}
}
return map[string]interface{}{
"time": time.Now().Format("2006-01-02 15:04:05"),
"totalNum": totalNum,
"noLoginNum": noLoginNum,
"onlineNum": onlineNum,
"offlineNum": offlineNum,
"connections": connections,
}
}
// 上报到后端 syncOnlineCount
func updateOnlineCount(count int32) error {
connectInfo := map[string]interface{}{}
connectInfo["ip"] = srvconfig.GlobalSetting.TargetIp
connectInfo["count"] = count
// 将参数转换为 JSON 格式
paramBytes, err := json.Marshal(connectInfo)
if err != nil {
fmt.Println("Error marshaling JSON:", err)
return err
}
if srvconfig.GlobalSetting.SyncOnlineCount == "" {
return nil
}
// 发送 POST 请求
fmt.Printf("上报在线数量:%d\n", count)
_, _ = websrv.TaskPostJson("http://"+srvconfig.GlobalSetting.SyncOnlineCount, paramBytes)
return nil
}