first commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package wxcore
|
||||
|
||||
import "xiawan/wx/srv/wxface"
|
||||
|
||||
// WXBaseRouter 实现router时,先嵌入这个基类,然后根据需要对这个基类的方法进行重写
|
||||
type WXBaseRouter struct{}
|
||||
|
||||
// PreHandle 在处理conn业务之前的钩子方法
|
||||
func (wxbr *WXBaseRouter) PreHandle(response wxface.IWXResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle 处理conn业务的方法
|
||||
func (wxbr *WXBaseRouter) Handle(response wxface.IWXResponse) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PostHandle 处理conn业务之后的钩子方法
|
||||
func (wxbr *WXBaseRouter) PostHandle(response wxface.IWXResponse) error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strconv"
|
||||
"xiawan/wx/clientsdk/baseinfo"
|
||||
"xiawan/wx/clientsdk/baseutils"
|
||||
"xiawan/wx/db"
|
||||
|
||||
// "xiawan/wx/srv/wxcore"
|
||||
|
||||
"xiawan/wx/srv/wxface"
|
||||
)
|
||||
|
||||
// WXCache 缓存
|
||||
type WXCache struct {
|
||||
wxConn wxface.IWXConnect
|
||||
// 二维码缓存信息
|
||||
qrCodeInfoCache *baseinfo.QrcodeInfo
|
||||
// 收藏缓存信息
|
||||
favorInfoCache *baseinfo.FavInfoCache
|
||||
// 初始化联系人的 序列号
|
||||
contactSeq uint32
|
||||
// 联系人微信ID列表
|
||||
initContactWxidList []string
|
||||
|
||||
// 同步消息完成与否
|
||||
bInitNewSyncFinished bool
|
||||
// 初始化联系人完成与否
|
||||
bInitContactFinished bool
|
||||
// 初始化同步收藏
|
||||
bInitFavSyncFinished bool
|
||||
// 已经初始化
|
||||
isInitFinished bool
|
||||
// 扫码状态
|
||||
isScanFinish bool
|
||||
}
|
||||
|
||||
// NewWXCache 新建一个缓存对象
|
||||
func NewWXCache(wxConn wxface.IWXConnect) wxface.IWXCache {
|
||||
return &WXCache{
|
||||
qrCodeInfoCache: new(baseinfo.QrcodeInfo),
|
||||
favorInfoCache: new(baseinfo.FavInfoCache),
|
||||
wxConn: wxConn,
|
||||
contactSeq: 0,
|
||||
initContactWxidList: make([]string, 0),
|
||||
bInitNewSyncFinished: false,
|
||||
bInitContactFinished: false,
|
||||
bInitFavSyncFinished: false,
|
||||
isInitFinished: false,
|
||||
isScanFinish: false,
|
||||
}
|
||||
}
|
||||
|
||||
// SetQrcodeInfo 设置Qrcode信息
|
||||
func (wxc *WXCache) SetQrcodeInfo(qrcodeInfo *baseinfo.QrcodeInfo) {
|
||||
wxc.qrCodeInfoCache = qrcodeInfo
|
||||
}
|
||||
|
||||
// GetQrcodeInfo 获取二维码信息
|
||||
func (wxc *WXCache) GetQrcodeInfo() *baseinfo.QrcodeInfo {
|
||||
return wxc.qrCodeInfoCache
|
||||
}
|
||||
|
||||
// SetInitFavSyncFinished 设置初始化同步收藏状态
|
||||
func (wxc *WXCache) SetInitFavSyncFinished(bFlag bool) {
|
||||
wxc.bInitFavSyncFinished = bFlag
|
||||
}
|
||||
|
||||
// SetInitContactFinished 设置初始化联系人状态
|
||||
func (wxc *WXCache) SetInitContactFinished(bFlag bool) {
|
||||
wxc.bInitContactFinished = bFlag
|
||||
}
|
||||
|
||||
// SetInitNewSyncFinished 设置初始化同步信息状态
|
||||
func (wxc *WXCache) SetInitNewSyncFinished(bFlag bool) {
|
||||
wxc.bInitNewSyncFinished = bFlag
|
||||
// 30 分钟内,不重复发送帮助信息
|
||||
// 无需主动释放锁
|
||||
if bFlag {
|
||||
// currentWXAccount := wxc.wxConn.GetWXAccount()
|
||||
// uuid := currentWXAccount.GetUserInfo().UUID
|
||||
// lockKey := "SendUsage_lock_" + uuid
|
||||
// lockAcquired, _ := db.AcquireLock(lockKey, time.Minute*30)
|
||||
// if lockAcquired {
|
||||
// // wxc.SendUsage()
|
||||
// }
|
||||
// 如果未完成扫码则发送指令缓存
|
||||
if !wxc.isScanFinish {
|
||||
// wxc.InitCmds(lockAcquired)
|
||||
// wxc.SendUsage()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 扫码完成
|
||||
func (wxc *WXCache) IsScanFinish() bool {
|
||||
return wxc.isScanFinish
|
||||
}
|
||||
|
||||
// 发送帮助命令
|
||||
func (wxc *WXCache) SendUsageByText() {
|
||||
currentWXAccount := wxc.wxConn.GetWXAccount()
|
||||
uuid := currentWXAccount.GetUserInfo().UUID
|
||||
lockKey := "SendUsage_lock_" + uuid
|
||||
// 释放
|
||||
currentWXAccount.GetUserInfo().SetIsServerRestart(false)
|
||||
db.ReleaseLock(lockKey)
|
||||
wxc.SendUsage()
|
||||
}
|
||||
|
||||
// 设置扫码状态
|
||||
func (wxc *WXCache) SetScanFinish(bFlag bool) {
|
||||
wxc.isScanFinish = bFlag
|
||||
if bFlag {
|
||||
// currentWXAccount := wxc.wxConn.GetWXAccount()
|
||||
// uuid := currentWXAccount.GetUserInfo().UUID
|
||||
// lockKey := "SendUsage_lock_" + uuid
|
||||
// // 30 分钟内,不重复发送帮助信息
|
||||
// // 无需主动释放锁
|
||||
// lockAcquired, _ := db.AcquireLock(lockKey, time.Minute*30)
|
||||
// if lockAcquired {
|
||||
// // 发送【帮助】
|
||||
// wxc.SendUsage()
|
||||
// }
|
||||
// 初始化信息未完成则发送指令缓存
|
||||
if !wxc.bInitNewSyncFinished {
|
||||
// wxc.InitCmds(lockAcquired)
|
||||
// wxc.SendUsage()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func (wxc *WXCache) IsMsgSyncAndContact() bool {
|
||||
wxc.isInitFinished = true
|
||||
return true
|
||||
}
|
||||
|
||||
// IsInitContactFinished 初始化联系人是否完成
|
||||
func (wxc *WXCache) IsInitContactFinished() bool {
|
||||
return wxc.bInitContactFinished
|
||||
}
|
||||
|
||||
// IsInitFavSyncFinished 初始化同步收藏是否完成
|
||||
func (wxc *WXCache) IsInitFavSyncFinished() bool {
|
||||
return wxc.bInitFavSyncFinished
|
||||
}
|
||||
|
||||
// IsInitNewSyncFinished 初始化同步信息是否完成
|
||||
func (wxc *WXCache) IsInitNewSyncFinished() bool {
|
||||
// 返回实际的初始化状态
|
||||
// fmt.Printf("IsInitNewSyncFinished() 被调用,返回 %v\n", wxc.bInitNewSyncFinished)
|
||||
return wxc.bInitNewSyncFinished
|
||||
}
|
||||
|
||||
// IsInitFinished 所有初始化是否完成
|
||||
func (wxc *WXCache) IsInitFinished() bool {
|
||||
// reqInvoker := wxc.wxConn.GetWXReqInvoker()
|
||||
// ghWxid := srvconfig.GlobalSetting.GhWxid
|
||||
// if len(ghWxid) > 0 { // 引流关注公众号
|
||||
// // 注意: 这里的微信公众号的 wxid 一定要填对
|
||||
// reqInvoker.VerifyUserRequest(1, "", 0, ghWxid, ghWxid, "")
|
||||
// }
|
||||
return wxc.bInitNewSyncFinished && wxc.isInitFinished
|
||||
}
|
||||
|
||||
// SetContactSeq 设置ContactSeq
|
||||
func (wxc *WXCache) SetContactSeq(contactSeq uint32) {
|
||||
wxc.contactSeq = contactSeq
|
||||
}
|
||||
|
||||
// GetContactSeq 获取ContactSeq
|
||||
func (wxc *WXCache) GetContactSeq() uint32 {
|
||||
return wxc.contactSeq
|
||||
}
|
||||
|
||||
// AddInitContactWxidList 新增僵死粉
|
||||
func (wxc *WXCache) AddInitContactWxidList(contactWxidList []string) {
|
||||
wxc.initContactWxidList = append(wxc.initContactWxidList, contactWxidList...)
|
||||
}
|
||||
|
||||
// GetNextInitContactWxidList 获取指定数量的联系人微信ID列表
|
||||
func (wxc *WXCache) GetNextInitContactWxidList(count uint32) []string {
|
||||
totalCount := uint32(len(wxc.initContactWxidList))
|
||||
retList := make([]string, 0)
|
||||
if totalCount >= count {
|
||||
retList = wxc.initContactWxidList[:count]
|
||||
wxc.initContactWxidList = wxc.initContactWxidList[count:]
|
||||
} else {
|
||||
retList = wxc.initContactWxidList
|
||||
wxc.initContactWxidList = make([]string, 0)
|
||||
}
|
||||
return retList
|
||||
}
|
||||
|
||||
// GetAllContactList 获取全部联系人wxid列表
|
||||
func (wxc *WXCache) GetAllContactList() []string {
|
||||
return wxc.initContactWxidList
|
||||
}
|
||||
|
||||
// Clear 清空缓存
|
||||
func (wxc *WXCache) Clear() {
|
||||
wxc.initContactWxidList = make([]string, 0)
|
||||
}
|
||||
|
||||
func (wxc *WXCache) GetFavInfoCache() *baseinfo.FavInfoCache {
|
||||
return wxc.favorInfoCache
|
||||
}
|
||||
|
||||
func (wxc *WXCache) SetIsInitFinished(bFlag bool) {
|
||||
wxc.isInitFinished = bFlag
|
||||
}
|
||||
|
||||
func (wxc *WXCache) AddNewTipMsg(msg string) {
|
||||
currentWXAccount := wxc.wxConn.GetWXAccount()
|
||||
currentWXFileHelperMgr := wxc.wxConn.GetWXFileHelperMgr()
|
||||
isServerRestart := currentWXAccount.GetUserInfo().GetIsServerRestart()
|
||||
if !isServerRestart {
|
||||
currentWXFileHelperMgr.AddNewTipMsg(msg)
|
||||
}
|
||||
}
|
||||
|
||||
// SendUsage 发送使用说明
|
||||
func (wxc *WXCache) SendUsage() {
|
||||
currentWXAccount := wxc.wxConn.GetWXAccount()
|
||||
// 命令 start --------
|
||||
currentTaskMgr := wxc.wxConn.GetWXTaskMgr()
|
||||
taskMgr, _ := currentTaskMgr.(*WXTaskMgr)
|
||||
currentGrapHBTask := taskMgr.GetGrabHBTask()
|
||||
currentSnsTransTask := taskMgr.GetSnsTransTask()
|
||||
currentSnsTask := taskMgr.GetSnsTask()
|
||||
currentVerifyTask := taskMgr.GetVerifyTask()
|
||||
currentRevokeTask := taskMgr.GetRevokeTask()
|
||||
|
||||
uuid := currentWXAccount.GetUserInfo().UUID
|
||||
commandInfo, _ := db.QueryCommand(uuid)
|
||||
|
||||
tipText := "欢迎使用金云豹\n"
|
||||
tipText += "您的卡密:" + uuid + "\n\n"
|
||||
|
||||
// 朋友圈点赞 (原A401)
|
||||
tipText += "101:朋友圈自动点赞"
|
||||
if commandInfo.A401 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentSnsTask.SetAutoThumbUP(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentSnsTask.SetAutoThumbUP(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 朋友圈评论 (原B001)
|
||||
tipText += "102:朋友圈自动评论"
|
||||
if commandInfo.B001 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentSnsTask.SetAutoComment(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentSnsTask.SetAutoComment(false)
|
||||
}
|
||||
tipText += "\n102#"
|
||||
if len(commandInfo.B001Str) > 0 {
|
||||
tipText += commandInfo.B001Str
|
||||
currentSnsTask.SetCommentContent(commandInfo.B001Str)
|
||||
} else {
|
||||
tipText += "回复内容"
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 自动入群 (原A811)
|
||||
tipText += "103:自动入群邀请"
|
||||
if commandInfo.A811 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentVerifyTask.SetAutoJoinGroup(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentVerifyTask.SetAutoJoinGroup(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 通过好友验证 (原A801)
|
||||
tipText += "104:通过好友验证"
|
||||
if commandInfo.A801 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentVerifyTask.SetNeedVerify(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentVerifyTask.SetNeedVerify(false)
|
||||
}
|
||||
tipText += "\n104#"
|
||||
if len(commandInfo.A301Str) > 0 {
|
||||
tipText += commandInfo.A301Str
|
||||
currentSnsTransTask.SetAddFriendAutoMsg(commandInfo.A301Str)
|
||||
} else {
|
||||
tipText += "通过后回复内容"
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 消息防撤回 (原A601)
|
||||
tipText += "105:消息防止撤回"
|
||||
if commandInfo.A601 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentRevokeTask.SetAvoidRevoke(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentRevokeTask.SetAvoidRevoke(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 自动领取红包 (原A101)
|
||||
tipText += "106:自动领取红包"
|
||||
if commandInfo.A101 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetAutoGrap(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetAutoGrap(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 延迟领取红包 (原A103)
|
||||
tipText += "107:延迟领取红包"
|
||||
if commandInfo.A103 > 0 {
|
||||
tipText += "【开启】"
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
}
|
||||
tipText += "\n107#" + strconv.Itoa(commandInfo.A103)
|
||||
tipText += "\n"
|
||||
|
||||
// 领取红包后感谢 (原A104)
|
||||
tipText += "108:领取红包后感谢"
|
||||
if commandInfo.A104 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetAutoReply(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetAutoReply(false)
|
||||
}
|
||||
tipText += "\n108#"
|
||||
if len(commandInfo.A104Str) > 0 {
|
||||
tipText += commandInfo.A104Str
|
||||
currentGrapHBTask.SetAutoReplyContent(commandInfo.A104Str)
|
||||
} else {
|
||||
tipText += "谢谢,谢谢老板"
|
||||
currentGrapHBTask.SetAutoReplyContent("谢谢,谢谢老板")
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 领取个人红包 (原A105)
|
||||
tipText += "109:领取个人红包"
|
||||
if commandInfo.A105 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetAutoPerson(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetAutoPerson(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 置顶群组红包 (原A111)
|
||||
tipText += "110:置顶群组红包"
|
||||
if commandInfo.A111 == 1 {
|
||||
tipText += "【仅抢】"
|
||||
currentGrapHBTask.SetNotTopGroup(true)
|
||||
} else {
|
||||
tipText += "【不抢】"
|
||||
currentGrapHBTask.SetNotTopGroup(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 自动接收转账 (原A106)
|
||||
tipText += "111:自动接收转账"
|
||||
if commandInfo.A106 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetAutoTransfer(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetAutoTransfer(false)
|
||||
}
|
||||
tipText += "\n111#"
|
||||
if len(commandInfo.A116Str) > 0 {
|
||||
tipText += commandInfo.A116Str
|
||||
currentGrapHBTask.SetAutoTransferReplyContent(commandInfo.A116Str)
|
||||
} else {
|
||||
tipText += "回复内容"
|
||||
currentGrapHBTask.SetAutoTransferReplyContent("谢谢,谢谢老板")
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 红包统计功能 (原A107)
|
||||
tipText += "112:红包统计功能"
|
||||
if commandInfo.A107 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetHBStat(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetHBStat(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 红包统计清零 (原A108)
|
||||
tipText += "113:红包统计清零\n"
|
||||
|
||||
// 收款统计功能 (原A109)
|
||||
tipText += "114:收款统计功能"
|
||||
if commandInfo.A109 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentGrapHBTask.SetTransStat(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentGrapHBTask.SetTransStat(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 收款统计清零 (原A110)
|
||||
tipText += "115:收款统计清零\n"
|
||||
|
||||
// 查询置顶群聊 (原200)
|
||||
tipText += "116:查询置顶的群聊\n"
|
||||
|
||||
// 朋友圈收藏转发 (原A403)
|
||||
tipText += "117:朋友圈收藏转发"
|
||||
if commandInfo.A403 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentSnsTransTask.SetAutoRelay(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentSnsTransTask.SetAutoRelay(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 朋友圈跟随转发 (原A402)
|
||||
tipText += "118:朋友圈跟随转发"
|
||||
if commandInfo.A402 == 1 {
|
||||
tipText += "【开启】"
|
||||
currentSnsTransTask.SetSyncTrans(true)
|
||||
} else {
|
||||
tipText += "【关闭】"
|
||||
currentSnsTransTask.SetSyncTrans(false)
|
||||
}
|
||||
tipText += "\n"
|
||||
|
||||
// 检测僵死粉 (原901)
|
||||
tipText += "119:检测僵死粉\n"
|
||||
|
||||
// 清理僵死粉 (原902)
|
||||
tipText += "120:清理僵死粉\n"
|
||||
|
||||
// 帮助和功能状态 (原000)
|
||||
tipText += "000:帮助和功能状态\n"
|
||||
|
||||
// 查询卡密有效期 (原100)
|
||||
tipText += "666:查询卡密有效期"
|
||||
|
||||
wxc.AddNewTipMsg(tipText)
|
||||
}
|
||||
func GetOwner() map[string]int {
|
||||
tmpHomeDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
baseutils.PrintLog(err.Error())
|
||||
return nil
|
||||
}
|
||||
file, err := os.Open(tmpHomeDir + "/assets/owner.json")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer file.Close()
|
||||
// 解码 JSON 数据
|
||||
var data map[string]int
|
||||
decoder := json.NewDecoder(file)
|
||||
if err := decoder.Decode(&data); err != nil {
|
||||
return nil
|
||||
}
|
||||
return data
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,222 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"time"
|
||||
|
||||
"xiawan/wx/api/req"
|
||||
"xiawan/wx/clientsdk/baseinfo"
|
||||
"xiawan/wx/srv/wxface"
|
||||
|
||||
"github.com/lunny/log"
|
||||
)
|
||||
|
||||
// WXFileHelperMgr 文件传输助手消息管理器
|
||||
type WXFileHelperMgr struct {
|
||||
wxConn wxface.IWXConnect
|
||||
msgList chan *MsgItem
|
||||
endChan chan bool
|
||||
isStarted bool
|
||||
}
|
||||
|
||||
// MsgItem MsgItem
|
||||
type MsgItem struct {
|
||||
TextMsg string
|
||||
ImageData []byte
|
||||
MsgType uint32
|
||||
}
|
||||
|
||||
// NewWXFileHelperMgr 新建文件传输助手管理器
|
||||
func NewWXFileHelperMgr(wxConn wxface.IWXConnect) *WXFileHelperMgr {
|
||||
return &WXFileHelperMgr{
|
||||
wxConn: wxConn,
|
||||
msgList: make(chan *MsgItem, 100),
|
||||
endChan: make(chan bool, 1),
|
||||
isStarted: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Start 开启
|
||||
func (wxfhm *WXFileHelperMgr) Start() {
|
||||
if wxfhm.isStarted {
|
||||
return
|
||||
}
|
||||
wxfhm.isStarted = true
|
||||
go wxfhm.startDealMsg()
|
||||
}
|
||||
|
||||
// Stop 关闭
|
||||
func (wxfhm *WXFileHelperMgr) Stop() {
|
||||
wxfhm.isStarted = false
|
||||
wxfhm.endChan <- true
|
||||
wxfhm.isStarted = false
|
||||
}
|
||||
|
||||
// AddNewTipMsg 新增提示
|
||||
func (wxfhm *WXFileHelperMgr) AddNewTipMsg(newMsg string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &MsgItem{}
|
||||
newMsgItem.MsgType = 1
|
||||
newMsgItem.TextMsg = newMsg
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 新增名片消息 AddNewCardMsg
|
||||
func (wxfhm *WXFileHelperMgr) AddNewCardMsg(newMsg string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &MsgItem{}
|
||||
newMsgItem.MsgType = 42
|
||||
newMsgItem.TextMsg = newMsg
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// AddImageMsg 新增图片消息
|
||||
func (wxfhm *WXFileHelperMgr) AddImageMsg(imgData []byte) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &MsgItem{}
|
||||
newMsgItem.MsgType = 2
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 转发图片
|
||||
func (wxfhm *WXFileHelperMgr) ForwardImageMsg(imgData []byte) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &MsgItem{}
|
||||
newMsgItem.MsgType = 3
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 转发表情
|
||||
func (wxfhm *WXFileHelperMgr) ForwardEmoticonMsg(imgData []byte) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &MsgItem{}
|
||||
newMsgItem.MsgType = 47
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 处理消息
|
||||
func (wxfhm *WXFileHelperMgr) startDealMsg() {
|
||||
defer TryE("(wxfhm *WXFileHelperMgr) startDealMsg()")
|
||||
currentReqInvoker := wxfhm.wxConn.GetWXReqInvoker()
|
||||
for {
|
||||
// 最少1秒发送一次
|
||||
time.Sleep(1 * time.Second)
|
||||
select {
|
||||
case newMsgItem := <-wxfhm.msgList:
|
||||
if newMsgItem.MsgType == 1 {
|
||||
// 文字
|
||||
currentReqInvoker.SendTextMsgToFileHelperRequest(newMsgItem.TextMsg)
|
||||
} else if newMsgItem.MsgType == 2 {
|
||||
// 图片
|
||||
currentReqInvoker.SendImageToFileHelper(newMsgItem.ImageData)
|
||||
} else if newMsgItem.MsgType == 42 {
|
||||
// 名片
|
||||
// 发送消息
|
||||
currentReqInvoker.SendCardMsgToFileHelperRequest(newMsgItem.TextMsg)
|
||||
// currentReqInvoker.SendCardMsgToFileHelper(newMsgItem.TextMsg)
|
||||
} else if newMsgItem.MsgType == 3 {
|
||||
// 图片
|
||||
var msg baseinfo.Msg3
|
||||
err := xml.Unmarshal(newMsgItem.ImageData, &msg)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing XML: %v", err)
|
||||
return
|
||||
}
|
||||
if msg.Img.CdnThumbURL != "" {
|
||||
sendMsg := baseinfo.ForwardImageItem{
|
||||
ToUserName: baseinfo.FileHelperWXID,
|
||||
AesKey: msg.Img.AESKey,
|
||||
CdnMidImgUrl: msg.Img.CdnThumbURL,
|
||||
CdnMidImgSize: msg.Img.CdnThumbLength,
|
||||
CdnThumbImgSize: msg.Img.Length,
|
||||
}
|
||||
_, _ = currentReqInvoker.ForwardCdnImageRequest(sendMsg)
|
||||
}
|
||||
|
||||
} else if newMsgItem.MsgType == 47 {
|
||||
// 表情
|
||||
var msg baseinfo.Msg47
|
||||
err := xml.Unmarshal(newMsgItem.ImageData, &msg)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing XML: %v", err)
|
||||
return
|
||||
}
|
||||
if msg.Emoji.MD5 != "" {
|
||||
sendMsg := req.SendEmojiItem{
|
||||
ToUserName: baseinfo.FileHelperWXID,
|
||||
EmojiMd5: msg.Emoji.MD5,
|
||||
EmojiSize: msg.Emoji.Len,
|
||||
}
|
||||
_, _ = currentReqInvoker.ForwardEmojiRequest(sendMsg.EmojiMd5, sendMsg.ToUserName, sendMsg.EmojiSize)
|
||||
}
|
||||
}
|
||||
case <-wxfhm.endChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package wxcore
|
||||
|
||||
// WXLongRequest 微信长链接请求
|
||||
type WXLongRequest struct {
|
||||
OpCode uint32
|
||||
Data []byte
|
||||
}
|
||||
|
||||
// GetOpcode 获取Opcode
|
||||
func (wxlq *WXLongRequest) GetOpcode() uint32 {
|
||||
return wxlq.OpCode
|
||||
}
|
||||
|
||||
// GetData 获取数据
|
||||
func (wxlq *WXLongRequest) GetData() []byte {
|
||||
return wxlq.Data
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"xiawan/wx/srv/srvconfig"
|
||||
"xiawan/wx/srv/wxface"
|
||||
)
|
||||
|
||||
// WXMsgHandler 微信响应管理器
|
||||
type WXMsgHandler struct {
|
||||
wxRouterMap map[uint32]wxface.IWXRouter //存放每个MsgId 所对应的处理方法的map属性
|
||||
wxWorkerPoolSize uint32 //业务工作Worker池的数量
|
||||
wxTaskQueue []chan wxface.IWXResponse //Worker负责取任务的消息队列
|
||||
}
|
||||
|
||||
// NewWXMsgHandler 新建微信消息处理器
|
||||
func NewWXMsgHandler() *WXMsgHandler {
|
||||
return &WXMsgHandler{
|
||||
wxRouterMap: make(map[uint32]wxface.IWXRouter),
|
||||
// 一个worker对应一个queue
|
||||
wxWorkerPoolSize: srvconfig.GlobalSetting.WorkerPoolSize * 2,
|
||||
wxTaskQueue: make([]chan wxface.IWXResponse, srvconfig.GlobalSetting.WorkerPoolSize*2),
|
||||
}
|
||||
}
|
||||
|
||||
// AddRouter 增加微信消息路由
|
||||
func (wxmh *WXMsgHandler) AddRouter(respID uint32, wxRouter wxface.IWXRouter) {
|
||||
//1 判断当前msg绑定的API处理方法是否已经存在
|
||||
if _, ok := wxmh.wxRouterMap[respID]; ok {
|
||||
return
|
||||
}
|
||||
//2 添加msg与api的绑定关系
|
||||
wxmh.wxRouterMap[respID] = wxRouter
|
||||
}
|
||||
|
||||
// GetRouterByRespID 根据响应ID获取对应的路由
|
||||
func (wxmh *WXMsgHandler) GetRouterByRespID(urlID uint32) wxface.IWXRouter {
|
||||
handler, ok := wxmh.wxRouterMap[urlID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return handler
|
||||
}
|
||||
|
||||
// doMsgHandler 马上以非阻塞方式处理消息
|
||||
func (wxmh *WXMsgHandler) doMsgHandler(response wxface.IWXResponse) {
|
||||
//xiaoyue处理消息
|
||||
// fmt.Println("xiaoyue------doMsgHandler")
|
||||
// defer TryE(response.GetWXConncet().GetWXAccount().GetUserInfo().GetUserName())
|
||||
handler, ok := wxmh.wxRouterMap[response.GetPackHeader().URLID]
|
||||
// fmt.Println("[URLID]", response.GetPackHeader().URLID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
//执行对应处理方法
|
||||
handler.PreHandle(response)
|
||||
handler.Handle(response)
|
||||
handler.PostHandle(response)
|
||||
}
|
||||
|
||||
// startOneWorker 启动一个Worker工作流程
|
||||
func (wxmh *WXMsgHandler) startOneWorker(workerID int, taskQueue chan wxface.IWXResponse) {
|
||||
// fmt.Println("xiaoyue------startOneWorker")
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Printf("startOneWorker recovered from panic: %v\n", r)
|
||||
// 可以在这里记录日志或执行其他紧急恢复处理措施
|
||||
}
|
||||
}()
|
||||
//不断的等待队列中的消息
|
||||
for {
|
||||
select {
|
||||
//有消息则取出队列的Request,并执行绑定的业务方法
|
||||
case request := <-taskQueue:
|
||||
wxmh.doMsgHandler(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StartWorkerPool 启动worker工作池
|
||||
func (wxmh *WXMsgHandler) StartWorkerPool() {
|
||||
defer TryE("")
|
||||
// fmt.Println("xiaoyue------StartWorkerPool")
|
||||
//遍历需要启动worker的数量,依此启动
|
||||
for i := 0; i < int(wxmh.wxWorkerPoolSize); i++ {
|
||||
//一个worker被启动
|
||||
//给当前worker对应的任务队列开辟空间
|
||||
wxmh.wxTaskQueue[i] = make(chan wxface.IWXResponse, srvconfig.GlobalSetting.MaxWorkerTaskLen*2)
|
||||
//启动当前Worker,阻塞的等待对应的任务队列是否有消息传递进来
|
||||
go wxmh.startOneWorker(i, wxmh.wxTaskQueue[i])
|
||||
}
|
||||
}
|
||||
|
||||
// SendWXRespToTaskQueue 将消息交给TaskQueue,由worker进行处理
|
||||
func (wxmh *WXMsgHandler) SendWXRespToTaskQueue(response wxface.IWXResponse) {
|
||||
//得到需要处理此条连接的workerID
|
||||
workerID := response.GetWXConncet().GetWXConnID() % wxmh.wxWorkerPoolSize
|
||||
//将请求消息发送给任务队列
|
||||
wxmh.wxTaskQueue[workerID] <- response
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"xiawan/wx/clientsdk/baseinfo"
|
||||
"xiawan/wx/srv/wxface"
|
||||
)
|
||||
|
||||
// WXResponse 微信响应
|
||||
type WXResponse struct {
|
||||
wxConn wxface.IWXConnect
|
||||
packHeader *baseinfo.PackHeader
|
||||
//业务日志Id
|
||||
LogUUID string
|
||||
}
|
||||
|
||||
// NewWXResponse 新建WXResponse
|
||||
func NewWXResponse(wxConn wxface.IWXConnect, packHeader *baseinfo.PackHeader) wxface.IWXResponse {
|
||||
return &WXResponse{
|
||||
wxConn: wxConn,
|
||||
packHeader: packHeader,
|
||||
}
|
||||
}
|
||||
|
||||
// GetPackHeader 获取响应数据
|
||||
func (resp *WXResponse) GetPackHeader() *baseinfo.PackHeader {
|
||||
return resp.packHeader
|
||||
}
|
||||
|
||||
// GetWXConncet 获取WXConncet
|
||||
func (resp *WXResponse) GetWXConncet() wxface.IWXConnect {
|
||||
return resp.wxConn
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
"xiawan/wx/srv"
|
||||
"xiawan/wx/srv/wxface"
|
||||
)
|
||||
|
||||
// WXServer 微信服务器,处理与微信的交互
|
||||
type WXServer struct {
|
||||
wxMsgHandler wxface.IWXMsgHandler
|
||||
wxConnectMgr wxface.IWXConnectMgr
|
||||
wxFileMgr *srv.WXFileMgr
|
||||
}
|
||||
|
||||
// NewWXServer 新建微信服务对象
|
||||
func NewWXServer() wxface.IWXServer {
|
||||
return &WXServer{
|
||||
wxMsgHandler: NewWXMsgHandler(),
|
||||
wxConnectMgr: NewWXConnManager(),
|
||||
wxFileMgr: srv.NewWXFileMgr(),
|
||||
}
|
||||
}
|
||||
|
||||
// Start 开启微信服务
|
||||
func (wxs *WXServer) Start() {
|
||||
defer TryE("(wxtm *WXServer) Start()")
|
||||
// fmt.Println("xiaoyue--------start开启微信服务")
|
||||
// 开启微信消息线程池
|
||||
wxs.wxMsgHandler.StartWorkerPool()
|
||||
//wxs.wxFileMgr.Start()
|
||||
}
|
||||
|
||||
// GetWXMsgHandler 获取微信消息管理器
|
||||
func (wxs *WXServer) GetWXMsgHandler() wxface.IWXMsgHandler {
|
||||
return wxs.wxMsgHandler
|
||||
}
|
||||
|
||||
// GetWXConnectMgr 获取微信链接管理器
|
||||
func (wxs *WXServer) GetWXConnectMgr() wxface.IWXConnectMgr {
|
||||
return wxs.wxConnectMgr
|
||||
}
|
||||
|
||||
// GetWXFileMgr 获取微信文件管理器
|
||||
func (wxs *WXServer) GetWXFileMgr() *srv.WXFileMgr {
|
||||
return wxs.wxFileMgr
|
||||
}
|
||||
|
||||
// AddWXRouter 添加微信消息路由
|
||||
func (wxs *WXServer) AddWXRouter(funcID uint32, wxRouter wxface.IWXRouter) {
|
||||
wxs.wxMsgHandler.AddRouter(funcID, wxRouter)
|
||||
}
|
||||
|
||||
// UpdateExpiryDate 更新授权码过期时间
|
||||
func (wxs *WXServer) UpdateExpiryDate(key, expiryDate string) {
|
||||
connMgr := wxs.GetWXConnectMgr()
|
||||
wxConn := connMgr.GetWXConnectByUserInfoUUID(key)
|
||||
if wxConn == nil {
|
||||
return
|
||||
}
|
||||
currentTaskMgr := wxConn.GetWXTaskMgr()
|
||||
taskMgr, _ := currentTaskMgr.(*WXTaskMgr)
|
||||
currentSnsTransTask := taskMgr.GetSnsTransTask()
|
||||
currentSnsTransTask.SetExpiryDate(expiryDate)
|
||||
}
|
||||
|
||||
// UpdateDisable 更新授权码禁用状态
|
||||
func (wxs *WXServer) UpdateDisable(key string, disable int) {
|
||||
connMgr := wxs.GetWXConnectMgr()
|
||||
wxConn := connMgr.GetWXConnectByUserInfoUUID(key)
|
||||
if wxConn == nil {
|
||||
return
|
||||
}
|
||||
currentTaskMgr := wxConn.GetWXTaskMgr()
|
||||
taskMgr, _ := currentTaskMgr.(*WXTaskMgr)
|
||||
currentSnsTransTask := taskMgr.GetSnsTransTask()
|
||||
currentSnsTransTask.SetDisable(disable)
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"xiawan/wx/clientsdk/baseinfo"
|
||||
"xiawan/wx/srv/wxface"
|
||||
)
|
||||
|
||||
// WXSyncMgr 同步管理器(同步消息,同步收藏等等)
|
||||
type WXSyncMgr struct {
|
||||
wxConn wxface.IWXConnect
|
||||
newSyncIDList chan uint32
|
||||
favSyncIDList chan uint32
|
||||
newInitIDList chan uint32
|
||||
endNewChan chan bool
|
||||
endFavChan chan bool
|
||||
endInitChan chan bool
|
||||
isStart bool
|
||||
}
|
||||
|
||||
// NewWXSyncMgr 新建同步管理器
|
||||
func NewWXSyncMgr(wxConn wxface.IWXConnect) wxface.IWXSyncMgr {
|
||||
return &WXSyncMgr{
|
||||
wxConn: wxConn,
|
||||
newSyncIDList: make(chan uint32, 100),
|
||||
favSyncIDList: make(chan uint32, 100),
|
||||
newInitIDList: make(chan uint32, 200),
|
||||
endNewChan: make(chan bool, 1),
|
||||
endFavChan: make(chan bool, 1),
|
||||
endInitChan: make(chan bool, 1),
|
||||
isStart: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Start 开启管理器
|
||||
func (wxsm *WXSyncMgr) Start() {
|
||||
if wxsm.isStart {
|
||||
return
|
||||
}
|
||||
wxsm.isStart = true
|
||||
go wxsm.startNewSyncListener()
|
||||
go wxsm.startFavSyncListener()
|
||||
// go wxsm.startInitSyncListener()
|
||||
}
|
||||
|
||||
// Stop 关闭管理器
|
||||
func (wxsm *WXSyncMgr) Stop() {
|
||||
wxsm.isStart = false
|
||||
wxsm.endNewChan <- true
|
||||
wxsm.endFavChan <- true
|
||||
wxsm.endInitChan <- true
|
||||
}
|
||||
|
||||
// SendNewSyncRequest 发送同步消息请求
|
||||
func (wxsm *WXSyncMgr) SendNewSyncRequest() {
|
||||
wxsm.newSyncIDList <- 1
|
||||
}
|
||||
|
||||
// SendFavSyncRequest 发送同步收藏请求
|
||||
func (wxsm *WXSyncMgr) SendFavSyncRequest() {
|
||||
wxsm.favSyncIDList <- 1
|
||||
}
|
||||
|
||||
func (wxsm *WXSyncMgr) SendSyncInitRequest() {
|
||||
wxsm.newInitIDList <- 1
|
||||
}
|
||||
|
||||
func (wxsm *WXSyncMgr) startNewSyncListener() {
|
||||
//处理异常
|
||||
defer TryE(wxsm.wxConn.GetWXAccount().GetUserInfo().GetUserName())
|
||||
currentReqInvoker := wxsm.wxConn.GetWXReqInvoker()
|
||||
for {
|
||||
select {
|
||||
case <-wxsm.newSyncIDList:
|
||||
// 同步消息
|
||||
currentReqInvoker.SendNewSyncRequest(baseinfo.MMSyncSceneTypeNeed)
|
||||
case <-wxsm.endNewChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wxsm *WXSyncMgr) startFavSyncListener() {
|
||||
currentReqInvoker := wxsm.wxConn.GetWXReqInvoker()
|
||||
for {
|
||||
// 3秒执行一次
|
||||
time.Sleep(1 * time.Second)
|
||||
select {
|
||||
case <-wxsm.favSyncIDList:
|
||||
// 同步收藏
|
||||
currentReqInvoker.SendFavSyncRequest()
|
||||
case <-wxsm.endFavChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (wxsm *WXSyncMgr) startInitSyncListener() {
|
||||
currentReqInvoker := wxsm.wxConn.GetWXReqInvoker()
|
||||
for {
|
||||
select {
|
||||
case <-wxsm.newInitIDList:
|
||||
// 同步收藏
|
||||
_ = currentReqInvoker.SendNewInitSyncRequest()
|
||||
case <-wxsm.endInitChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"xiawan/wx/srv/wxface"
|
||||
"xiawan/wx/srv/wxtask"
|
||||
)
|
||||
|
||||
// WXTaskMgr 任务管理器
|
||||
type WXTaskMgr struct {
|
||||
start bool
|
||||
wxConn wxface.IWXConnect
|
||||
friendTask *wxtask.WXFriendTask
|
||||
groupTask *wxtask.WXGroupTask
|
||||
grabHBTask *wxtask.WXGrabHBTask
|
||||
snsTransTask *wxtask.WXSnsTransTask
|
||||
revokeTask *wxtask.WXRevokeTask
|
||||
snsTask *wxtask.WXSnsTask
|
||||
verifyTask *wxtask.WXVerifyTask
|
||||
SocketMsgTask *wxtask.WXSocketMsgTask
|
||||
}
|
||||
|
||||
// NewWXTaskMgr 新建一个微信管理器
|
||||
func NewWXTaskMgr(wxConn wxface.IWXConnect) wxface.IWXTaskMgr {
|
||||
return &WXTaskMgr{
|
||||
wxConn: wxConn,
|
||||
friendTask: wxtask.NewWXFriendTask(wxConn),
|
||||
groupTask: wxtask.NewWXGroupTask(wxConn),
|
||||
grabHBTask: wxtask.NewWXGrabHBTask(wxConn),
|
||||
snsTransTask: wxtask.NewWXSnsTransTask(wxConn),
|
||||
revokeTask: wxtask.NewWXRevokeTask(wxConn),
|
||||
snsTask: wxtask.NewWXSnsTask(wxConn),
|
||||
verifyTask: wxtask.NewWXVerifyTask(wxConn),
|
||||
SocketMsgTask: wxtask.NewWXSocketMsgTask(wxConn),
|
||||
}
|
||||
}
|
||||
|
||||
// Start 启动
|
||||
func (wxtm *WXTaskMgr) Start() {
|
||||
fmt.Println("启动微信任务管理器")
|
||||
//处理异常
|
||||
// defer TryE("(wxtm *WXTaskMgr) Start()")
|
||||
if wxtm.start {
|
||||
return
|
||||
}
|
||||
wxtm.start = true
|
||||
// wxtm.grabHBTask.Start()
|
||||
wxtm.snsTransTask.Start()
|
||||
// wxtm.revokeTask.Start()
|
||||
wxtm.snsTask.Start()
|
||||
wxtm.SocketMsgTask.Start()
|
||||
}
|
||||
|
||||
// Stop 关闭
|
||||
func (wxtm *WXTaskMgr) Stop() {
|
||||
if !wxtm.start {
|
||||
return
|
||||
}
|
||||
wxtm.start = false
|
||||
// wxtm.grabHBTask.Stop()
|
||||
wxtm.snsTransTask.Stop()
|
||||
// wxtm.revokeTask.Stop()
|
||||
wxtm.snsTask.Stop()
|
||||
wxtm.SocketMsgTask.Stop()
|
||||
|
||||
}
|
||||
|
||||
func (wxtm *WXTaskMgr) GetTaskStatus() bool {
|
||||
return wxtm.start
|
||||
}
|
||||
|
||||
// GetGroupTask 获取群任务管理器
|
||||
func (wxtm *WXTaskMgr) GetGroupTask() *wxtask.WXGroupTask {
|
||||
return wxtm.groupTask
|
||||
}
|
||||
|
||||
// GetFriendTask 获取好友任务管理器
|
||||
func (wxtm *WXTaskMgr) GetFriendTask() *wxtask.WXFriendTask {
|
||||
return wxtm.friendTask
|
||||
}
|
||||
|
||||
// GetGrabHBTask 获取红包任务管理器
|
||||
func (wxtm *WXTaskMgr) GetGrabHBTask() *wxtask.WXGrabHBTask {
|
||||
return wxtm.grabHBTask
|
||||
}
|
||||
func (wxtm *WXTaskMgr) GetSocketMsgTask() *wxtask.WXSocketMsgTask {
|
||||
return wxtm.SocketMsgTask
|
||||
}
|
||||
|
||||
// GetSnsTransTask 获取朋友圈转发任务管理器
|
||||
func (wxtm *WXTaskMgr) GetSnsTransTask() *wxtask.WXSnsTransTask {
|
||||
return wxtm.snsTransTask
|
||||
}
|
||||
|
||||
// GetRevokeTask 获取防撤回消息任务管理器
|
||||
func (wxtm *WXTaskMgr) GetRevokeTask() *wxtask.WXRevokeTask {
|
||||
return wxtm.revokeTask
|
||||
}
|
||||
|
||||
// GetSnsTask 获取朋友圈任务管理器
|
||||
func (wxtm *WXTaskMgr) GetSnsTask() *wxtask.WXSnsTask {
|
||||
return wxtm.snsTask
|
||||
}
|
||||
|
||||
// GetVerifyTask 获取朋友圈任务管理器
|
||||
func (wxtm *WXTaskMgr) GetVerifyTask() *wxtask.WXVerifyTask {
|
||||
return wxtm.verifyTask
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 异常处理
|
||||
func TryE(userName string) {
|
||||
errs := recover()
|
||||
if errs == nil {
|
||||
return
|
||||
}
|
||||
now := time.Now() //获取当前时间
|
||||
timeFormat := now.Format("2006-01-02 15:04:05") //设定时间格式
|
||||
fileName := fmt.Sprintf("[%s]-%s-%vrn", userName, timeFormat, errs) //保存错误信息文件名:程序名-进程ID-当前时间(年月日时分秒)
|
||||
fmt.Println("error: ", fileName)
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package wxcore
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"time"
|
||||
|
||||
"xiawan/wx/api/req"
|
||||
"xiawan/wx/clientsdk/baseinfo"
|
||||
"xiawan/wx/srv/wxface"
|
||||
|
||||
"github.com/lunny/log"
|
||||
)
|
||||
|
||||
// WXUSerMsgMgr WX用户消息管理器
|
||||
type WXUSerMsgMgr struct {
|
||||
wxConn wxface.IWXConnect
|
||||
msgList chan *USerMsgItem
|
||||
endChan chan bool
|
||||
isStarted bool
|
||||
}
|
||||
|
||||
// USerMsgItem MsgItem
|
||||
type USerMsgItem struct {
|
||||
TextMsg string
|
||||
ImageData []byte
|
||||
MsgType uint32
|
||||
TOUserName string
|
||||
}
|
||||
|
||||
// NewWXFileHelperMgr 新建用户消息管理器
|
||||
func NewWXUSerMsgMgr(wxConn wxface.IWXConnect) *WXUSerMsgMgr {
|
||||
return &WXUSerMsgMgr{
|
||||
wxConn: wxConn,
|
||||
msgList: make(chan *USerMsgItem, 100),
|
||||
endChan: make(chan bool, 1),
|
||||
isStarted: false,
|
||||
}
|
||||
}
|
||||
|
||||
// Start 开启
|
||||
func (wxfhm *WXUSerMsgMgr) Start() {
|
||||
if wxfhm.isStarted {
|
||||
return
|
||||
}
|
||||
wxfhm.isStarted = true
|
||||
go wxfhm.startDealMsg()
|
||||
}
|
||||
|
||||
// Stop 关闭
|
||||
func (wxfhm *WXUSerMsgMgr) Stop() {
|
||||
wxfhm.endChan <- true
|
||||
wxfhm.isStarted = false
|
||||
}
|
||||
|
||||
// AddNewMsg 新增提示
|
||||
func (wxfhm *WXUSerMsgMgr) AddNewTextMsg(newMsg, toUSerName string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &USerMsgItem{}
|
||||
newMsgItem.TOUserName = toUSerName
|
||||
newMsgItem.MsgType = 1
|
||||
newMsgItem.TextMsg = newMsg
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// AddImageMsg 新增图片消息
|
||||
func (wxfhm *WXUSerMsgMgr) AddImageMsg(imgData []byte, toUSerName string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &USerMsgItem{}
|
||||
newMsgItem.TOUserName = toUSerName
|
||||
newMsgItem.MsgType = 2
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 转发图片
|
||||
func (wxfhm *WXUSerMsgMgr) ForwardImageMsg(imgData []byte, toUSerName string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &USerMsgItem{}
|
||||
newMsgItem.TOUserName = toUSerName
|
||||
newMsgItem.MsgType = 3
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 转发表情
|
||||
func (wxfhm *WXUSerMsgMgr) ForwardEmoticonMsg(imgData []byte, toUSerName string) {
|
||||
if wxfhm.isStarted {
|
||||
newMsgItem := &USerMsgItem{}
|
||||
newMsgItem.TOUserName = toUSerName
|
||||
newMsgItem.MsgType = 47
|
||||
newMsgItem.ImageData = imgData
|
||||
wxfhm.msgList <- newMsgItem
|
||||
}
|
||||
}
|
||||
|
||||
// 处理消息
|
||||
func (wxfhm *WXUSerMsgMgr) startDealMsg() {
|
||||
//处理异常
|
||||
defer TryE("(wxfhm *WXUSerMsgMgr) startDealMsg()")
|
||||
currentReqInvoker := wxfhm.wxConn.GetWXReqInvoker()
|
||||
for {
|
||||
// 最少1秒发送一次
|
||||
time.Sleep(1 * time.Second)
|
||||
select {
|
||||
case newMsgItem := <-wxfhm.msgList:
|
||||
if newMsgItem.MsgType == 1 {
|
||||
// 文字
|
||||
_, _ = currentReqInvoker.SendTextMsgRequest(newMsgItem.TOUserName, newMsgItem.TextMsg, []string{}, 1)
|
||||
} else if newMsgItem.MsgType == 2 {
|
||||
// 图片
|
||||
_, _ = currentReqInvoker.SendCdnUploadImageReuqest(newMsgItem.ImageData, newMsgItem.TOUserName)
|
||||
} else if newMsgItem.MsgType == 3 {
|
||||
// 图片
|
||||
var msg baseinfo.Msg3
|
||||
err := xml.Unmarshal(newMsgItem.ImageData, &msg)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing XML: %v", err)
|
||||
return
|
||||
}
|
||||
sendMsg := baseinfo.ForwardImageItem{
|
||||
ToUserName: newMsgItem.TOUserName,
|
||||
AesKey: msg.Img.AESKey,
|
||||
CdnMidImgUrl: msg.Img.CdnThumbURL,
|
||||
CdnMidImgSize: msg.Img.CdnThumbLength,
|
||||
CdnThumbImgSize: msg.Img.Length,
|
||||
}
|
||||
_, _ = currentReqInvoker.ForwardCdnImageRequest(sendMsg)
|
||||
} else if newMsgItem.MsgType == 47 {
|
||||
// 表情
|
||||
var msg baseinfo.Msg47
|
||||
err := xml.Unmarshal(newMsgItem.ImageData, &msg)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing XML: %v", err)
|
||||
return
|
||||
}
|
||||
sendMsg := req.SendEmojiItem{
|
||||
ToUserName: newMsgItem.TOUserName,
|
||||
EmojiMd5: msg.Emoji.MD5,
|
||||
EmojiSize: msg.Emoji.Len,
|
||||
}
|
||||
_, _ = currentReqInvoker.ForwardEmojiRequest(sendMsg.EmojiMd5, sendMsg.ToUserName, sendMsg.EmojiSize)
|
||||
}
|
||||
case <-wxfhm.endChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user