func (this *UserMap) Online(uid int64, host string) { bn := getBlockID(uid) this.mu[bn].Lock() hostlist, ok := this.kv[bn][uid] if !ok { hostlist = hlist.New() this.kv[bn][uid] = hostlist } doAdd := true if hostlist.Len() > 0 { for e := hostlist.Front(); e != nil; e = e.Next() { if _host, ok := e.Value.(string); ok { if _host == host { doAdd = false break } } } } if doAdd { hostlist.PushFront(host) } else { glog.Warningf("[online|repeat] id %d online repeatly on host %v which could be a mistake between LoadAllUser and SubOnlineUser", uid, host) } this.mu[bn].Unlock() }
func NewRmqs(onNew func(server string), onClosed func(server string), onSentMsg func(msg []byte)) *Rmqs { r := &Rmqs{ onNew: onNew, onClosed: onClosed, onSentMsg: onSentMsg, servers: hlist.New(), curr: nil, mu: sync.Mutex{}, } return r }
func (this *UserMap) Load(users []string, host string) { for i := 0; i < len(users); i++ { uid, _ := strconv.ParseInt(users[i], 10, 64) bn := getBlockID(uid) h, ok := this.kv[bn][uid] if !ok { h = hlist.New() this.kv[bn][uid] = h } if glog.V(1) { glog.Infof("[load online] user %d on %s", uid, host) } h.PushFront(host) } }
func (this *UserMap) GetUserComet(uid int64) (*hlist.Hlist, error) { bn := getBlockID(uid) this.mu[bn].Lock() hosts, ok := this.kv[bn][uid] if !ok { this.mu[bn].Unlock() return nil, fmt.Errorf("[bus|err] Cannot found %d comet", uid) } newList := hlist.New() for e := hosts.Front(); e != nil; e = e.Next() { newList.PushFront(e.Value) } this.mu[bn].Unlock() return newList, nil }
func (this *SessionList) AddSession(s *Session) *hlist.Element { // 能想到的错误返回值是同一用户,同一mac多次登录,但这可能不算错误 blockId := getBlockID(s.Uid) this.onlinedMu[blockId].Lock() h, ok := this.onlined[blockId][s.Uid] var e *hlist.Element if ok { e = h.PushFront(s) } else { h = hlist.New() this.onlined[blockId][s.Uid] = h e = h.PushFront(s) } this.onlinedMu[blockId].Unlock() return e }
func NewMsgBusManager() *MsgBusManager { return &MsgBusManager{list: hlist.New(), mu: &sync.Mutex{}} }
func MainHandle(srcMsg []byte) { statIncUpStreamIn() srcId := int64(binary.LittleEndian.Uint64(srcMsg[:8])) msg := srcMsg[8:] idsSize := binary.LittleEndian.Uint16(msg[:2]) toIds := msg[2 : 2+idsSize*8] data := msg[2+idsSize*8:] if glog.V(2) { var ids []int64 for i := uint16(0); i < idsSize; i++ { ids = append(ids, int64(binary.LittleEndian.Uint64(toIds[i*8:i*8+8]))) } glog.Infof("[bus|in] from: %d to ids: %v, ids count: %d, total len: %d, data: %v...", srcId, ids, idsSize, len(msg), msg[:3]) } if srcId < 0 { shouldForward := msgs.IsForwardType(data) // Write into rabbitmq if !shouldForward { msgId := msgs.GetMsgId(data) GRmqs.Push(data, int(msgId)) id := msgs.ForwardSrcId(data) ackMsg := msgs.NewAckMsg(data) pushBuf := make([]byte, 2+8+len(ackMsg)) binary.LittleEndian.PutUint16(pushBuf[:8], 1) binary.LittleEndian.PutUint64(pushBuf[2:2+8], uint64(id)) copy(pushBuf[2+8:], ackMsg) err := GUserMap.PushToComet(id, pushBuf) if err != nil { statIncDownStreamOutBad() glog.Errorf("[bus|ack] ACK to [%d] error: %v", id, err) } return } } if idsSize == 1 { uid := int64(binary.LittleEndian.Uint64(toIds)) var err error if uid > 0 { glog.Infoln("GUserMap.PushToComet(uid, msg)", uid, msg) err = GUserMap.PushToComet(uid, msg) } else if uid < 0 { glog.Infoln("GComets.PushUdpMsg(msg)", uid, msg) err = GComets.PushUdpMsg(msg) if err == nil { if glog.V(3) { glog.Infof("[bus|down] to: %d, data: (len: %d)%v", uid, len(msg), msg) } else if glog.V(2) { glog.Infof("[bus|down] to: %d, data: (len: %d)%v", uid, len(msg), msg[:3]) } } } if err != nil { statIncDownStreamOutBad() glog.Errorf("Push to comet failed, [%d] %v", uid, err) } return } // key: cometName, value: idList wsCometToIds := make(map[string]*hlist.Hlist, idsSize) var udpIds *hlist.Hlist for i := uint16(0); i < idsSize; i++ { id := int64(binary.LittleEndian.Uint64(toIds[i*8 : i*8+8])) if id > 0 { cometHosts, err := GUserMap.GetUserComet(id) if err != nil { if glog.V(4) { glog.Errorf("id: %d, error: %v", id, err) } continue } for e := cometHosts.Front(); e != nil; e = e.Next() { haddr, _ := e.Value.(string) hl, ok := wsCometToIds[haddr] if !ok { hl = hlist.New() wsCometToIds[haddr] = hl } hl.PushFront(id) } } else if id < 0 { if udpIds == nil { udpIds = hlist.New() } udpIds.PushFront(id) } } for k, v := range wsCometToIds { vSize := uint16(v.Len()) pushData := make([]byte, 2+vSize*8+uint16(len(data))) binary.LittleEndian.PutUint16(pushData[:2], vSize) i := 0 //var idsDebug []int64 for e := v.Front(); e != nil; e = e.Next() { id, _ := e.Value.(int64) binary.LittleEndian.PutUint64(pushData[2+i*8:2+i*8+8], uint64(id)) //idsDebug = append(idsDebug, id) i++ } copy(pushData[2+vSize*8:], data) err := GComets.PushMsg(pushData, k) if err != nil { glog.Errorf("[bus|down] Broadcast to websocket comet failed, comet: %s, ids: %s, err: %v", k, v, err) } else { if glog.V(3) { glog.Infof("[bus|down] to comet: %s, ids: %s, data: (len: %d)%v", k, v, len(msg), pushData) } else { glog.Infof("[bus|down] to comet: %s, ids: %s, data: (len: %d)%v...", k, v, len(msg), pushData[:3]) } } } if udpIds != nil { vSize := uint16(udpIds.Len()) pushData := make([]byte, 2+vSize*8+uint16(len(data))) binary.LittleEndian.PutUint16(pushData[:2], vSize) copy(pushData[2+vSize*8:], data) err := GComets.PushUdpMsg(pushData) if err != nil { glog.Errorf("[bus|down] Broadcast to udp comet failed, ids: %s, err: %v", udpIds, err) } else { if glog.V(3) { glog.Infof("[bus|down] to udp comet failed, ids: %s, data: (len: %d)%v", udpIds, len(msg), pushData) } else { glog.Infof("[bus|down] to udp comet failed, ids: %s, data: (len: %d)%v...", udpIds, len(msg), pushData[:3]) } } } }