Example #1
0
/*
   发送给消息接受者的消息
   MsgServer -> device/client
       REQ_SEND_P2P_MSG_CMD
       arg0: Msg           //消息内容
       arg1: FromID        //发送方用户ID
       arg2: uuid          //MsgServer分配的消息uuid,可选,如果提供了则须IND_ACK_P2P_STATUS_CMD(ClientID, uuid)
*/
func (self *ProtoProc) procOfflineMsg(session *libnet.Session, ID string) error {
	var err error
	exist, err := self.msgServer.offlineMsgCache.IsKeyExist(ID)
	if exist.(int64) == 0 {
		return err
	} else {
		omrd, err := common.GetOfflineMsgFromOwnerName(self.msgServer.offlineMsgCache, ID)
		if err != nil {
			log.Error(err.Error())
			return err
		}
		for _, v := range omrd.MsgList {
			if v.Msg == protocol.IND_ACK_P2P_STATUS_CMD {
				resp := protocol.NewCmdSimple(protocol.IND_ACK_P2P_STATUS_CMD)
				resp.AddArg(v.Uuid)
				resp.AddArg(v.FromID) // v.FromID is status
				if self.msgServer.sessions[ID] != nil {
					self.msgServer.sessions[ID].Send(libnet.Json(resp))
					if err != nil {
						log.Error(err.Error())
						return err
					}
				}
			} else {
				resp := protocol.NewCmdSimple(protocol.REQ_SEND_P2P_MSG_CMD)
				resp.AddArg(v.Msg)
				resp.AddArg(v.FromID)
				resp.AddArg(v.Uuid)

				if self.msgServer.sessions[ID] != nil {
					self.msgServer.sessions[ID].Send(libnet.Json(resp))
					if err != nil {
						log.Error(err.Error())
						return err
					} else {
						self.procP2PAckStatus(v.FromID, v.Uuid, protocol.P2P_ACK_SENT)
					}
				}
			}
		}

		omrd.ClearMsg()
		self.msgServer.offlineMsgCache.Set(omrd)
	}

	return err
}
Example #2
0
/*
   IND_ACK_P2P_STATUS_CMD
   arg0: uuid // 发送方知道uuid对应的已发送的消息已送达
   arg1: SENT/READ // 发送方知道uuid对应的消息状态:已送达/已读
*/
func (self *ProtoProc) procP2PAckStatus(fromID string, uuid string, status string) error {
	log.Info("procP2PAckStatus")
	//var err error

	p2psd, err := self.msgServer.p2pStatusCache.Get(fromID)
	if p2psd == nil {
		p2psd = redis_store.NewP2pStatusCacheData(fromID)
	}
	p2psd.Set(uuid, status)

	if status == protocol.P2P_ACK_FALSE {
		return nil
	}

	sessionCacheData, err := self.msgServer.sessionCache.Get(fromID)
	if sessionCacheData == nil {
		log.Warningf("no cache ID : %s, err: %s", fromID, err.Error())
		sessionStoreData, err := self.msgServer.mongoStore.GetSessionFromCid(fromID)
		if sessionStoreData == nil {
			// not registered
			log.Warningf("no store ID : %s, err: %s", fromID, err.Error())
			self.msgServer.p2pStatusCache.Delete(fromID)
			return err
		}
	}
	if sessionCacheData == nil || sessionCacheData.Alive == false {
		// offline
		log.Info(fromID + " | is offline")
		omrd, err := common.GetOfflineMsgFromOwnerName(self.msgServer.offlineMsgCache, fromID)
		log.Info(omrd)
		if err != nil {
			log.Error(err.Error())
			return err
		}
		if omrd == nil {
			omrd = redis_store.NewOfflineMsgCacheData(fromID)
		}
		omrd.AddMsg(redis_store.NewOfflineMsgData(protocol.IND_ACK_P2P_STATUS_CMD /*fromID*/, status, uuid))

		err = self.msgServer.offlineMsgCache.Set(omrd)

		if err != nil {
			log.Error(err.Error())
			return err
		}
	} else {
		// online
		resp := protocol.NewCmdSimple(protocol.IND_ACK_P2P_STATUS_CMD)
		resp.AddArg(uuid)
		resp.AddArg(status)
		log.Info(fromID + " | is online")
		if sessionCacheData.MsgServerAddr == self.msgServer.cfg.LocalIP {
			log.Info("in the same server")

			if self.msgServer.sessions[fromID] != nil {
				self.msgServer.sessions[fromID].Send(libnet.Json(resp))
				if err != nil {
					log.Error(err.Error())
					return err
				}
			}
		} else {
			log.Info("not in the same server")
			if self.msgServer.channels[protocol.SYSCTRL_SEND] != nil {
				resp.AddArg(fromID)
				_, err = self.msgServer.channels[protocol.SYSCTRL_SEND].Channel.Broadcast(libnet.Json(resp))
				if err != nil {
					log.Error(err.Error())
					return err
				}
			}
		}
	}

	return nil
}