go-pitaya学习笔记(11) - 测试集群rpc

go-pitaya学习笔记(11) - 测试集群rpc,第1张

 学习笔记: 我家别墅靠大海/pitaya-learn

尝试集成功能:我家别墅靠大海/pitaya-game

如果你正在看此笔记,请你左边放笔记,右边放chatdemo的代码!!

我是按代码的顺序记的笔记

我们自己写一个聊天室,测试一下集群tcp登录和聊天。

第四个demo了

这次我们只有3个服务器

game 登录与聊天室逻辑(前端服务器)

log 日志(后端服务器)

worker

目录结构如下,代码在gitee中

account.go ,处理用户登录

package services

import (
	"context"

	"github.com/topfreegames/pitaya/v2"
	"github.com/topfreegames/pitaya/v2/component"
	pb "github.com/topfreegames/pitaya/v2/examples/demo/cluster_protobuf/protos"
)

type Account struct {
	component.Base
	app pitaya.Pitaya
}

// 暂时用这个存贮账号密码
var AccountMap map[string]string = map[string]string{
	"123123": "123123",
	"abc":    "abc",
}

// 实例化一个句柄
func NewAccount(app pitaya.Pitaya) *Account {
	return &Account{app: app}
}

// 登录参数
type ReqLogin struct {
	UserName string `json:"username"`
	Password string `json:"password"`
}

// req就用json了(用proto的话,client不知道咋写啊。。。)
// proto返还就用demo里面的了
func (a *Account) Login(ctx context.Context, req *ReqLogin) (*pb.Response, error) {

	// 没找到用户
	password, ok := AccountMap[req.UserName]
	if !ok {
		return ReplayError("account not found")
	}

	// 密码错误
	if password != req.Password {
		return ReplayError("password error")
	}

	// 登录成功了的话,绑定一下我的uid
	session_ := a.app.GetSessionFromCtx(ctx)
	err := session_.Bind(ctx, req.UserName)
	if err != nil {
		return ReplayError("bind session error")
	}

	return &pb.Response{
		Code: 0,
		Msg:  "success",
	}, nil
}

common.go

package services

import (
	"errors"

	"github.com/topfreegames/pitaya/v2"
	pb "github.com/topfreegames/pitaya/v2/examples/demo/cluster_protobuf/protos"
)

func ReplayError(msg string) (*pb.Response, error) {
	return &pb.Response{
		Code: 1,
		Msg:  msg,
	}, pitaya.Error(errors.New(msg), "1")
}

log.go 

package services

import (
	"context"
	"fmt"

	"github.com/topfreegames/pitaya/v2/component"
	pb "github.com/topfreegames/pitaya/v2/examples/demo/cluster_protobuf/protos"
)

type Log struct {
	component.Base
}

func (log *Log) RecordLog(ctx context.Context, req *pb.Response) (*pb.Response, error) {
	fmt.Println("record log:", req)
	return &pb.Response{
		Code: 0,
		Msg:  "Success",
	}, nil
}

room.go

package services

import (
	"context"
	"fmt"

	"github.com/topfreegames/pitaya/v2"
	"github.com/topfreegames/pitaya/v2/component"
	pb "github.com/topfreegames/pitaya/v2/examples/demo/cluster_protobuf/protos"
)

type Room struct {
	component.Base
	app pitaya.Pitaya
}

var RoomGroupName string = "RoomGroupName"

// 句柄
func NewRoom(app pitaya.Pitaya) *Room {

	app.GroupCreate(context.Background(), RoomGroupName)

	return &Room{
		app: app,
	}
}

// 加入房间
func (room *Room) Join(ctx context.Context, req []byte) (*pb.Response, error) {

	session_ := room.app.GetSessionFromCtx(ctx)
	uid := session_.UID()

	if uid == "" {
		return ReplayError("not login")
	}

	if have, _ := room.app.GroupContainsMember(ctx, RoomGroupName, uid); have {
		return ReplayError("i in room , uid:" + uid)
	}

	room.app.GroupAddMember(ctx, RoomGroupName, uid)
	room.app.GroupBroadcast(ctx, "game", RoomGroupName, "joinPush", pb.Response{
		Msg: fmt.Sprintf("------------------\n--user: %sjoin\n------------------\n", uid),
	})

	// 为了方便,请求和返还,都用response...
	replay := pb.Response{}
	room.app.ReliableRPC("log.log.recordlog", nil, &replay, &pb.Response{Msg: "uid:" + uid + ",join room"})

	return &pb.Response{
		Code: 0,
		Msg:  "Join Success",
	}, nil
}

// 聊天参数
type ReqMessage struct {
	Msg string `json:"msg"`
}

// 发送消息
func (room *Room) Message(ctx context.Context, req *ReqMessage) (*pb.Response, error) {

	session_ := room.app.GetSessionFromCtx(ctx)
	uid := session_.UID()

	if uid == "" {
		return ReplayError("not login")
	}

	if have, _ := room.app.GroupContainsMember(ctx, RoomGroupName, uid); !have {
		return ReplayError("i not in room")
	}

	room.app.GroupBroadcast(ctx, "game", RoomGroupName, "messagePush", pb.Response{
		Msg: fmt.Sprintf("%s say: %s\n", uid, req.Msg),
	})

	// 为了方便,请求和返还,都用response...
	replay := pb.Response{}
	room.app.ReliableRPC("log.log.recordlog", nil, &replay, &pb.Response{Msg: "uid:" + uid + ", send message :" + req.Msg})

	return &pb.Response{
		Code: 0,
		Msg:  "Send Message Success",
	}, nil
}

worker.go

package services

import (
	"context"

	"github.com/golang/protobuf/proto"
	"github.com/topfreegames/pitaya/v2"
	"github.com/topfreegames/pitaya/v2/component"
	"github.com/topfreegames/pitaya/v2/examples/demo/worker/protos"
)

// Worker server
type Worker struct {
	component.Base
}

// Configure starts workers and register rpc job
func (w *Worker) Configure(app pitaya.Pitaya) {
	app.StartWorker()
	app.RegisterRPCJob(&RPCJob{app: app})
}

// RPCJob implements worker.RPCJob
type RPCJob struct {
	app pitaya.Pitaya
}

// ServerDiscovery returns a serverID="", meaning any server
// is ok
func (r *RPCJob) ServerDiscovery(
	route string,
	rpcMetadata map[string]interface{},
) (serverID string, err error) {
	return "", nil
}

// RPC calls pitaya's rpc
func (r *RPCJob) RPC(
	ctx context.Context,
	serverID, routeStr string,
	reply, arg proto.Message,
) error {
	return r.app.RPCTo(ctx, serverID, routeStr, reply, arg)
}

// GetArgReply returns reply and arg of LogRemote,
// since we have no other methods in this example
func (r *RPCJob) GetArgReply(
	route string,
) (arg, reply proto.Message, err error) {
	return &protos.Arg{}, &protos.Response{}, nil
}

main.go

package main

import (
	"flag"
	"fmt"
	"game/mydemo/demo4/services"
	"strings"

	"github.com/spf13/viper"
	"github.com/topfreegames/pitaya/v2"
	"github.com/topfreegames/pitaya/v2/acceptor"
	"github.com/topfreegames/pitaya/v2/component"
	"github.com/topfreegames/pitaya/v2/config"
)

type srvConfig struct {
	port     int
	frontend bool
}

var scs map[string]srvConfig = map[string]srvConfig{
	"game": {
		port:     3250,
		frontend: true,
	},
	"worker": {
		port:     3251,
		frontend: false,
	},
	"log": {
		port:     3252,
		frontend: false,
	},
}

var app pitaya.Pitaya

func main() {

	srvType := flag.String("type", "game", "server type")
	flag.Parse()

	srvConfig, ok := scs[*srvType]
	if !ok {
		fmt.Println("not found type:", *srvType)
		return
	}

	// 启动worker
	conf := viper.New()
	conf.SetDefault("pitaya.worker.redis.url", "localhost:6379")
	conf.SetDefault("pitaya.worker.redis.pool", "3")
	config := config.NewConfig(conf)

	// 构造器
	builder := pitaya.NewBuilderWithConfigs(srvConfig.frontend, *srvType, pitaya.Cluster, map[string]string{}, config)

	// 如果是前端服务器的话
	if srvConfig.frontend {
		builder.AddAcceptor(acceptor.NewTCPAcceptor(fmt.Sprintf(":%d", srvConfig.port)))
	}

	// 构建火龙果
	app = builder.Build()
	switch *srvType {
	case "game":
		app.Register(services.NewRoom(app), component.WithName("room"), component.WithNameFunc(strings.ToLower))
		app.Register(services.NewAccount(app), component.WithName("account"), component.WithNameFunc(strings.ToLower))
	case "log":
		app.RegisterRemote(&services.Log{}, component.WithName("log"), component.WithNameFunc(strings.ToLower))
	case "worker":
		worker := services.Worker{}
		worker.Configure(app)
	}

	// 延迟关闭
	defer app.Shutdown()
	// 启动
	app.Start()

}

启动

game PS D:\Work\pitaya-test-game\mydemo\demo4> go run .\main.go

worker PS D:\Work\pitaya-test-game\mydemo\demo4> go run .\main.go -type worker

log PS D:\Work\pitaya-test-game\mydemo\demo4> go run .\main.go -type log

测试

笔记:

go-pitaya学习笔记(12) - 看一看火龙果内置模块_冰纳-CSDN博客

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/995132.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-21
下一篇2022-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存