//---------------------------------------------------------- p2p send from src_id to dest_id func Send(src_id, dest_id int32, service int16, multicast bool, object interface{}) (ret bool) { if multicast { return _multicast(src_id, dest_id, service, object) } // convert the OBJECT to json, LEVEL-1 encapsulation val, err := json.Marshal(object) if err != nil { log.Println("cannot marshal object to json", err) return false } req := &IPCObject{SrcID: src_id, DestID: dest_id, Service: service, Object: val, Time: time.Now().Unix()} // first try local delivery, if dest_id is not in the same server, just forward to HUB server. peer := gsdb.QueryOnline(dest_id) if peer != nil { defer func() { if x := recover(); x != nil { ret = false forward_tbl.Push(req) } }() select { case peer.MQ <- *req: case <-time.After(time.Second): panic("deadlock") // rare case, when both chan is full } return true } else { // convert req to json again, LEVEL-2 encapsulation return hub_client.Forward(req) } }
//---------------------------------------------------------- 组播 // 发消息到一组**给定的**目标ID func Multicast(ids []int32, service int16, object interface{}) (ret bool) { // object序列化 val, err := json.Marshal(object) if err != nil { ERR("cannot marshal object to json", err) return false } // 内容包 content := &IPCObject{ Service: service, Object: val, Time: time.Now().Unix(), } content_json, _ := json.Marshal(content) // 封装为Multicast包 mc := &IPCObject{ AuxIDs: ids, Service: SYS_MULTICAST, Object: content_json, Time: time.Now().Unix(), } // 投递到HUB hub_client.Forward(mc) // 投递到本地SYS_ROUTINE peer := gsdb.QueryOnline(SYS_USR) peer.MQ <- *mc return true }
//---------------------------------------------------------- 全服广播一条动态消息 func Broadcast(service int16, object interface{}) (ret bool) { obj, ok := _create_broadcast_ipcobject(service, object) if !ok { return false } // 投递到HUB hub_client.Forward(obj) // 投递到本地SYS_ROUTINE peer := gsdb.QueryOnline(SYS_USR) peer.MQ <- *obj return true }
//---------------------------------------------------------- 异步消息发送 func Send(src_id, dest_id int32, service int16, object interface{}) (ret bool) { // 况序列化被传输对象为json val, err := json.Marshal(object) if err != nil { ERR("cannot marshal object to json", err) return false } // Send函数不能投递到SYS_USR if dest_id == SYS_USR { ERR("cannot Send to SYS_USR") return false } // 打包为IPCObject req := &IPCObject{SrcID: src_id, DestID: dest_id, Service: service, Object: val, Time: time.Now().Unix()} peer := gsdb.QueryOnline(dest_id) if peer != nil { // 如果玩家在本服务器 // 对方的channel 可能会close, 需要处理panic的情况 defer func() { if x := recover(); x != nil { ret = false forward_tbl.Push(req) } }() select { case peer.MQ <- *req: case <-time.After(time.Second): panic("deadlock") // rare case, when both chans are full. } return true } else { // 通过HUB转发IPCObject return hub_client.Forward(req) } return false }