• [手游项目3]-5-游戏登录排队


    游戏登录排队主要是考虑排名的性能问题,很多插入删除查询操作
    go的map是无序的不好做排名而数组查询效率低
    需要一个有序的map,有序的map可以保证先进先出,顺序不会被打乱
    但是名次问题需要一个的算法

    login_que.go 实现有序map

    package service
    
    import (
    	"container/list"
    	"time"
    )
    
    var MapService = NewMapList()
    
    type MapList struct {
    	dataMap    map[string]*list.Element
    	dataList   *list.List
    	QueueIndex int32
    }
    
    func NewMapList() *MapList {
    	return &MapList{
    		dataMap:    make(map[string]*list.Element),
    		dataList:   list.New(),
    		QueueIndex: 1,
    	}
    }
    
    func (mapList *MapList) Exists(key string) bool {
    	_, exists := mapList.dataMap[key]
    	return exists
    }
    
    func (mapList *MapList) UpDateTime(key string) {
    	info, exists := mapList.dataMap[key]
    	if exists {
    		return
    	}
    	info.Value.(*AccountLogin).time = time.Now().Unix()
    }
    
    func (mapList *MapList) GetRank(key string) int32 {
    	info, exists := mapList.dataMap[key]
    	if exists {
    		return info.Value.(*AccountLogin).rank
    	}
    	return 999
    }
    
    func (mapList *MapList) Push(data AccountLogin) bool {
    	if mapList.Exists(data.account) {
    		return false
    	}
    	elem := mapList.dataList.PushBack(data)
    	mapList.dataMap[data.account] = elem
    	return true
    }
    
    func (mapList *MapList) Remove(key string) {
    	if !mapList.Exists(key) {
    		return
    	}
    	mapList.dataList.Remove(mapList.dataMap[key])
    	delete(mapList.dataMap, key)
    }
    
    func (mapList *MapList) Size() int {
    	return mapList.dataList.Len()
    }
    
    type AccountLogin struct {
    	account string
    	rank    int32
    	time    int64
    }
    
    func (e AccountLogin) GetAccount() string {
    	return e.account
    }
    

    下面排队算法

    	//排队逻辑
    	nOnlineNum := rolemanager.RoleManager.GetOnlineNum()
    	if service.Maxlimit <= nOnlineNum {
    		//取消排队 不用返回协议
    		if reqMsg.LoginType == 2 {
    			MapService.Remove(accountId)
    			return nil
    		}
    		nSize := int32(MapService.Size())
    		for i := int32(0); i < nSize; i++ {
    			//第一名的掉线了
    			first := MapService.dataList.Front()
    			if first == nil {
    				break
    			}
    			heartTime := first.Value.(*AccountLogin).time
    			if 10 < time.Now().Unix()-heartTime {
    				MapService.Remove(first.Value.(*AccountLogin).account)
    			} else {
    				break
    			}
    		}
    		if MapService.Exists(accountId) { //已经在队列里面
    			nRank := MapService.GetRank(accountId)                           //名次编号
    			loginResult.QueueIndex = nRank - (MapService.QueueIndex - nSize) //真实名次
    			if loginResult.QueueIndex < 1 {
    				loginResult.QueueIndex = 1
    			}
    			if loginResult.QueueIndex <= 1 { //我是第一名
    				MapService.Remove(accountId)
    			} else { //排队
    				MapService.UpDateTime(accountId)
    				loginResult.LoginResult = message.Growth_ResRoleLogin_LOGIN_QUEUE
    				return session.Send(message.MSGID_Growth_ResRoleLoginE, loginResult)
    			}
    		} else { //排队
    			loginResult.QueueIndex = nSize + 1
    			Ele := AccountLogin{accountId, MapService.QueueIndex, time.Now().Unix()}
    			MapService.Push(Ele)
    			MapService.QueueIndex++
    			loginResult.LoginResult = message.Growth_ResRoleLogin_LOGIN_QUEUE
    			return session.Send(message.MSGID_Growth_ResRoleLoginE, loginResult)
    		}
    	}
  • 相关阅读:
    继承中的构造函数的问题base,this的用法 Carl
    apache+php+mysql服务器环境配置注意点
    收藏音乐
    doubleClickv2as3.0 概述
    doubleClickv2as3.0 学习笔记(2)
    doubleclickv2as3.0模板
    as 2.0 笔记
    Html css 推荐文章
    [经济杂谈]如果你读懂了 股市就是取款机(要保存的) 管理帖子
    字符编码 UTF8 gb2312
  • 原文地址:https://www.cnblogs.com/byfei/p/14104188.html
Copyright © 2020-2023  润新知