
学习笔记: 我家别墅靠大海/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博客
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)