diff --git a/cmd/gameserver/action/RoleAction.go b/cmd/gameserver/action/RoleAction.go index 4a48d24..79638cc 100644 --- a/cmd/gameserver/action/RoleAction.go +++ b/cmd/gameserver/action/RoleAction.go @@ -42,7 +42,7 @@ func LoginRpc(msg components.IMessage) (int32, interface{}) { return 1, nil } - role := models.RoleExistByUid(req.Uid) + role := models.RoleExistByUid(req.Token) if role == nil { return 2, nil } diff --git a/cmd/gameserver/game.go b/cmd/gameserver/game.go index b6e2df3..5df7f7f 100644 --- a/cmd/gameserver/game.go +++ b/cmd/gameserver/game.go @@ -6,7 +6,7 @@ import ( "pro2d/cmd/gameserver/action" "pro2d/common" "pro2d/common/components" - "pro2d/common/db" + "pro2d/common/db/mongoproxy" "pro2d/models" "pro2d/common/etcd" @@ -34,7 +34,7 @@ func NewGameServer(sconf *common.SConf) (*GameServer, error) { s.IServer = iserver //mgo init - err := db.ConnectMongo(sconf.MongoConf) + err := mongoproxy.ConnectMongo(sconf.MongoConf) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (s *GameServer) Start() error { func (s *GameServer) Stop() { s.IServer.Stop() - db.CloseMongo() + mongoproxy.CloseMongo() s.EtcdClient.Close() } diff --git a/cmd/gameserver/plugin/plugin.go b/cmd/gameserver/plugin/plugin.go index 58c1bf1..c03c3f1 100644 --- a/cmd/gameserver/plugin/plugin.go +++ b/cmd/gameserver/plugin/plugin.go @@ -28,7 +28,7 @@ func LoginRpc(msg components.IMessage) (int32, interface{}) { return 1, nil } - role := models.RoleExistByUid(req.Uid) + role := models.RoleExistByUid(req.Token) if role == nil { return 2, nil } diff --git a/cmd/httpserver/AccountAction.go b/cmd/httpserver/AccountAction.go index 9079eb6..ee29d02 100644 --- a/cmd/httpserver/AccountAction.go +++ b/cmd/httpserver/AccountAction.go @@ -15,35 +15,39 @@ type AccountAction struct { func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ var register pb.Register if err := c.ShouldBindJSON(®ister); err != nil { - return -1, err.Error() + return 1, err.Error() + } + + if register.Code != "0000" { + return 2, "code error" } account := models.NewAccount(register.Phone) if err := account.Load(); err == nil { - return -2 , "account exists: " + register.Phone + return 3 , "account exists: " + register.Phone } account.Uid = common.SnowFlack.NextValStr() account.Password = utils.Md5V(register.Password) if err := account.Create(); err != nil{ - return -3, "account register err: " + err.Error() + return 4, "account register err: " + err.Error() } account.Password = register.Password - return 0, account.Account + return 0, "success" } func (h *AccountAction) Login(c *gin.Context) (int,interface{}) { var login pb.Account if err := c.ShouldBindJSON(&login); err != nil { - return -1, err.Error() + return 1, err.Error() } account := models.NewAccount(login.Phone) if err := account.Load(); err != nil { - return -2, err.Error() + return 2, err.Error() } if utils.Md5V(login.Password) != account.Password { - return -3, "password error" + return 3, "password error" } var gs []*pb.ServiceInfo @@ -55,7 +59,7 @@ func (h *AccountAction) Login(c *gin.Context) (int,interface{}) { }) } rsp := &pb.LoginRsp{ - Uid: account.Uid, + Token: account.Uid, GameService: gs, } return 0, rsp diff --git a/cmd/httpserver/http.go b/cmd/httpserver/http.go index 8f6de30..01c36b6 100644 --- a/cmd/httpserver/http.go +++ b/cmd/httpserver/http.go @@ -6,7 +6,7 @@ import ( "os/signal" "pro2d/common" "pro2d/common/components" - "pro2d/common/db" + "pro2d/common/db/mongoproxy" "pro2d/common/etcd" "pro2d/common/logger" "syscall" @@ -23,7 +23,7 @@ func NewAccountServer(version string, port ...string) *AccountServer { func (s *AccountServer) Init() error { //mgo init - err := db.ConnectMongo(common.GlobalConf.AccountConf.MongoConf) + err := mongoproxy.ConnectMongo(common.GlobalConf.AccountConf.MongoConf) //Etcd 初始化 s.EtcdClient, err = etcd.NewEtcdClient(common.GlobalConf.Etcd) diff --git a/common/conf.go b/common/conf.go index 7d72915..5927ae6 100644 --- a/common/conf.go +++ b/common/conf.go @@ -6,6 +6,7 @@ import ( "gopkg.in/yaml.v3" "io/ioutil" "pro2d/common/logger" + "pro2d/common/snow" "strings" ) @@ -92,7 +93,7 @@ type ServerConf struct { var( GlobalConf ServerConf - SnowFlack *Snowflake + SnowFlack *snow.Snowflake ) func init() { @@ -120,5 +121,5 @@ func init() { } //初始化雪花算法 - SnowFlack = NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) + SnowFlack = snow.NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) } \ No newline at end of file diff --git a/common/db/mongo.go b/common/db/mongo.go deleted file mode 100644 index 8a9b1d1..0000000 --- a/common/db/mongo.go +++ /dev/null @@ -1,104 +0,0 @@ -package db - -import ( - "context" - "fmt" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "go.mongodb.org/mongo-driver/x/bsonx" - "pro2d/common/components" - "sort" - "strings" -) - -var ( - mongoClient *mongo.Client - mongoDatabase *mongo.Database -) - -type MgoColl struct { - components.IDB - Schema components.ISchema - - dbname string - coll *mongo.Collection -} - -func NewMongoColl(dbname string, schema components.ISchema) *MgoColl { - m := &MgoColl{ - dbname: dbname, - coll: DB().Collection(dbname), - Schema: schema, - } - return m -} - -func (m *MgoColl) CreateTable() error { - colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) - pos := sort.SearchStrings(colls, m.dbname) - if pos != len(colls) { - if m.dbname == colls[pos] { - return DB().CreateCollection(context.TODO(), m.dbname) - } - } - return DB().CreateCollection(context.TODO(), m.dbname) -} - -func (m *MgoColl) Create() (interface{}, error){ - return m.coll.InsertOne(context.TODO(), m.Schema.GetSchema()) -} - -func (m *MgoColl) Load() error{ - r := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) - err := r.Decode(m.Schema.GetSchema()) - if err != nil { - return err - } - return nil -} - -// 查询单个 -func (m *MgoColl) FindOne() error { - singleResult := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) - return singleResult.Decode(m.Schema.GetSchema()) -} - -func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { - res, err := m.coll.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) - if err != nil { - return nil - } - return res -} - -func (m *MgoColl) UpdateProperty(key string, val interface{}) error { - _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), bson.D{{"$set", bson.M{strings.ToLower(key): val}}}) - return err -} - -func (m *MgoColl) UpdateProperties(properties map[string]interface{}) error { - _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), properties) - return err -} - -//索引 -func (m *MgoColl) SetUnique(key string) (string, error){ - return m.coll.Indexes().CreateOne( - context.Background(), - mongo.IndexModel{ - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, - Options: options.Index().SetUnique(true), - }, - ) -} - -func (m *MgoColl) Delete(key string, value interface{}) int64 { - filter := bson.D{ {key, value}} - count, err := m.coll.DeleteOne(context.TODO(), filter, nil) - if err != nil { - fmt.Println(err) - } - return count.DeletedCount - -} diff --git a/common/db/mongoplugin.go b/common/db/mongoplugin.go deleted file mode 100644 index c4de4ff..0000000 --- a/common/db/mongoplugin.go +++ /dev/null @@ -1,148 +0,0 @@ -package db - -import ( - "context" - "fmt" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "go.mongodb.org/mongo-driver/mongo/readpref" - "go.mongodb.org/mongo-driver/x/bsonx" - "pro2d/common" - "pro2d/common/logger" - "reflect" - "sort" - "strings" - "time" -) - -func DB() *mongo.Database { - return mongoDatabase -} - -func ConnectMongo(conf *common.MongoConf) error { - var uri string - if conf.User!= "" { - //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) - uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", conf.User, conf.Password, conf.Host, conf.Port) - }else { - //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) - uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", conf.Host, conf.Port) - } - // 设置连接超时时间 - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.TimeOut) * time.Second) - defer cancel() - // 通过传进来的uri连接相关的配置 - o := options.Client().ApplyURI(uri) - // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 - o.SetMaxPoolSize(uint64(conf.MaxNum)) - // 发起链接 - var err error - mongoClient, err = mongo.Connect(ctx, o) - if err != nil { - return err - } - // 判断服务是不是可用 - if err = mongoClient.Ping(context.Background(), readpref.Primary()); err != nil { - return err - } - - mongoDatabase = mongoClient.Database(conf.DBName) - return nil -} - -func CloseMongo(){ - mongoClient.Disconnect(context.TODO()) -} - -func CreateTable(tb string) error { - colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) - pos := sort.SearchStrings(colls, tb) - if pos != len(colls) { - if tb == colls[pos] { - return DB().CreateCollection(context.TODO(), tb) - } - } - return DB().CreateCollection(context.TODO(), tb) -} - -func FindOne(pri interface{}, schema interface{}) error { - r := mongoDatabase.Collection(GetCollName(schema)).FindOne(context.TODO(), pri) - return r.Decode(schema) -} - -func GetBsonD(key string, value interface{}) interface{} { - return bson.D{ {key, value}} -} - -func GetBsonM(key string, value interface{}) interface{} { - return bson.M{key: value} -} - -func GetSchemaType(schema interface{}) reflect.Type { - s := reflect.TypeOf(schema) - if s.Kind() == reflect.Ptr { - s = reflect.TypeOf(schema).Elem() - } - return s -} - -func GetCollName(schema interface{}) string { - return strings.ToLower(GetSchemaType(schema).Name()) -} - -func GetPriKey(schema interface{}) string { - s := GetSchemaType(schema) - - var pri string - for i := 0; i < s.NumField(); i++ { - if s.Field(i).Tag.Get("pri") == "1" { - pri = strings.ToLower(s.Field(i).Name) - break - } - } - return pri -} - -func FindIndex(schema interface{}) (string, []string){ - s := GetSchemaType(schema) - - var index []string - for i := 0; i < s.NumField(); i++ { - if s.Field(i).Tag.Get("index") != "" { - js := strings.Split(s.Field(i).Tag.Get("json"), ",") - if len(js) == 0 { - continue - } - index = append(index, js[0]) - } - } - return strings.ToLower(s.Name()), index -} - -func SetUnique(coll, key string) (string, error){ - return DB().Collection(coll).Indexes().CreateOne( - context.TODO(), - mongo.IndexModel{ - Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, - Options: options.Index().SetUnique(true), - }, - ) -} - -func InitDoc(schema ...interface{}) { - for _, s := range schema { - coll, keys := FindIndex(s) - CreateTable(coll) - for _, index := range keys { - - logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) - res, err := SetUnique(coll, index) - if err != nil { - logger.Error("InitDoc unique: %s, err: %v", res, err) - continue - } - } - } - -} \ No newline at end of file diff --git a/common/db/mongoproxy/mongo.go b/common/db/mongoproxy/mongo.go new file mode 100644 index 0000000..547ab34 --- /dev/null +++ b/common/db/mongoproxy/mongo.go @@ -0,0 +1,104 @@ +package mongoproxy + +import ( + "context" + "fmt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/x/bsonx" + "pro2d/common/components" + "sort" + "strings" +) + +var ( + mongoClient *mongo.Client + mongoDatabase *mongo.Database +) + +type MgoColl struct { + components.IDB + Schema components.ISchema + + dbname string + coll *mongo.Collection +} + +func NewMongoColl(dbname string, schema components.ISchema) *MgoColl { + m := &MgoColl{ + dbname: dbname, + coll: DB().Collection(dbname), + Schema: schema, + } + return m +} + +func (m *MgoColl) CreateTable() error { + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) + pos := sort.SearchStrings(colls, m.dbname) + if pos != len(colls) { + if m.dbname == colls[pos] { + return DB().CreateCollection(context.TODO(), m.dbname) + } + } + return DB().CreateCollection(context.TODO(), m.dbname) +} + +func (m *MgoColl) Create() (interface{}, error){ + return m.coll.InsertOne(context.TODO(), m.Schema.GetSchema()) +} + +func (m *MgoColl) Load() error{ + r := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) + err := r.Decode(m.Schema.GetSchema()) + if err != nil { + return err + } + return nil +} + +// 查询单个 +func (m *MgoColl) FindOne() error { + singleResult := m.coll.FindOne(context.TODO(), m.Schema.GetPri()) + return singleResult.Decode(m.Schema.GetSchema()) +} + +func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { + res, err := m.coll.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) + if err != nil { + return nil + } + return res +} + +func (m *MgoColl) UpdateProperty(key string, val interface{}) error { + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), bson.D{{"$set", bson.M{strings.ToLower(key): val}}}) + return err +} + +func (m *MgoColl) UpdateProperties(properties map[string]interface{}) error { + _, err := m.coll.UpdateOne(context.TODO(), m.Schema.GetPri(), properties) + return err +} + +//索引 +func (m *MgoColl) SetUnique(key string) (string, error){ + return m.coll.Indexes().CreateOne( + context.Background(), + mongo.IndexModel{ + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, + Options: options.Index().SetUnique(true), + }, + ) +} + +func (m *MgoColl) Delete(key string, value interface{}) int64 { + filter := bson.D{ {key, value}} + count, err := m.coll.DeleteOne(context.TODO(), filter, nil) + if err != nil { + fmt.Println(err) + } + return count.DeletedCount + +} diff --git a/common/db/mongoproxy/mongoplugin.go b/common/db/mongoproxy/mongoplugin.go new file mode 100644 index 0000000..a9056f3 --- /dev/null +++ b/common/db/mongoproxy/mongoplugin.go @@ -0,0 +1,148 @@ +package mongoproxy + +import ( + "context" + "fmt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/mongo/readpref" + "go.mongodb.org/mongo-driver/x/bsonx" + "pro2d/common" + "pro2d/common/logger" + "reflect" + "sort" + "strings" + "time" +) + +func DB() *mongo.Database { + return mongoDatabase +} + +func ConnectMongo(conf *common.MongoConf) error { + var uri string + if conf.User!= "" { + //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) + uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/?w=majority", conf.User, conf.Password, conf.Host, conf.Port) + }else { + //uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) + uri = fmt.Sprintf("mongodb://%s:%d/?w=majority", conf.Host, conf.Port) + } + // 设置连接超时时间 + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.TimeOut) * time.Second) + defer cancel() + // 通过传进来的uri连接相关的配置 + o := options.Client().ApplyURI(uri) + // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 + o.SetMaxPoolSize(uint64(conf.MaxNum)) + // 发起链接 + var err error + mongoClient, err = mongo.Connect(ctx, o) + if err != nil { + return err + } + // 判断服务是不是可用 + if err = mongoClient.Ping(context.Background(), readpref.Primary()); err != nil { + return err + } + + mongoDatabase = mongoClient.Database(conf.DBName) + return nil +} + +func CloseMongo(){ + mongoClient.Disconnect(context.TODO()) +} + +func CreateTable(tb string) error { + colls, _ := DB().ListCollectionNames(context.TODO(), bson.D{}) + pos := sort.SearchStrings(colls, tb) + if pos != len(colls) { + if tb == colls[pos] { + return DB().CreateCollection(context.TODO(), tb) + } + } + return DB().CreateCollection(context.TODO(), tb) +} + +func FindOne(pri interface{}, schema interface{}) error { + r := mongoDatabase.Collection(GetCollName(schema)).FindOne(context.TODO(), pri) + return r.Decode(schema) +} + +func GetBsonD(key string, value interface{}) interface{} { + return bson.D{ {key, value}} +} + +func GetBsonM(key string, value interface{}) interface{} { + return bson.M{key: value} +} + +func GetSchemaType(schema interface{}) reflect.Type { + s := reflect.TypeOf(schema) + if s.Kind() == reflect.Ptr { + s = reflect.TypeOf(schema).Elem() + } + return s +} + +func GetCollName(schema interface{}) string { + return strings.ToLower(GetSchemaType(schema).Name()) +} + +func GetPriKey(schema interface{}) string { + s := GetSchemaType(schema) + + var pri string + for i := 0; i < s.NumField(); i++ { + if s.Field(i).Tag.Get("pri") == "1" { + pri = strings.ToLower(s.Field(i).Name) + break + } + } + return pri +} + +func FindIndex(schema interface{}) (string, []string){ + s := GetSchemaType(schema) + + var index []string + for i := 0; i < s.NumField(); i++ { + if s.Field(i).Tag.Get("index") != "" { + js := strings.Split(s.Field(i).Tag.Get("json"), ",") + if len(js) == 0 { + continue + } + index = append(index, js[0]) + } + } + return strings.ToLower(s.Name()), index +} + +func SetUnique(coll, key string) (string, error){ + return DB().Collection(coll).Indexes().CreateOne( + context.TODO(), + mongo.IndexModel{ + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, + Options: options.Index().SetUnique(true), + }, + ) +} + +func InitDoc(schema ...interface{}) { + for _, s := range schema { + coll, keys := FindIndex(s) + CreateTable(coll) + for _, index := range keys { + + logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index) + res, err := SetUnique(coll, index) + if err != nil { + logger.Error("InitDoc unique: %s, err: %v", res, err) + continue + } + } + } + +} \ No newline at end of file diff --git a/common/db/redis.go b/common/db/redis.go deleted file mode 100644 index 76de78a..0000000 --- a/common/db/redis.go +++ /dev/null @@ -1,43 +0,0 @@ -package db - -import ( - "github.com/garyburd/redigo/redis" - "time" -) -var RedisPool *redis.Pool - -//conf *conf.ServerConf -func ConnectRedis(db int, auth, address string) error { - RedisPool = &redis.Pool{ - //最大活跃连接数,0代表无限 - MaxActive: 888, - MaxIdle: 20, - //闲置连接的超时时间 - IdleTimeout: time.Second * 100, - //定义拨号获得连接的函数 - Dial: func() (redis.Conn, error) { - option := []redis.DialOption{redis.DialDatabase(db)} - if auth != "" { - option = append(option, redis.DialPassword(auth)) - } - return redis.Dial("tcp",address, option...) - }, - } - return nil -} - -func CloseRedis() { - RedisPool.Close() -} - -func HKEYS(args ...interface{}) (reply interface{}, err error) { - conn := RedisPool.Get() - defer conn.Close() - return conn.Do("HKEYS", args) -} - -func HMSET(args ...interface{}) (reply interface{}, err error) { - conn := RedisPool.Get() - defer conn.Close() - return conn.Do("HMSET", args) -} \ No newline at end of file diff --git a/common/db/redisproxy/redis.go b/common/db/redisproxy/redis.go new file mode 100644 index 0000000..bbab04f --- /dev/null +++ b/common/db/redisproxy/redis.go @@ -0,0 +1,43 @@ +package redisproxy + +import ( + "github.com/garyburd/redigo/redis" + "time" +) +var RedisPool *redis.Pool + +//conf *conf.ServerConf +func ConnectRedis(db int, auth, address string) error { + RedisPool = &redis.Pool{ + //最大活跃连接数,0代表无限 + MaxActive: 888, + MaxIdle: 20, + //闲置连接的超时时间 + IdleTimeout: time.Second * 100, + //定义拨号获得连接的函数 + Dial: func() (redis.Conn, error) { + option := []redis.DialOption{redis.DialDatabase(db)} + if auth != "" { + option = append(option, redis.DialPassword(auth)) + } + return redis.Dial("tcp",address, option...) + }, + } + return nil +} + +func CloseRedis() { + RedisPool.Close() +} + +func HKEYS(args ...interface{}) (reply interface{}, err error) { + conn := RedisPool.Get() + defer conn.Close() + return conn.Do("HKEYS", args) +} + +func HMSET(args ...interface{}) (reply interface{}, err error) { + conn := RedisPool.Get() + defer conn.Close() + return conn.Do("HMSET", args) +} \ No newline at end of file diff --git a/common/snow/snowflake.go b/common/snow/snowflake.go new file mode 100644 index 0000000..31a350b --- /dev/null +++ b/common/snow/snowflake.go @@ -0,0 +1,73 @@ +package snow + +import ( + "fmt" + "github.com/golang/glog" + "sync" + "time" +) + +type Snowflake struct { + *sync.Mutex // 锁 + timestamp int64 // 时间戳 ,毫秒 + workerid int64 // 工作节点 + datacenterid int64 // 数据中心机房id + sequence int64 // 序列号 +} +const ( + epoch = int64(1577808000000) // 设置起始时间(时间戳/毫秒):2020-01-01 00:00:00,有效期69年 + timestampBits = uint(41) // 时间戳占用位数 + datacenteridBits = uint(2) // 数据中心id所占位数 + workeridBits = uint(7) // 机器id所占位数 + sequenceBits = uint(12) // 序列所占的位数 + timestampMax = int64(-1 ^ (-1 << timestampBits)) // 时间戳最大值 + datacenteridMax = int64(-1 ^ (-1 << datacenteridBits)) // 支持的最大数据中心id数量 + workeridMax = int64(-1 ^ (-1 << workeridBits)) // 支持的最大机器id数量 + sequenceMask = int64(-1 ^ (-1 << sequenceBits)) // 支持的最大序列id数量 + workeridShift = sequenceBits // 机器id左移位数 + datacenteridShift = sequenceBits + workeridBits // 数据中心id左移位数 + timestampShift = sequenceBits + workeridBits + datacenteridBits // 时间戳左移位数 +) + +func NewSnowflake(workerid, datacenterid int64) *Snowflake { + return &Snowflake{ + Mutex: new(sync.Mutex), + timestamp: time.Now().UnixNano() / 1000000, + workerid: workerid, + datacenterid: datacenterid, + sequence: 0, + } +} + +func (s *Snowflake) NextValStr() string { + return fmt.Sprintf("%d", s.NextVal()) +} + +func (s *Snowflake) NextVal() int64 { + s.Lock() + now := time.Now().UnixNano() / 1000000 // 转毫秒 + if s.timestamp == now { + // 当同一时间戳(精度:毫秒)下多次生成id会增加序列号 + s.sequence = (s.sequence + 1) & sequenceMask + if s.sequence == 0 { + // 如果当前序列超出12bit长度,则需要等待下一毫秒 + // 下一毫秒将使用sequence:0 + for now <= s.timestamp { + now = time.Now().UnixNano() / 1000000 + } + } + } else { + // 不同时间戳(精度:毫秒)下直接使用序列号:0 + s.sequence = 0 + } + t := now - epoch + if t > timestampMax { + s.Unlock() + glog.Errorf("epoch must be between 0 and %d", timestampMax-1) + return 0 + } + s.timestamp = now + r := int64((t)< timestampMax { - s.Unlock() - glog.Errorf("epoch must be between 0 and %d", timestampMax-1) - return 0 - } - s.timestamp = now - r := int64((t)< models.Role - 6, // 1: game.RoleRsp.hero:type_name -> models.Hero - 7, // 2: game.RoleRsp.team:type_name -> models.Team - 8, // 3: game.RoleRsp.equips:type_name -> models.Equipment + 4, // 0: game.RoleRsp.role:type_name -> models.Role + 5, // 1: game.RoleRsp.hero:type_name -> models.Hero + 6, // 2: game.RoleRsp.team:type_name -> models.Team + 7, // 3: game.RoleRsp.equips:type_name -> models.Equipment 4, // [4:4] is the sub-list for method output_type 4, // [4:4] is the sub-list for method input_type 4, // [4:4] is the sub-list for extension type_name @@ -403,18 +344,6 @@ func file_game_proto_init() { } } file_game_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LoginResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_game_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateReq); i { case 0: return &v.state @@ -426,7 +355,7 @@ func file_game_proto_init() { return nil } } - file_game_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_game_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RoleRsp); i { case 0: return &v.state @@ -445,7 +374,7 @@ func file_game_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_game_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/protos b/protos index 7257f0e..f725ea2 160000 --- a/protos +++ b/protos @@ -1 +1 @@ -Subproject commit 7257f0e1d7cbce636e95993247107ca58fd5e374 +Subproject commit f725ea29c1806f14c15502406a83b4269193f76b -- libgit2 0.21.2