mirror of
https://github.com/duanhf2012/origin.git
synced 2026-03-11 10:07:31 +08:00
优化代码规范
This commit is contained in:
@@ -20,7 +20,6 @@ var DefaultReadTimeout time.Duration = time.Second * 10
|
||||
var DefaultWriteTimeout time.Duration = time.Second * 10
|
||||
var DefaultProcessTimeout time.Duration = time.Second * 10
|
||||
|
||||
//http redirect
|
||||
type HttpRedirectData struct {
|
||||
Url string
|
||||
CookieList []*http.Cookie
|
||||
@@ -53,7 +52,7 @@ type IHttpRouter interface {
|
||||
POST(url string, handle HttpHandle) bool
|
||||
Router(session *HttpSession)
|
||||
|
||||
SetServeFile(method HTTP_METHOD, urlpath string, dirname string) error
|
||||
SetServeFile(method HTTP_METHOD, urlPath string, dirname string) error
|
||||
SetFormFileKey(formFileKey string)
|
||||
GetFormFileKey() string
|
||||
AddHttpFiltrate(FiltrateFun HttpFiltrate) bool
|
||||
@@ -93,7 +92,7 @@ type HttpService struct {
|
||||
listenAddr string
|
||||
corsHeader *CORSHeader
|
||||
processTimeout time.Duration
|
||||
manualStart bool
|
||||
manualStart bool
|
||||
}
|
||||
|
||||
type HttpFiltrate func(session *HttpSession) bool //true is pass
|
||||
@@ -118,7 +117,7 @@ func NewHttpHttpRouter() IHttpRouter {
|
||||
return httpRouter
|
||||
}
|
||||
|
||||
func (slf *HttpSession) GetRawQuery() string{
|
||||
func (slf *HttpSession) GetRawQuery() string {
|
||||
return slf.r.URL.RawQuery
|
||||
}
|
||||
|
||||
@@ -215,7 +214,7 @@ func (slf *HttpRouter) analysisRouterUrl(url string) (string, error) {
|
||||
//替换所有空格
|
||||
url = strings.ReplaceAll(url, " ", "")
|
||||
if len(url) <= 1 || url[0] != '/' {
|
||||
return "", fmt.Errorf("url %s format is error!", url)
|
||||
return "", fmt.Errorf("url %s format is error", url)
|
||||
}
|
||||
|
||||
//去掉尾部的/
|
||||
@@ -300,12 +299,12 @@ func (httpService *HttpService) SetHttpRouter(httpRouter IHttpRouter, eventHandl
|
||||
httpService.RegEventReceiverFunc(event.Sys_Event_Http_Event, eventHandler, httpService.HttpEventHandler)
|
||||
}
|
||||
|
||||
func (slf *HttpRouter) SetServeFile(method HTTP_METHOD, urlpath string, dirname string) error {
|
||||
func (slf *HttpRouter) SetServeFile(method HTTP_METHOD, urlPath string, dirname string) error {
|
||||
_, err := os.Stat(dirname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
matchURL, aErr := slf.analysisRouterUrl(urlpath)
|
||||
matchURL, aErr := slf.analysisRouterUrl(urlPath)
|
||||
if aErr != nil {
|
||||
return aErr
|
||||
}
|
||||
@@ -350,15 +349,15 @@ func (slf *HttpSession) redirects() {
|
||||
func (httpService *HttpService) OnInit() error {
|
||||
iConfig := httpService.GetServiceCfg()
|
||||
if iConfig == nil {
|
||||
return fmt.Errorf("%s service config is error!", httpService.GetName())
|
||||
return fmt.Errorf("%s service config is error", httpService.GetName())
|
||||
}
|
||||
httpCfg := iConfig.(map[string]interface{})
|
||||
addr, ok := httpCfg["ListenAddr"]
|
||||
if ok == false {
|
||||
return fmt.Errorf("%s service config is error!", httpService.GetName())
|
||||
return fmt.Errorf("%s service config is error", httpService.GetName())
|
||||
}
|
||||
var readTimeout time.Duration = DefaultReadTimeout
|
||||
var writeTimeout time.Duration = DefaultWriteTimeout
|
||||
var readTimeout = DefaultReadTimeout
|
||||
var writeTimeout = DefaultWriteTimeout
|
||||
|
||||
if cfgRead, ok := httpCfg["ReadTimeout"]; ok == true {
|
||||
readTimeout = time.Duration(cfgRead.(float64)) * time.Millisecond
|
||||
@@ -370,8 +369,8 @@ func (httpService *HttpService) OnInit() error {
|
||||
|
||||
if manualStart, ok := httpCfg["ManualStart"]; ok == true {
|
||||
httpService.manualStart = manualStart.(bool)
|
||||
}else{
|
||||
manualStart =false
|
||||
} else {
|
||||
manualStart = false
|
||||
}
|
||||
|
||||
httpService.processTimeout = DefaultProcessTimeout
|
||||
|
||||
@@ -24,7 +24,7 @@ type CustomerSubscriber struct {
|
||||
subscribeMethod SubscribeMethod
|
||||
customerId string
|
||||
|
||||
isStop int32 //退出标记
|
||||
isStop int32 //退出标记
|
||||
topicCache []TopicData // 从消息队列中取出来的消息的缓存
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ func (cs *CustomerSubscriber) trySetSubscriberBaseInfo(rpcHandler rpc.IRpcHandle
|
||||
cs.serviceName = strRpcMethod[0]
|
||||
|
||||
if cluster.HasService(fromNodeId, cs.serviceName) == false {
|
||||
err := fmt.Errorf("nodeId %d cannot found %s", fromNodeId, cs.serviceName)
|
||||
err := fmt.Errorf("nodeId %s cannot found %s", fromNodeId, cs.serviceName)
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
if cluster.GetCluster().IsNodeConnected(fromNodeId) == false {
|
||||
err := fmt.Errorf("nodeId %d is disconnect", fromNodeId)
|
||||
err := fmt.Errorf("nodeId %s is disconnect", fromNodeId)
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func (cs *CustomerSubscriber) trySetSubscriberBaseInfo(rpcHandler rpc.IRpcHandle
|
||||
return nil
|
||||
}
|
||||
|
||||
// 开始订阅
|
||||
// Subscribe 开始订阅
|
||||
func (cs *CustomerSubscriber) Subscribe(rpcHandler rpc.IRpcHandler, ss *Subscriber, topic string, subscribeMethod SubscribeMethod, customerId string, fromNodeId string, callBackRpcMethod string, startIndex uint64, oneBatchQuantity int32) error {
|
||||
err := cs.trySetSubscriberBaseInfo(rpcHandler, ss, topic, subscribeMethod, customerId, fromNodeId, callBackRpcMethod, startIndex, oneBatchQuantity)
|
||||
if err != nil {
|
||||
@@ -96,7 +96,7 @@ func (cs *CustomerSubscriber) Subscribe(rpcHandler rpc.IRpcHandler, ss *Subscrib
|
||||
return nil
|
||||
}
|
||||
|
||||
// 取消订阅
|
||||
// UnSubscribe 取消订阅
|
||||
func (cs *CustomerSubscriber) UnSubscribe() {
|
||||
atomic.StoreInt32(&cs.isStop, 1)
|
||||
}
|
||||
@@ -163,14 +163,14 @@ func (cs *CustomerSubscriber) subscribe() bool {
|
||||
cs.publishToCustomer(topicData)
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
//从持久化数据中来找
|
||||
topicData = cs.subscriber.dataPersist.FindTopicData(cs.topic, cs.StartIndex, int64(cs.oneBatchQuantity),cs.topicCache[:0])
|
||||
topicData = cs.subscriber.dataPersist.FindTopicData(cs.topic, cs.StartIndex, int64(cs.oneBatchQuantity), cs.topicCache[:0])
|
||||
return cs.publishToCustomer(topicData)
|
||||
}
|
||||
|
||||
func (cs *CustomerSubscriber) checkCustomerIsValid() bool {
|
||||
//1.检查nodeid是否在线,不在线,直接取消订阅
|
||||
//1.检查nodeId是否在线,不在线,直接取消订阅
|
||||
if cluster.GetCluster().IsNodeConnected(cs.fromNodeId) == false {
|
||||
return false
|
||||
}
|
||||
@@ -213,7 +213,7 @@ func (cs *CustomerSubscriber) publishToCustomer(topicData []TopicData) bool {
|
||||
}
|
||||
|
||||
//推送数据
|
||||
err := cs.CallNodeWithTimeout(4*time.Minute,cs.fromNodeId, cs.callBackRpcMethod, &dbQueuePublishReq, &dbQueuePushRes)
|
||||
err := cs.CallNodeWithTimeout(4*time.Minute, cs.fromNodeId, cs.callBackRpcMethod, &dbQueuePublishReq, &dbQueuePushRes)
|
||||
if err != nil {
|
||||
time.Sleep(time.Second * 1)
|
||||
continue
|
||||
|
||||
@@ -19,7 +19,7 @@ func (mq *MemoryQueue) Init(cap int32) {
|
||||
mq.topicQueue = make([]TopicData, cap+1)
|
||||
}
|
||||
|
||||
// 从队尾Push数据
|
||||
// Push 从队尾Push数据
|
||||
func (mq *MemoryQueue) Push(topicData *TopicData) bool {
|
||||
mq.locker.Lock()
|
||||
defer mq.locker.Unlock()
|
||||
@@ -51,7 +51,7 @@ func (mq *MemoryQueue) findData(startPos int32, startIndex uint64, limit int32)
|
||||
} else {
|
||||
findEndPos = int32(len(mq.topicQueue))
|
||||
}
|
||||
|
||||
|
||||
if findStartPos >= findEndPos {
|
||||
return nil, false
|
||||
}
|
||||
@@ -87,21 +87,21 @@ func (mq *MemoryQueue) FindData(startIndex uint64, limit int32, dataQueue []Topi
|
||||
return nil, false
|
||||
} else if mq.head < mq.tail {
|
||||
// 队列没有折叠
|
||||
datas,ret := mq.findData(mq.head + 1, startIndex, limit)
|
||||
datas, ret := mq.findData(mq.head+1, startIndex, limit)
|
||||
if ret {
|
||||
dataQueue = append(dataQueue, datas...)
|
||||
}
|
||||
return dataQueue, ret
|
||||
} else {
|
||||
// 折叠先找后面的部分
|
||||
datas,ret := mq.findData(mq.head+1, startIndex, limit)
|
||||
datas, ret := mq.findData(mq.head+1, startIndex, limit)
|
||||
if ret {
|
||||
dataQueue = append(dataQueue, datas...)
|
||||
return dataQueue, ret
|
||||
}
|
||||
|
||||
// 后面没找到,从前面开始找
|
||||
datas,ret = mq.findData(0, startIndex, limit)
|
||||
datas, ret = mq.findData(0, startIndex, limit)
|
||||
dataQueue = append(dataQueue, datas...)
|
||||
return dataQueue, ret
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func (mp *MongoPersist) OnInit() error {
|
||||
keys = append(keys, "Customer", "Topic")
|
||||
IndexKey = append(IndexKey, keys)
|
||||
s := mp.mongo.TakeSession()
|
||||
if err := s.EnsureUniqueIndex(mp.dbName, CustomerCollectName, IndexKey, true, true,true); err != nil {
|
||||
if err := s.EnsureUniqueIndex(mp.dbName, CustomerCollectName, IndexKey, true, true, true); err != nil {
|
||||
log.SError("EnsureUniqueIndex is fail ", err.Error())
|
||||
return err
|
||||
}
|
||||
@@ -162,7 +162,7 @@ func (mp *MongoPersist) persistTopicData(collectionName string, topicData []Topi
|
||||
|
||||
_, err := s.Collection(mp.dbName, collectionName).InsertMany(ctx, documents)
|
||||
if err != nil {
|
||||
log.SError("PersistTopicData InsertMany fail,collect name is ", collectionName," error:",err.Error())
|
||||
log.SError("PersistTopicData InsertMany fail,collect name is ", collectionName, " error:", err.Error())
|
||||
|
||||
//失败最大重试数量
|
||||
return retryCount >= mp.retryCount
|
||||
@@ -171,16 +171,16 @@ func (mp *MongoPersist) persistTopicData(collectionName string, topicData []Topi
|
||||
return true
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) IsSameDay(timestamp1 int64,timestamp2 int64) bool{
|
||||
func (mp *MongoPersist) IsSameDay(timestamp1 int64, timestamp2 int64) bool {
|
||||
t1 := time.Unix(timestamp1, 0)
|
||||
t2 := time.Unix(timestamp2, 0)
|
||||
return t1.Year() == t2.Year() && t1.Month() == t2.Month()&&t1.Day() == t2.Day()
|
||||
return t1.Year() == t2.Year() && t1.Month() == t2.Month() && t1.Day() == t2.Day()
|
||||
}
|
||||
|
||||
// PersistTopicData 持久化数据
|
||||
func (mp *MongoPersist) PersistTopicData(topic string, topicData []TopicData, retryCount int) ([]TopicData, []TopicData, bool) {
|
||||
if len(topicData) == 0 {
|
||||
return nil, nil,true
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
preDate := topicData[0].Seq >> 32
|
||||
@@ -188,7 +188,7 @@ func (mp *MongoPersist) PersistTopicData(topic string, topicData []TopicData, re
|
||||
for findPos = 1; findPos < len(topicData); findPos++ {
|
||||
newDate := topicData[findPos].Seq >> 32
|
||||
//说明换天了
|
||||
if mp.IsSameDay(int64(preDate),int64(newDate)) == false {
|
||||
if mp.IsSameDay(int64(preDate), int64(newDate)) == false {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -201,14 +201,13 @@ func (mp *MongoPersist) PersistTopicData(topic string, topicData []TopicData, re
|
||||
}
|
||||
|
||||
//如果成功
|
||||
return topicData[findPos:len(topicData)], topicData[0:findPos], true
|
||||
return topicData[findPos:], topicData[0:findPos], true
|
||||
}
|
||||
|
||||
// FindTopicData 查找数据
|
||||
func (mp *MongoPersist) findTopicData(topic string, startIndex uint64, limit int64,topicBuff []TopicData) ([]TopicData, bool) {
|
||||
func (mp *MongoPersist) findTopicData(topic string, startIndex uint64, limit int64, topicBuff []TopicData) ([]TopicData, bool) {
|
||||
s := mp.mongo.TakeSession()
|
||||
|
||||
|
||||
condition := bson.D{{Key: "_id", Value: bson.D{{Key: "$gt", Value: startIndex}}}}
|
||||
|
||||
var findOption options.FindOptions
|
||||
@@ -238,11 +237,7 @@ func (mp *MongoPersist) findTopicData(topic string, startIndex uint64, limit int
|
||||
defer cancelAll()
|
||||
err = cursor.All(ctxAll, &res)
|
||||
if err != nil {
|
||||
if err != nil {
|
||||
log.SError("find collect name ", topic, " is error:", err.Error())
|
||||
return nil, false
|
||||
}
|
||||
|
||||
log.Error("find collect name ", topic, " is error", log.ErrorAttr("err", err))
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -251,7 +246,7 @@ func (mp *MongoPersist) findTopicData(topic string, startIndex uint64, limit int
|
||||
rawData, errM := bson.Marshal(res[i])
|
||||
if errM != nil {
|
||||
if errM != nil {
|
||||
log.SError("collect name ", topic, " Marshal is error:", err.Error())
|
||||
log.Error("collect name ", topic, " Marshal is error", log.ErrorAttr("err", err))
|
||||
return nil, false
|
||||
}
|
||||
continue
|
||||
@@ -262,26 +257,26 @@ func (mp *MongoPersist) findTopicData(topic string, startIndex uint64, limit int
|
||||
return topicBuff, true
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) IsYesterday(startIndex uint64) (bool,string){
|
||||
timeStamp := int64(startIndex>>32)
|
||||
func (mp *MongoPersist) IsYesterday(startIndex uint64) (bool, string) {
|
||||
timeStamp := int64(startIndex >> 32)
|
||||
|
||||
startTime := time.Unix(timeStamp, 0).AddDate(0,0,1)
|
||||
startTime := time.Unix(timeStamp, 0).AddDate(0, 0, 1)
|
||||
nowTm := time.Now()
|
||||
|
||||
return startTime.Year() == nowTm.Year() && startTime.Month() == nowTm.Month()&&startTime.Day() == nowTm.Day(),nowTm.Format("20060102")
|
||||
return startTime.Year() == nowTm.Year() && startTime.Month() == nowTm.Month() && startTime.Day() == nowTm.Day(), nowTm.Format("20060102")
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) getCollectCount(topic string,today string) (int64 ,error){
|
||||
func (mp *MongoPersist) getCollectCount(topic string, today string) (int64, error) {
|
||||
s := mp.mongo.TakeSession()
|
||||
ctx, cancel := s.GetDefaultContext()
|
||||
defer cancel()
|
||||
collectName := fmt.Sprintf("%s_%s", topic, today)
|
||||
count, err := s.Collection(mp.dbName, collectName).EstimatedDocumentCount(ctx)
|
||||
return count,err
|
||||
return count, err
|
||||
}
|
||||
|
||||
// FindTopicData 查找数据
|
||||
func (mp *MongoPersist) FindTopicData(topic string, startIndex uint64, limit int64,topicBuff []TopicData) []TopicData {
|
||||
func (mp *MongoPersist) FindTopicData(topic string, startIndex uint64, limit int64, topicBuff []TopicData) []TopicData {
|
||||
//某表找不到,一直往前找,找到当前置为止
|
||||
for days := 1; days <= MaxDays; days++ {
|
||||
//是否可以跳天
|
||||
@@ -290,12 +285,12 @@ func (mp *MongoPersist) FindTopicData(topic string, startIndex uint64, limit int
|
||||
IsJumpDays := true
|
||||
|
||||
//如果是昨天,先判断当天有没有表数据
|
||||
bYesterday,strToday := mp.IsYesterday(startIndex)
|
||||
if bYesterday {
|
||||
count,err := mp.getCollectCount(topic,strToday)
|
||||
bYesterday, strToday := mp.IsYesterday(startIndex)
|
||||
if bYesterday {
|
||||
count, err := mp.getCollectCount(topic, strToday)
|
||||
if err != nil {
|
||||
//失败时,重新开始
|
||||
log.SError("getCollectCount ",topic,"_",strToday," is fail:",err.Error())
|
||||
log.SError("getCollectCount ", topic, "_", strToday, " is fail:", err.Error())
|
||||
return nil
|
||||
}
|
||||
//当天没有记录,则不能跳表,有可能当天还有数据
|
||||
@@ -305,9 +300,9 @@ func (mp *MongoPersist) FindTopicData(topic string, startIndex uint64, limit int
|
||||
}
|
||||
|
||||
//从startIndex开始一直往后查
|
||||
topicData, isSucc := mp.findTopicData(topic, startIndex, limit,topicBuff)
|
||||
topicData, ok := mp.findTopicData(topic, startIndex, limit, topicBuff)
|
||||
//有数据或者数据库出错时返回,返回后,会进行下一轮的查询遍历
|
||||
if len(topicData) > 0 || isSucc == false {
|
||||
if len(topicData) > 0 || ok == false {
|
||||
return topicData
|
||||
}
|
||||
|
||||
@@ -411,14 +406,14 @@ func (mp *MongoPersist) PersistIndex(topic string, customerId string, index uint
|
||||
|
||||
condition := bson.D{{Key: "Customer", Value: customerId}, {Key: "Topic", Value: topic}}
|
||||
upsert := bson.M{"Customer": customerId, "Topic": topic, "Index": index}
|
||||
updata := bson.M{"$set": upsert}
|
||||
update := bson.M{"$set": upsert}
|
||||
|
||||
var UpdateOptionsOpts []*options.UpdateOptions
|
||||
UpdateOptionsOpts = append(UpdateOptionsOpts, options.Update().SetUpsert(true))
|
||||
|
||||
ctx, cancel := s.GetDefaultContext()
|
||||
defer cancel()
|
||||
_, err := s.Collection(mp.dbName, CustomerCollectName).UpdateOne(ctx, condition, updata, UpdateOptionsOpts...)
|
||||
_, err := s.Collection(mp.dbName, CustomerCollectName).UpdateOne(ctx, condition, update, UpdateOptionsOpts...)
|
||||
if err != nil {
|
||||
log.SError("PersistIndex fail :", err.Error())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// 订阅器
|
||||
// Subscriber 订阅器
|
||||
type Subscriber struct {
|
||||
customerLocker sync.RWMutex
|
||||
mapCustomer map[string]*CustomerSubscriber
|
||||
|
||||
@@ -43,7 +43,7 @@ type TopicRoom struct {
|
||||
isStop int32
|
||||
}
|
||||
|
||||
// maxProcessTopicBacklogNum:主题最大积压数量
|
||||
// Init maxProcessTopicBacklogNum:主题最大积压数量
|
||||
func (tr *TopicRoom) Init(maxTopicBacklogNum int32, memoryQueueLen int32, topic string, queueWait *sync.WaitGroup, dataPersist QueueDataPersist) {
|
||||
if maxTopicBacklogNum == 0 {
|
||||
maxTopicBacklogNum = DefaultMaxTopicBacklogNum
|
||||
@@ -116,18 +116,18 @@ func (tr *TopicRoom) topicRoomRun() {
|
||||
for retryCount := 0; retryCount < maxTryPersistNum; {
|
||||
//持久化处理
|
||||
stagingBuff, savedBuff, ret := tr.PersistTopicData(tr.topic, stagingBuff, retryCount+1)
|
||||
|
||||
|
||||
if ret == true {
|
||||
// 1. 把成功存储的数据放入内存中
|
||||
if len(savedBuff) > 0 {
|
||||
tr.PushTopicDataToQueue(tr.topic, savedBuff)
|
||||
}
|
||||
|
||||
|
||||
// 2. 如果存档成功,并且有后续批次,则继续存档
|
||||
if ret == true && len(stagingBuff) > 0 {
|
||||
if len(stagingBuff) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
// 3. 成功了,跳出
|
||||
break
|
||||
} else {
|
||||
|
||||
@@ -14,37 +14,37 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const batchRemoveNum = 128 //一切删除的最大数量
|
||||
const batchRemoveNum = 128 //一切删除的最大数量
|
||||
|
||||
// RankDataDB 排行表数据
|
||||
type RankDataDB struct {
|
||||
Id uint64 `bson:"_id"`
|
||||
RefreshTime int64 `bson:"RefreshTime"`
|
||||
SortData []int64 `bson:"SortData"`
|
||||
Data []byte `bson:"Data"`
|
||||
ExData []int64 `bson:"ExData"`
|
||||
Id uint64 `bson:"_id"`
|
||||
RefreshTime int64 `bson:"RefreshTime"`
|
||||
SortData []int64 `bson:"SortData"`
|
||||
Data []byte `bson:"Data"`
|
||||
ExData []int64 `bson:"ExData"`
|
||||
}
|
||||
|
||||
// MongoPersist持久化Module
|
||||
// MongoPersist 持久化Module
|
||||
type MongoPersist struct {
|
||||
service.Module
|
||||
mongo mongodbmodule.MongoModule
|
||||
|
||||
url string //Mongodb连接url
|
||||
dbName string //数据库名称
|
||||
SaveInterval time.Duration //落地数据库时间间隔
|
||||
url string //Mongodb连接url
|
||||
dbName string //数据库名称
|
||||
SaveInterval time.Duration //落地数据库时间间隔
|
||||
|
||||
sync.Mutex
|
||||
mapRemoveRankData map[uint64]map[uint64]struct{} //将要删除的排行数据 map[RankId]map[Key]struct{}
|
||||
mapUpsertRankData map[uint64]map[uint64]RankData //需要upsert的排行数据 map[RankId][key]RankData
|
||||
|
||||
mapRankSkip map[uint64]IRankSkip //所有的排行榜对象map[RankId]IRankSkip
|
||||
maxRetrySaveCount int //存档重试次数
|
||||
retryTimeIntervalMs time.Duration //重试时间间隔
|
||||
mapRankSkip map[uint64]IRankSkip //所有的排行榜对象map[RankId]IRankSkip
|
||||
maxRetrySaveCount int //存档重试次数
|
||||
retryTimeIntervalMs time.Duration //重试时间间隔
|
||||
|
||||
lastSaveTime time.Time //最后一次存档时间
|
||||
lastSaveTime time.Time //最后一次存档时间
|
||||
|
||||
stop int32 //是否停服
|
||||
stop int32 //是否停服
|
||||
waitGroup sync.WaitGroup //等待停服
|
||||
}
|
||||
|
||||
@@ -84,12 +84,12 @@ func (mp *MongoPersist) ReadCfg() error {
|
||||
}
|
||||
|
||||
//读取数据库配置
|
||||
saveMongoCfg,ok := mapDBServiceCfg["SaveMongo"]
|
||||
saveMongoCfg, ok := mapDBServiceCfg["SaveMongo"]
|
||||
if ok == false {
|
||||
return fmt.Errorf("RankService.SaveMongo config is error")
|
||||
}
|
||||
|
||||
mongodbCfg,ok := saveMongoCfg.(map[string]interface{})
|
||||
mongodbCfg, ok := saveMongoCfg.(map[string]interface{})
|
||||
if ok == false {
|
||||
return fmt.Errorf("RankService.SaveMongo config is error")
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func (mp *MongoPersist) ReadCfg() error {
|
||||
return fmt.Errorf("RankService.SaveMongo.SaveIntervalMs config is error")
|
||||
}
|
||||
|
||||
mp.SaveInterval = time.Duration(saveInterval.(float64))*time.Millisecond
|
||||
mp.SaveInterval = time.Duration(saveInterval.(float64)) * time.Millisecond
|
||||
|
||||
maxRetrySaveCount, ok := mongodbCfg["MaxRetrySaveCount"]
|
||||
if ok == false {
|
||||
@@ -123,16 +123,16 @@ func (mp *MongoPersist) ReadCfg() error {
|
||||
if ok == false {
|
||||
return fmt.Errorf("RankService.SaveMongo.RetryTimeIntervalMs config is error")
|
||||
}
|
||||
mp.retryTimeIntervalMs = time.Duration(retryTimeIntervalMs.(float64))*time.Millisecond
|
||||
mp.retryTimeIntervalMs = time.Duration(retryTimeIntervalMs.(float64)) * time.Millisecond
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//启服从数据库加载
|
||||
// OnStart 启服从数据库加载
|
||||
func (mp *MongoPersist) OnStart() {
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) OnSetupRank(manual bool,rankSkip *RankSkip) error{
|
||||
func (mp *MongoPersist) OnSetupRank(manual bool, rankSkip *RankSkip) error {
|
||||
if mp.mapRankSkip == nil {
|
||||
mp.mapRankSkip = map[uint64]IRankSkip{}
|
||||
}
|
||||
@@ -142,17 +142,17 @@ func (mp *MongoPersist) OnSetupRank(manual bool,rankSkip *RankSkip) error{
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("start load rank ",rankSkip.GetRankName()," from mongodb.")
|
||||
err := mp.loadFromDB(rankSkip.GetRankID(),rankSkip.GetRankName())
|
||||
if err != nil {
|
||||
log.SError("load from db is fail :%s",err.Error())
|
||||
log.Info("start load rank ", rankSkip.GetRankName(), " from mongodb.")
|
||||
err := mp.loadFromDB(rankSkip.GetRankID(), rankSkip.GetRankName())
|
||||
if err != nil {
|
||||
log.SError("load from db is fail :%s", err.Error())
|
||||
return err
|
||||
}
|
||||
log.Info("finish load rank ",rankSkip.GetRankName()," from mongodb.")
|
||||
log.Info("finish load rank ", rankSkip.GetRankName(), " from mongodb.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) loadFromDB(rankId uint64,rankCollectName string) error{
|
||||
func (mp *MongoPersist) loadFromDB(rankId uint64, rankCollectName string) error {
|
||||
s := mp.mongo.TakeSession()
|
||||
ctx, cancel := s.GetDefaultContext()
|
||||
defer cancel()
|
||||
@@ -164,14 +164,14 @@ func (mp *MongoPersist) loadFromDB(rankId uint64,rankCollectName string) error{
|
||||
return err
|
||||
}
|
||||
|
||||
if cursor.Err()!=nil {
|
||||
if cursor.Err() != nil {
|
||||
log.SError("find collect name ", rankCollectName, " is error:", cursor.Err().Error())
|
||||
return err
|
||||
}
|
||||
|
||||
rankSkip := mp.mapRankSkip[rankId]
|
||||
if rankSkip == nil {
|
||||
err = fmt.Errorf("rank ", rankCollectName, " is not setup:")
|
||||
err = fmt.Errorf("rank %s is not setup", rankCollectName)
|
||||
log.SError(err.Error())
|
||||
return err
|
||||
}
|
||||
@@ -189,69 +189,68 @@ func (mp *MongoPersist) loadFromDB(rankId uint64,rankCollectName string) error{
|
||||
rankData.Data = rankDataDB.Data
|
||||
rankData.Key = rankDataDB.Id
|
||||
rankData.SortData = rankDataDB.SortData
|
||||
for _,eData := range rankDataDB.ExData{
|
||||
rankData.ExData = append(rankData.ExData,&rpc.ExtendIncData{InitValue:eData})
|
||||
for _, eData := range rankDataDB.ExData {
|
||||
rankData.ExData = append(rankData.ExData, &rpc.ExtendIncData{InitValue: eData})
|
||||
}
|
||||
|
||||
//更新到排行榜
|
||||
rankSkip.UpsetRank(&rankData,rankDataDB.RefreshTime,true)
|
||||
rankSkip.UpsetRank(&rankData, rankDataDB.RefreshTime, true)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) lazyInitRemoveMap(rankId uint64){
|
||||
func (mp *MongoPersist) lazyInitRemoveMap(rankId uint64) {
|
||||
if mp.mapRemoveRankData[rankId] == nil {
|
||||
mp.mapRemoveRankData[rankId] = make(map[uint64]struct{},256)
|
||||
mp.mapRemoveRankData[rankId] = make(map[uint64]struct{}, 256)
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) lazyInitUpsertMap(rankId uint64){
|
||||
func (mp *MongoPersist) lazyInitUpsertMap(rankId uint64) {
|
||||
if mp.mapUpsertRankData[rankId] == nil {
|
||||
mp.mapUpsertRankData[rankId] = make(map[uint64]RankData,256)
|
||||
mp.mapUpsertRankData[rankId] = make(map[uint64]RankData, 256)
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) OnEnterRank(rankSkip IRankSkip, enterData *RankData){
|
||||
func (mp *MongoPersist) OnEnterRank(rankSkip IRankSkip, enterData *RankData) {
|
||||
mp.Lock()
|
||||
defer mp.Unlock()
|
||||
|
||||
delete(mp.mapRemoveRankData,enterData.Key)
|
||||
delete(mp.mapRemoveRankData, enterData.Key)
|
||||
|
||||
mp.lazyInitUpsertMap(rankSkip.GetRankID())
|
||||
mp.mapUpsertRankData[rankSkip.GetRankID()][enterData.Key] = *enterData
|
||||
}
|
||||
|
||||
|
||||
func (mp *MongoPersist) OnLeaveRank(rankSkip IRankSkip, leaveData *RankData){
|
||||
func (mp *MongoPersist) OnLeaveRank(rankSkip IRankSkip, leaveData *RankData) {
|
||||
mp.Lock()
|
||||
defer mp.Unlock()
|
||||
|
||||
//先删掉更新中的数据
|
||||
delete(mp.mapUpsertRankData,leaveData.Key)
|
||||
delete(mp.mapUpsertRankData, leaveData.Key)
|
||||
mp.lazyInitRemoveMap(rankSkip.GetRankID())
|
||||
mp.mapRemoveRankData[rankSkip.GetRankID()][leaveData.Key] = struct{}{}
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) OnChangeRankData(rankSkip IRankSkip, changeData *RankData){
|
||||
func (mp *MongoPersist) OnChangeRankData(rankSkip IRankSkip, changeData *RankData) {
|
||||
mp.Lock()
|
||||
defer mp.Unlock()
|
||||
|
||||
//先删掉要删除的数据
|
||||
delete(mp.mapRemoveRankData,changeData.Key)
|
||||
delete(mp.mapRemoveRankData, changeData.Key)
|
||||
|
||||
//更新数据
|
||||
mp.lazyInitUpsertMap(rankSkip.GetRankID())
|
||||
mp.mapUpsertRankData[rankSkip.GetRankID()][changeData.Key] = *changeData
|
||||
}
|
||||
|
||||
//停存持久化到DB
|
||||
func (mp *MongoPersist) OnStop(mapRankSkip map[uint64]*RankSkip){
|
||||
atomic.StoreInt32(&mp.stop,1)
|
||||
// OnStop 停存持久化到DB
|
||||
func (mp *MongoPersist) OnStop(mapRankSkip map[uint64]*RankSkip) {
|
||||
atomic.StoreInt32(&mp.stop, 1)
|
||||
mp.waitGroup.Wait()
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) JugeTimeoutSave() bool{
|
||||
func (mp *MongoPersist) JudgeTimeoutSave() bool {
|
||||
timeout := time.Now()
|
||||
isTimeOut := timeout.Sub(mp.lastSaveTime) >= mp.SaveInterval
|
||||
if isTimeOut == true {
|
||||
@@ -261,18 +260,18 @@ func (mp *MongoPersist) JugeTimeoutSave() bool{
|
||||
return isTimeOut
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) persistCoroutine(){
|
||||
func (mp *MongoPersist) persistCoroutine() {
|
||||
defer mp.waitGroup.Done()
|
||||
for atomic.LoadInt32(&mp.stop)==0 {
|
||||
for atomic.LoadInt32(&mp.stop) == 0 {
|
||||
//间隔时间sleep
|
||||
time.Sleep(time.Second*1)
|
||||
time.Sleep(time.Second * 1)
|
||||
|
||||
//没有持久化数据continue
|
||||
if mp.hasPersistData() == false {
|
||||
continue
|
||||
}
|
||||
|
||||
if mp.JugeTimeoutSave() == false{
|
||||
if mp.JudgeTimeoutSave() == false {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -284,20 +283,20 @@ func (mp *MongoPersist) persistCoroutine(){
|
||||
mp.saveToDB()
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) hasPersistData() bool{
|
||||
func (mp *MongoPersist) hasPersistData() bool {
|
||||
mp.Lock()
|
||||
defer mp.Unlock()
|
||||
|
||||
return len(mp.mapUpsertRankData)>0 || len(mp.mapRemoveRankData) >0
|
||||
return len(mp.mapUpsertRankData) > 0 || len(mp.mapRemoveRankData) > 0
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) saveToDB(){
|
||||
func (mp *MongoPersist) saveToDB() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
errString := fmt.Sprint(r)
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
log.Dump(string(buf[:l]), log.String("error", errString))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -314,13 +313,13 @@ func (mp *MongoPersist) saveToDB(){
|
||||
mp.upsertRankDataToDB(mapUpsertRankData)
|
||||
}
|
||||
|
||||
for len(mapRemoveRankData) >0 {
|
||||
for len(mapRemoveRankData) > 0 {
|
||||
mp.removeRankDataToDB(mapRemoveRankData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) removeToDB(collectName string,keys []uint64) error{
|
||||
func (mp *MongoPersist) removeToDB(collectName string, keys []uint64) error {
|
||||
s := mp.mongo.TakeSession()
|
||||
ctx, cancel := s.GetDefaultContext()
|
||||
defer cancel()
|
||||
@@ -336,16 +335,16 @@ func (mp *MongoPersist) removeToDB(collectName string,keys []uint64) error{
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) removeRankData(rankId uint64,keys []uint64) bool {
|
||||
func (mp *MongoPersist) removeRankData(rankId uint64, keys []uint64) bool {
|
||||
rank := mp.mapRankSkip[rankId]
|
||||
if rank== nil {
|
||||
log.SError("cannot find rankId ",rankId,"config")
|
||||
if rank == nil {
|
||||
log.SError("cannot find rankId ", rankId, "config")
|
||||
return false
|
||||
}
|
||||
|
||||
//不成功则重试maxRetrySaveCount次
|
||||
for i:=0;i<mp.maxRetrySaveCount;i++{
|
||||
if mp.removeToDB(rank.GetRankName(),keys)!= nil {
|
||||
for i := 0; i < mp.maxRetrySaveCount; i++ {
|
||||
if mp.removeToDB(rank.GetRankName(), keys) != nil {
|
||||
time.Sleep(mp.retryTimeIntervalMs)
|
||||
continue
|
||||
}
|
||||
@@ -355,9 +354,9 @@ func (mp *MongoPersist) removeRankData(rankId uint64,keys []uint64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) upsertToDB(collectName string,rankData *RankData) error{
|
||||
func (mp *MongoPersist) upsertToDB(collectName string, rankData *RankData) error {
|
||||
condition := bson.D{{"_id", rankData.Key}}
|
||||
upsert := bson.M{"_id":rankData.Key,"RefreshTime": rankData.RefreshTimestamp, "SortData": rankData.SortData, "Data": rankData.Data,"ExData":rankData.ExData}
|
||||
upsert := bson.M{"_id": rankData.Key, "RefreshTime": rankData.RefreshTimestamp, "SortData": rankData.SortData, "Data": rankData.Data, "ExData": rankData.ExData}
|
||||
update := bson.M{"$set": upsert}
|
||||
|
||||
s := mp.mongo.TakeSession()
|
||||
@@ -365,7 +364,7 @@ func (mp *MongoPersist) upsertToDB(collectName string,rankData *RankData) error{
|
||||
defer cancel()
|
||||
|
||||
updateOpts := options.Update().SetUpsert(true)
|
||||
_, err := s.Collection(mp.dbName, collectName).UpdateOne(ctx, condition,update,updateOpts)
|
||||
_, err := s.Collection(mp.dbName, collectName).UpdateOne(ctx, condition, update, updateOpts)
|
||||
if err != nil {
|
||||
log.SError("MongoPersist upsertDB fail,collect name is ", collectName)
|
||||
return err
|
||||
@@ -374,19 +373,19 @@ func (mp *MongoPersist) upsertToDB(collectName string,rankData *RankData) error{
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) upsertRankDataToDB(mapUpsertRankData map[uint64]map[uint64]RankData) error{
|
||||
for rankId,mapRankData := range mapUpsertRankData{
|
||||
rank,ok := mp.mapRankSkip[rankId]
|
||||
func (mp *MongoPersist) upsertRankDataToDB(mapUpsertRankData map[uint64]map[uint64]RankData) error {
|
||||
for rankId, mapRankData := range mapUpsertRankData {
|
||||
rank, ok := mp.mapRankSkip[rankId]
|
||||
if ok == false {
|
||||
log.SError("cannot find rankId ",rankId,",config is error")
|
||||
delete(mapUpsertRankData,rankId)
|
||||
log.SError("cannot find rankId ", rankId, ",config is error")
|
||||
delete(mapUpsertRankData, rankId)
|
||||
continue
|
||||
}
|
||||
|
||||
for key,rankData := range mapRankData{
|
||||
for key, rankData := range mapRankData {
|
||||
//最大重试mp.maxRetrySaveCount次
|
||||
for i:=0;i<mp.maxRetrySaveCount;i++{
|
||||
err := mp.upsertToDB(rank.GetRankName(),&rankData)
|
||||
for i := 0; i < mp.maxRetrySaveCount; i++ {
|
||||
err := mp.upsertToDB(rank.GetRankName(), &rankData)
|
||||
if err != nil {
|
||||
time.Sleep(mp.retryTimeIntervalMs)
|
||||
continue
|
||||
@@ -395,11 +394,11 @@ func (mp *MongoPersist) upsertRankDataToDB(mapUpsertRankData map[uint64]map[uint
|
||||
}
|
||||
|
||||
//存完删掉指定key
|
||||
delete(mapRankData,key)
|
||||
delete(mapRankData, key)
|
||||
}
|
||||
|
||||
if len(mapRankData) == 0 {
|
||||
delete(mapUpsertRankData,rankId)
|
||||
delete(mapUpsertRankData, rankId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,23 +406,22 @@ func (mp *MongoPersist) upsertRankDataToDB(mapUpsertRankData map[uint64]map[uint
|
||||
}
|
||||
|
||||
func (mp *MongoPersist) removeRankDataToDB(mapRemoveRankData map[uint64]map[uint64]struct{}) {
|
||||
for rankId ,mapRemoveKey := range mapRemoveRankData{
|
||||
for rankId, mapRemoveKey := range mapRemoveRankData {
|
||||
//每100个一删
|
||||
keyList := make([]uint64,0,batchRemoveNum)
|
||||
for key := range mapRemoveKey {
|
||||
delete(mapRemoveKey,key)
|
||||
keyList = append(keyList,key)
|
||||
if len(keyList) >= batchRemoveNum {
|
||||
break
|
||||
}
|
||||
}
|
||||
keyList := make([]uint64, 0, batchRemoveNum)
|
||||
for key := range mapRemoveKey {
|
||||
delete(mapRemoveKey, key)
|
||||
keyList = append(keyList, key)
|
||||
if len(keyList) >= batchRemoveNum {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
mp.removeRankData(rankId,keyList)
|
||||
mp.removeRankData(rankId, keyList)
|
||||
|
||||
//如果删完,删掉rankid下所有
|
||||
if len(mapRemoveKey) == 0 {
|
||||
delete(mapRemoveRankData,rankId)
|
||||
}
|
||||
if len(mapRemoveKey) == 0 {
|
||||
delete(mapRemoveRankData, rankId)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package rankservice
|
||||
|
||||
import (
|
||||
"github.com/duanhf2012/origin/v2/service"
|
||||
"github.com/duanhf2012/origin/v2/rpc"
|
||||
"github.com/duanhf2012/origin/v2/service"
|
||||
)
|
||||
|
||||
type RankDataChangeType int8
|
||||
@@ -11,19 +11,18 @@ type IRankSkip interface {
|
||||
GetRankID() uint64
|
||||
GetRankName() string
|
||||
GetRankLen() uint64
|
||||
UpsetRank(upsetData *rpc.RankData,refreshTimestamp int64,fromLoad bool) RankDataChangeType
|
||||
UpsetRank(upsetData *rpc.RankData, refreshTimestamp int64, fromLoad bool) RankDataChangeType
|
||||
}
|
||||
|
||||
type IRankModule interface {
|
||||
service.IModule
|
||||
|
||||
|
||||
OnSetupRank(manual bool,rankSkip *RankSkip) error //当完成安装排行榜对象时
|
||||
OnStart() //服务开启时回调
|
||||
OnSetupRank(manual bool, rankSkip *RankSkip) error //当完成安装排行榜对象时
|
||||
OnStart() //服务开启时回调
|
||||
OnEnterRank(rankSkip IRankSkip, enterData *RankData) //进入排行
|
||||
OnLeaveRank(rankSkip IRankSkip, leaveData *RankData) //离开排行
|
||||
OnChangeRankData(rankSkip IRankSkip, changeData *RankData) //当排行数据变化时
|
||||
OnStop(mapRankSkip map[uint64]*RankSkip) //服务结束时回调
|
||||
OnStop(mapRankSkip map[uint64]*RankSkip) //服务结束时回调
|
||||
}
|
||||
|
||||
type DefaultRankModule struct {
|
||||
|
||||
@@ -45,7 +45,7 @@ func (rs *RankService) OnRelease() {
|
||||
rs.rankModule.OnStop(rs.mapRankSkip)
|
||||
}
|
||||
|
||||
// 安装排行模块
|
||||
// SetupRankModule 安装排行模块
|
||||
func (rs *RankService) SetupRankModule(rankModule IRankModule) {
|
||||
rs.rankModule = rankModule
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ func (rs *RankSkip) GetRankNodeData(findKey uint64) (*RankData, uint64) {
|
||||
return rankNode, index + 1
|
||||
}
|
||||
|
||||
// GetRankNodeDataByPos 获取,返回排名节点与名次
|
||||
// GetRankNodeDataByRank 获取,返回排名节点与名次
|
||||
func (rs *RankSkip) GetRankNodeDataByRank(rank uint64) (*RankData, uint64) {
|
||||
rs.pickExpireKey()
|
||||
rankNode := rs.skipList.ByPosition(rank - 1)
|
||||
@@ -382,7 +382,7 @@ func (rs *RankSkip) GetRankKeyPrevToLimit(findKey, count uint64, result *rpc.Ran
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRankKeyPrevToLimit 获取key前count名的数据
|
||||
// GetRankKeyNextToLimit 获取key前count名的数据
|
||||
func (rs *RankSkip) GetRankKeyNextToLimit(findKey, count uint64, result *rpc.RankDataList) error {
|
||||
if rs.GetRankLen() <= 0 {
|
||||
return fmt.Errorf("rank[%d] no data", rs.rankId)
|
||||
@@ -411,7 +411,7 @@ func (rs *RankSkip) GetRankKeyNextToLimit(findKey, count uint64, result *rpc.Ran
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRankList 获取排行榜数据,startPos开始的count个数据
|
||||
// GetRankDataFromToLimit 获取排行榜数据,startPos开始的count个数据
|
||||
func (rs *RankSkip) GetRankDataFromToLimit(startPos, count uint64, result *rpc.RankDataList) error {
|
||||
if rs.GetRankLen() <= 0 {
|
||||
//初始排行榜可能没有数据
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"github.com/duanhf2012/origin/v2/network/processor"
|
||||
"github.com/duanhf2012/origin/v2/service"
|
||||
"github.com/duanhf2012/origin/v2/util/bytespool"
|
||||
"runtime"
|
||||
"sync"
|
||||
"github.com/google/uuid"
|
||||
"time"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type TcpService struct {
|
||||
@@ -20,79 +20,80 @@ type TcpService struct {
|
||||
service.Service
|
||||
|
||||
mapClientLocker sync.RWMutex
|
||||
mapClient map[string] *Client
|
||||
process processor.IProcessor
|
||||
mapClient map[string]*Client
|
||||
process processor.IProcessor
|
||||
}
|
||||
|
||||
type TcpPackType int8
|
||||
const(
|
||||
TPT_Connected TcpPackType = 0
|
||||
|
||||
const (
|
||||
TPT_Connected TcpPackType = 0
|
||||
TPT_DisConnected TcpPackType = 1
|
||||
TPT_Pack TcpPackType = 2
|
||||
TPT_UnknownPack TcpPackType = 3
|
||||
TPT_Pack TcpPackType = 2
|
||||
TPT_UnknownPack TcpPackType = 3
|
||||
)
|
||||
|
||||
type TcpPack struct {
|
||||
Type TcpPackType //0表示连接 1表示断开 2表示数据
|
||||
ClientId string
|
||||
Data interface{}
|
||||
Type TcpPackType //0表示连接 1表示断开 2表示数据
|
||||
ClientId string
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
id string
|
||||
tcpConn *network.TCPConn
|
||||
id string
|
||||
tcpConn *network.TCPConn
|
||||
tcpService *TcpService
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) OnInit() error{
|
||||
func (tcpService *TcpService) OnInit() error {
|
||||
iConfig := tcpService.GetServiceCfg()
|
||||
if iConfig == nil {
|
||||
return fmt.Errorf("%s service config is error!", tcpService.GetName())
|
||||
return fmt.Errorf("%s service config is error", tcpService.GetName())
|
||||
}
|
||||
tcpCfg := iConfig.(map[string]interface{})
|
||||
addr,ok := tcpCfg["ListenAddr"]
|
||||
addr, ok := tcpCfg["ListenAddr"]
|
||||
if ok == false {
|
||||
return fmt.Errorf("%s service config is error!", tcpService.GetName())
|
||||
return fmt.Errorf("%s service config is error", tcpService.GetName())
|
||||
}
|
||||
|
||||
tcpService.tcpServer.Addr = addr.(string)
|
||||
MaxConnNum,ok := tcpCfg["MaxConnNum"]
|
||||
MaxConnNum, ok := tcpCfg["MaxConnNum"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.MaxConnNum = int(MaxConnNum.(float64))
|
||||
}
|
||||
|
||||
PendingWriteNum,ok := tcpCfg["PendingWriteNum"]
|
||||
|
||||
PendingWriteNum, ok := tcpCfg["PendingWriteNum"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.PendingWriteNum = int(PendingWriteNum.(float64))
|
||||
}
|
||||
LittleEndian,ok := tcpCfg["LittleEndian"]
|
||||
LittleEndian, ok := tcpCfg["LittleEndian"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.LittleEndian = LittleEndian.(bool)
|
||||
}
|
||||
LenMsgLen,ok := tcpCfg["LenMsgLen"]
|
||||
LenMsgLen, ok := tcpCfg["LenMsgLen"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.LenMsgLen = int(LenMsgLen.(float64))
|
||||
}
|
||||
MinMsgLen,ok := tcpCfg["MinMsgLen"]
|
||||
MinMsgLen, ok := tcpCfg["MinMsgLen"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.MinMsgLen = uint32(MinMsgLen.(float64))
|
||||
}
|
||||
MaxMsgLen,ok := tcpCfg["MaxMsgLen"]
|
||||
MaxMsgLen, ok := tcpCfg["MaxMsgLen"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.MaxMsgLen = uint32(MaxMsgLen.(float64))
|
||||
}
|
||||
|
||||
readDeadline,ok := tcpCfg["ReadDeadline"]
|
||||
readDeadline, ok := tcpCfg["ReadDeadline"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.ReadDeadline = time.Second*time.Duration(readDeadline.(float64))
|
||||
tcpService.tcpServer.ReadDeadline = time.Second * time.Duration(readDeadline.(float64))
|
||||
}
|
||||
|
||||
writeDeadline,ok := tcpCfg["WriteDeadline"]
|
||||
writeDeadline, ok := tcpCfg["WriteDeadline"]
|
||||
if ok == true {
|
||||
tcpService.tcpServer.WriteDeadline = time.Second*time.Duration(writeDeadline.(float64))
|
||||
tcpService.tcpServer.WriteDeadline = time.Second * time.Duration(writeDeadline.(float64))
|
||||
}
|
||||
|
||||
tcpService.mapClient = make( map[string] *Client, tcpService.tcpServer.MaxConnNum)
|
||||
tcpService.mapClient = make(map[string]*Client, tcpService.tcpServer.MaxConnNum)
|
||||
tcpService.tcpServer.NewAgent = tcpService.NewClient
|
||||
tcpService.tcpServer.Start()
|
||||
|
||||
@@ -107,26 +108,25 @@ func (tcpService *TcpService) TcpEventHandler(ev event.IEvent) {
|
||||
case TPT_DisConnected:
|
||||
tcpService.process.DisConnectedRoute(pack.ClientId)
|
||||
case TPT_UnknownPack:
|
||||
tcpService.process.UnknownMsgRoute(pack.ClientId,pack.Data,tcpService.recyclerReaderBytes)
|
||||
tcpService.process.UnknownMsgRoute(pack.ClientId, pack.Data, tcpService.recyclerReaderBytes)
|
||||
case TPT_Pack:
|
||||
tcpService.process.MsgRoute(pack.ClientId,pack.Data,tcpService.recyclerReaderBytes)
|
||||
tcpService.process.MsgRoute(pack.ClientId, pack.Data, tcpService.recyclerReaderBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) recyclerReaderBytes(data []byte) {
|
||||
}
|
||||
|
||||
|
||||
func (tcpService *TcpService) SetProcessor(process processor.IProcessor,handler event.IEventHandler){
|
||||
func (tcpService *TcpService) SetProcessor(process processor.IProcessor, handler event.IEventHandler) {
|
||||
tcpService.process = process
|
||||
tcpService.RegEventReceiverFunc(event.Sys_Event_Tcp,handler, tcpService.TcpEventHandler)
|
||||
tcpService.RegEventReceiverFunc(event.Sys_Event_Tcp, handler, tcpService.TcpEventHandler)
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) NewClient(conn *network.TCPConn) network.Agent {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
defer tcpService.mapClientLocker.Unlock()
|
||||
|
||||
uuId,_ := uuid.NewUUID()
|
||||
uuId, _ := uuid.NewUUID()
|
||||
clientId := strings.ReplaceAll(uuId.String(), "-", "")
|
||||
pClient := &Client{tcpConn: conn, id: clientId}
|
||||
pClient.tcpService = tcpService
|
||||
@@ -145,49 +145,49 @@ func (slf *Client) Run() {
|
||||
buf := make([]byte, 4096)
|
||||
l := runtime.Stack(buf, false)
|
||||
errString := fmt.Sprint(r)
|
||||
log.Dump(string(buf[:l]),log.String("error",errString))
|
||||
log.Dump(string(buf[:l]), log.String("error", errString))
|
||||
}
|
||||
}()
|
||||
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type:event.Sys_Event_Tcp,Data:TcpPack{ClientId:slf.id,Type:TPT_Connected}})
|
||||
for{
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type: event.Sys_Event_Tcp, Data: TcpPack{ClientId: slf.id, Type: TPT_Connected}})
|
||||
for {
|
||||
if slf.tcpConn == nil {
|
||||
break
|
||||
}
|
||||
|
||||
slf.tcpConn.SetReadDeadline(slf.tcpService.tcpServer.ReadDeadline)
|
||||
bytes,err := slf.tcpConn.ReadMsg()
|
||||
bytes, err := slf.tcpConn.ReadMsg()
|
||||
if err != nil {
|
||||
log.Debug("read client failed",log.ErrorAttr("error",err),log.String("clientId",slf.id))
|
||||
log.Debug("read client failed", log.ErrorAttr("error", err), log.String("clientId", slf.id))
|
||||
break
|
||||
}
|
||||
data,err:=slf.tcpService.process.Unmarshal(slf.id,bytes)
|
||||
data, err := slf.tcpService.process.Unmarshal(slf.id, bytes)
|
||||
|
||||
if err != nil {
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type:event.Sys_Event_Tcp,Data:TcpPack{ClientId:slf.id,Type:TPT_UnknownPack,Data:bytes}})
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type: event.Sys_Event_Tcp, Data: TcpPack{ClientId: slf.id, Type: TPT_UnknownPack, Data: bytes}})
|
||||
continue
|
||||
}
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type:event.Sys_Event_Tcp,Data:TcpPack{ClientId:slf.id,Type:TPT_Pack,Data:data}})
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type: event.Sys_Event_Tcp, Data: TcpPack{ClientId: slf.id, Type: TPT_Pack, Data: data}})
|
||||
}
|
||||
}
|
||||
|
||||
func (slf *Client) OnClose(){
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type:event.Sys_Event_Tcp,Data:TcpPack{ClientId:slf.id,Type:TPT_DisConnected}})
|
||||
func (slf *Client) OnClose() {
|
||||
slf.tcpService.NotifyEvent(&event.Event{Type: event.Sys_Event_Tcp, Data: TcpPack{ClientId: slf.id, Type: TPT_DisConnected}})
|
||||
slf.tcpService.mapClientLocker.Lock()
|
||||
defer slf.tcpService.mapClientLocker.Unlock()
|
||||
delete (slf.tcpService.mapClient,slf.GetId())
|
||||
delete(slf.tcpService.mapClient, slf.GetId())
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) SendMsg(clientId string,msg interface{}) error{
|
||||
func (tcpService *TcpService) SendMsg(clientId string, msg interface{}) error {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
client,ok := tcpService.mapClient[clientId]
|
||||
if ok == false{
|
||||
client, ok := tcpService.mapClient[clientId]
|
||||
if ok == false {
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
return fmt.Errorf("client %d is disconnect!",clientId)
|
||||
return fmt.Errorf("client %s is disconnect", clientId)
|
||||
}
|
||||
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
bytes,err := tcpService.process.Marshal(clientId,msg)
|
||||
bytes, err := tcpService.process.Marshal(clientId, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -198,53 +198,51 @@ func (tcpService *TcpService) Close(clientId string) {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
defer tcpService.mapClientLocker.Unlock()
|
||||
|
||||
client,ok := tcpService.mapClient[clientId]
|
||||
if ok == false{
|
||||
client, ok := tcpService.mapClient[clientId]
|
||||
if ok == false {
|
||||
return
|
||||
}
|
||||
|
||||
if client.tcpConn!=nil {
|
||||
if client.tcpConn != nil {
|
||||
client.tcpConn.Close()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) GetClientIp(clientid string) string{
|
||||
func (tcpService *TcpService) GetClientIp(clientId string) string {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
defer tcpService.mapClientLocker.Unlock()
|
||||
pClient,ok := tcpService.mapClient[clientid]
|
||||
if ok == false{
|
||||
pClient, ok := tcpService.mapClient[clientId]
|
||||
if ok == false {
|
||||
return ""
|
||||
}
|
||||
|
||||
return pClient.tcpConn.GetRemoteIp()
|
||||
}
|
||||
|
||||
|
||||
func (tcpService *TcpService) SendRawMsg(clientId string,msg []byte) error{
|
||||
func (tcpService *TcpService) SendRawMsg(clientId string, msg []byte) error {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
client,ok := tcpService.mapClient[clientId]
|
||||
if ok == false{
|
||||
client, ok := tcpService.mapClient[clientId]
|
||||
if ok == false {
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
return fmt.Errorf("client %d is disconnect!",clientId)
|
||||
return fmt.Errorf("client %s is disconnect", clientId)
|
||||
}
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
return client.tcpConn.WriteMsg(msg)
|
||||
}
|
||||
|
||||
func (tcpService *TcpService) SendRawData(clientId string,data []byte) error{
|
||||
func (tcpService *TcpService) SendRawData(clientId string, data []byte) error {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
client,ok := tcpService.mapClient[clientId]
|
||||
if ok == false{
|
||||
client, ok := tcpService.mapClient[clientId]
|
||||
if ok == false {
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
return fmt.Errorf("client %d is disconnect!",clientId)
|
||||
return fmt.Errorf("client %s is disconnect", clientId)
|
||||
}
|
||||
tcpService.mapClientLocker.Unlock()
|
||||
return client.tcpConn.WriteRawMsg(data)
|
||||
}
|
||||
|
||||
|
||||
func (tcpService *TcpService) GetConnNum() int {
|
||||
tcpService.mapClientLocker.Lock()
|
||||
connNum := len(tcpService.mapClient)
|
||||
@@ -252,14 +250,14 @@ func (tcpService *TcpService) GetConnNum() int {
|
||||
return connNum
|
||||
}
|
||||
|
||||
func (server *TcpService) SetNetMempool(mempool bytespool.IBytesMempool){
|
||||
server.tcpServer.SetNetMempool(mempool)
|
||||
func (tcpService *TcpService) SetNetMemPool(memPool bytespool.IBytesMemPool) {
|
||||
tcpService.tcpServer.SetNetMemPool(memPool)
|
||||
}
|
||||
|
||||
func (server *TcpService) GetNetMempool() bytespool.IBytesMempool {
|
||||
return server.tcpServer.GetNetMempool()
|
||||
func (tcpService *TcpService) GetNetMemPool() bytespool.IBytesMemPool {
|
||||
return tcpService.tcpServer.GetNetMemPool()
|
||||
}
|
||||
|
||||
func (server *TcpService) ReleaseNetMem(byteBuff []byte) {
|
||||
server.tcpServer.GetNetMempool().ReleaseBytes(byteBuff)
|
||||
func (tcpService *TcpService) ReleaseNetMem(byteBuff []byte) {
|
||||
tcpService.tcpServer.GetNetMemPool().ReleaseBytes(byteBuff)
|
||||
}
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"github.com/duanhf2012/origin/v2/network"
|
||||
"github.com/duanhf2012/origin/v2/network/processor"
|
||||
"github.com/duanhf2012/origin/v2/service"
|
||||
"sync"
|
||||
"github.com/google/uuid"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type WSService struct {
|
||||
@@ -17,16 +17,17 @@ type WSService struct {
|
||||
wsServer network.WSServer
|
||||
|
||||
mapClientLocker sync.RWMutex
|
||||
mapClient map[string] *WSClient
|
||||
mapClient map[string]*WSClient
|
||||
process processor.IProcessor
|
||||
}
|
||||
|
||||
type WSPackType int8
|
||||
const(
|
||||
WPT_Connected WSPackType = 0
|
||||
|
||||
const (
|
||||
WPT_Connected WSPackType = 0
|
||||
WPT_DisConnected WSPackType = 1
|
||||
WPT_Pack WSPackType = 2
|
||||
WPT_UnknownPack WSPackType = 3
|
||||
WPT_Pack WSPackType = 2
|
||||
WPT_UnknownPack WSPackType = 3
|
||||
)
|
||||
|
||||
const Default_WS_MaxConnNum = 3000
|
||||
@@ -34,8 +35,8 @@ const Default_WS_PendingWriteNum = 10000
|
||||
const Default_WS_MaxMsgLen = 65535
|
||||
|
||||
type WSClient struct {
|
||||
id string
|
||||
wsConn *network.WSConn
|
||||
id string
|
||||
wsConn *network.WSConn
|
||||
wsService *WSService
|
||||
}
|
||||
|
||||
@@ -46,44 +47,44 @@ type WSPack struct {
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
func (ws *WSService) OnInit() error{
|
||||
func (ws *WSService) OnInit() error {
|
||||
|
||||
iConfig := ws.GetServiceCfg()
|
||||
if iConfig == nil {
|
||||
return fmt.Errorf("%s service config is error!", ws.GetName())
|
||||
return fmt.Errorf("%s service config is error", ws.GetName())
|
||||
}
|
||||
wsCfg := iConfig.(map[string]interface{})
|
||||
addr,ok := wsCfg["ListenAddr"]
|
||||
addr, ok := wsCfg["ListenAddr"]
|
||||
if ok == false {
|
||||
return fmt.Errorf("%s service config is error!", ws.GetName())
|
||||
return fmt.Errorf("%s service config is error", ws.GetName())
|
||||
}
|
||||
|
||||
ws.wsServer.Addr = addr.(string)
|
||||
ws.wsServer.MaxConnNum = Default_WS_MaxConnNum
|
||||
ws.wsServer.PendingWriteNum = Default_WS_PendingWriteNum
|
||||
ws.wsServer.MaxMsgLen = Default_WS_MaxMsgLen
|
||||
MaxConnNum,ok := wsCfg["MaxConnNum"]
|
||||
MaxConnNum, ok := wsCfg["MaxConnNum"]
|
||||
if ok == true {
|
||||
ws.wsServer.MaxConnNum = int(MaxConnNum.(float64))
|
||||
}
|
||||
|
||||
PendingWriteNum,ok := wsCfg["PendingWriteNum"]
|
||||
PendingWriteNum, ok := wsCfg["PendingWriteNum"]
|
||||
if ok == true {
|
||||
ws.wsServer.PendingWriteNum = int(PendingWriteNum.(float64))
|
||||
}
|
||||
|
||||
MaxMsgLen,ok := wsCfg["MaxMsgLen"]
|
||||
MaxMsgLen, ok := wsCfg["MaxMsgLen"]
|
||||
if ok == true {
|
||||
ws.wsServer.MaxMsgLen = uint32(MaxMsgLen.(float64))
|
||||
}
|
||||
|
||||
ws.mapClient = make( map[string] *WSClient, ws.wsServer.MaxConnNum)
|
||||
ws.mapClient = make(map[string]*WSClient, ws.wsServer.MaxConnNum)
|
||||
ws.wsServer.NewAgent = ws.NewWSClient
|
||||
ws.wsServer.Start()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ws *WSService) SetMessageType(messageType int){
|
||||
func (ws *WSService) SetMessageType(messageType int) {
|
||||
ws.wsServer.SetMessageType(messageType)
|
||||
}
|
||||
|
||||
@@ -95,15 +96,15 @@ func (ws *WSService) WSEventHandler(ev event.IEvent) {
|
||||
case WPT_DisConnected:
|
||||
pack.MsgProcessor.DisConnectedRoute(pack.ClientId)
|
||||
case WPT_UnknownPack:
|
||||
pack.MsgProcessor.UnknownMsgRoute(pack.ClientId,pack.Data,ws.recyclerReaderBytes)
|
||||
pack.MsgProcessor.UnknownMsgRoute(pack.ClientId, pack.Data, ws.recyclerReaderBytes)
|
||||
case WPT_Pack:
|
||||
pack.MsgProcessor.MsgRoute(pack.ClientId,pack.Data,ws.recyclerReaderBytes)
|
||||
pack.MsgProcessor.MsgRoute(pack.ClientId, pack.Data, ws.recyclerReaderBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func (ws *WSService) SetProcessor(process processor.IProcessor,handler event.IEventHandler){
|
||||
func (ws *WSService) SetProcessor(process processor.IProcessor, handler event.IEventHandler) {
|
||||
ws.process = process
|
||||
ws.RegEventReceiverFunc(event.Sys_Event_WebSocket,handler, ws.WSEventHandler)
|
||||
ws.RegEventReceiverFunc(event.Sys_Event_WebSocket, handler, ws.WSEventHandler)
|
||||
}
|
||||
|
||||
func (ws *WSService) NewWSClient(conn *network.WSConn) network.Agent {
|
||||
@@ -125,55 +126,55 @@ func (slf *WSClient) GetId() string {
|
||||
}
|
||||
|
||||
func (slf *WSClient) Run() {
|
||||
slf.wsService.NotifyEvent(&event.Event{Type:event.Sys_Event_WebSocket,Data:&WSPack{ClientId:slf.id,Type:WPT_Connected,MsgProcessor:slf.wsService.process}})
|
||||
for{
|
||||
bytes,err := slf.wsConn.ReadMsg()
|
||||
slf.wsService.NotifyEvent(&event.Event{Type: event.Sys_Event_WebSocket, Data: &WSPack{ClientId: slf.id, Type: WPT_Connected, MsgProcessor: slf.wsService.process}})
|
||||
for {
|
||||
bytes, err := slf.wsConn.ReadMsg()
|
||||
if err != nil {
|
||||
log.Debug("read client id %s is error:%+v",slf.id,err)
|
||||
log.Debug("read client id %s is error:%+v", slf.id, err)
|
||||
break
|
||||
}
|
||||
data,err:=slf.wsService.process.Unmarshal(slf.id,bytes)
|
||||
data, err := slf.wsService.process.Unmarshal(slf.id, bytes)
|
||||
if err != nil {
|
||||
slf.wsService.NotifyEvent(&event.Event{Type:event.Sys_Event_WebSocket,Data:&WSPack{ClientId:slf.id,Type:WPT_UnknownPack,Data:bytes,MsgProcessor:slf.wsService.process}})
|
||||
slf.wsService.NotifyEvent(&event.Event{Type: event.Sys_Event_WebSocket, Data: &WSPack{ClientId: slf.id, Type: WPT_UnknownPack, Data: bytes, MsgProcessor: slf.wsService.process}})
|
||||
continue
|
||||
}
|
||||
slf.wsService.NotifyEvent(&event.Event{Type:event.Sys_Event_WebSocket,Data:&WSPack{ClientId:slf.id,Type:WPT_Pack,Data:data,MsgProcessor:slf.wsService.process}})
|
||||
slf.wsService.NotifyEvent(&event.Event{Type: event.Sys_Event_WebSocket, Data: &WSPack{ClientId: slf.id, Type: WPT_Pack, Data: data, MsgProcessor: slf.wsService.process}})
|
||||
}
|
||||
}
|
||||
|
||||
func (slf *WSClient) OnClose(){
|
||||
slf.wsService.NotifyEvent(&event.Event{Type:event.Sys_Event_WebSocket,Data:&WSPack{ClientId:slf.id,Type:WPT_DisConnected,MsgProcessor:slf.wsService.process}})
|
||||
func (slf *WSClient) OnClose() {
|
||||
slf.wsService.NotifyEvent(&event.Event{Type: event.Sys_Event_WebSocket, Data: &WSPack{ClientId: slf.id, Type: WPT_DisConnected, MsgProcessor: slf.wsService.process}})
|
||||
slf.wsService.mapClientLocker.Lock()
|
||||
defer slf.wsService.mapClientLocker.Unlock()
|
||||
delete (slf.wsService.mapClient,slf.GetId())
|
||||
delete(slf.wsService.mapClient, slf.GetId())
|
||||
}
|
||||
|
||||
func (ws *WSService) SendMsg(clientid string,msg interface{}) error{
|
||||
func (ws *WSService) SendMsg(clientId string, msg interface{}) error {
|
||||
ws.mapClientLocker.Lock()
|
||||
client,ok := ws.mapClient[clientid]
|
||||
if ok == false{
|
||||
client, ok := ws.mapClient[clientId]
|
||||
if ok == false {
|
||||
ws.mapClientLocker.Unlock()
|
||||
return fmt.Errorf("client %s is disconnect!",clientid)
|
||||
return fmt.Errorf("client %s is disconnect", clientId)
|
||||
}
|
||||
|
||||
ws.mapClientLocker.Unlock()
|
||||
bytes,err := ws.process.Marshal(clientid,msg)
|
||||
bytes, err := ws.process.Marshal(clientId, msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return client.wsConn.WriteMsg(bytes)
|
||||
}
|
||||
|
||||
func (ws *WSService) Close(clientid string) {
|
||||
func (ws *WSService) Close(clientId string) {
|
||||
ws.mapClientLocker.Lock()
|
||||
defer ws.mapClientLocker.Unlock()
|
||||
|
||||
client,ok := ws.mapClient[clientid]
|
||||
if ok == false{
|
||||
client, ok := ws.mapClient[clientId]
|
||||
if ok == false {
|
||||
return
|
||||
}
|
||||
|
||||
if client.wsConn!=nil {
|
||||
if client.wsConn != nil {
|
||||
client.wsConn.Close()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user