// 玩家登陆过程 func P_user_login_req(sess *Session, reader *packet.Packet) []byte { // TODO: 登陆鉴权 sess.UserId = 1 // TODO: 选择登陆服务器 sess.GSID = DEFAULT_GSID // 选服 cli, err := sp.GetServiceWithId(sp.SERVICE_GAME, sess.GSID) if err != nil { log.Critical(err) return nil } // type assertion game_cli, ok := cli.(spp.GameServiceClient) if !ok { log.Critical("cannot do type assertion on: %v", sess.GSID) return nil } // 开启到游戏服的流 // TODO: 处理context,设定超时 stream, err := game_cli.Stream(context.Background()) if err != nil { log.Critical(err) return nil } sess.Stream = stream // 在game注册 // TODO: 新用户的创建由game处理 sess.Stream.Send(&spp.Game_Frame{Type: spp.Game_Register, UserId: sess.UserId}) // 读取GAME返回消息 fetcher_task := func(sess *Session) { for { in, err := sess.Stream.Recv() if err == io.EOF { // 流关闭 log.Trace(err) return } if err != nil { log.Error(err) return } sess.MQ <- *in } } go fetcher_task(sess) return packet.Pack(Code["user_login_ack"], user_snapshot{F_uid: sess.UserId}, nil) }
// 玩家登陆过程 func P_user_login_req(sess *Session, reader *packet.Packet) []byte { // TODO: 登陆鉴权 sess.UserId = 1 // TODO: 选择登陆服务器 sess.GSID = DEFAULT_GSID // 选服 conn := sp.GetServiceWithId(sp.DEFAULT_SERVICE_PATH+"/game", sess.GSID) if conn == nil { log.Critical("cannot get game service:", sess.GSID) return nil } cli := pb.NewGameServiceClient(conn) // 开启到游戏服的流 // TODO: 处理context,设定超时 stream, err := cli.Stream(context.Background()) if err != nil { log.Critical(err) return nil } sess.Stream = stream // 在game注册 // TODO: 新用户的创建由game处理 sess.Stream.Send(&pb.Game_Frame{Type: pb.Game_Register, UserId: sess.UserId}) // 读取GAME返回消息 fetcher_task := func(sess *Session) { for { in, err := sess.Stream.Recv() if err == io.EOF { // 流关闭 log.Trace(err) return } if err != nil { log.Error(err) return } select { case sess.MQ <- *in: case <-sess.Die: } } } go fetcher_task(sess) return packet.Pack(Code["user_login_succeed_ack"], S_user_snapshot{F_uid: sess.UserId}, nil) }
// 玩家登陆过程 func P_user_login_req(sess *Session, reader *packet.Packet) []byte { // TODO: 登陆鉴权 // 简单鉴权可以在agent直接完成,通常公司都存在一个用户中心服务器用于鉴权 sess.UserId = 1 // TODO: 选择GAME服务器 // 选服策略依据业务进行,比如小服可以固定选取某台,大服可以采用HASH或一致性HASH sess.GSID = DEFAULT_GSID // 连接到已选定GAME服务器 conn := sp.GetServiceWithId(sp.DEFAULT_SERVICE_PATH+"/game", sess.GSID) if conn == nil { log.Critical("cannot get game service:", sess.GSID) return nil } cli := pb.NewGameServiceClient(conn) // 开启到游戏服的流 ctx := metadata.NewContext(context.Background(), metadata.New(map[string]string{"userid": fmt.Sprint(sess.UserId)})) stream, err := cli.Stream(ctx) if err != nil { log.Critical(err) return nil } sess.Stream = stream // 读取GAME返回消息的goroutine fetcher_task := func(sess *Session) { for { in, err := sess.Stream.Recv() if err == io.EOF { // 流关闭 log.Trace(err) return } if err != nil { log.Error(err) return } select { case sess.MQ <- *in: case <-sess.Die: } } } go fetcher_task(sess) return packet.Pack(Code["user_login_succeed_ack"], S_user_snapshot{F_uid: sess.UserId}, nil) }