etcd (用于服务发现)
nats (可选的,用于发送和接收rpc, grpc实现也可以使用,如果喜欢的话)
docker (可选:用于在容器上运行etcd和nats依赖项)
安装
clone the repo
git clone https://github测试数据/topfreegames/pitaya.git
setup pitaya dependencies
make setup
Hacking pitaya
下面是一个跑pitaya的例子:
启动etcd(此命令需要docker-compose,并将在本地运行etcd容器。etcd可以在没有docker的情况下运行。
cd ./examples/testing && docker-compose up -d etcd
run the connector frontend server from cluster_grpc example
make run-cluster-grpc-example-connector
run the room backend server from the cluster_grpc example
make run-cluster-grpc-example-room
Now there should be 2 pitaya servers running, a frontend connector and a backend room. To send requests, use a REPL client for pitaya pitaya-cli .
$ pitaya-cli Pitaya REPL Client>>> connect localhost:3250connected!>>> request room.room.entry>>> sv-> {"code":0,"result":"ok"}
Running the tests
Resources
一个聊天的demo package main
import (
"context"
"fmt"
"log"
"net/http"
"strconv"
"time"
"strings"
"github测试数据/spf13/viper"
"github测试数据/topfreegames/pitaya"
"github测试数据/topfreegames/pitaya/acceptor"
"github测试数据/topfreegames/pitaya/component"
"github测试数据/topfreegames/pitaya/config"
"github测试数据/topfreegames/pitaya/groups"
"github测试数据/topfreegames/pitaya/logger"
"github测试数据/topfreegames/pitaya/serialize/json"
"github测试数据/topfreegames/pitaya/timer"
)
type (
// Room represents a component that contains a bundle of room related handler
// like Join/Message
Room struct {
component.Base
timer *timer.Timer
}
// UserMessage represents a message that user sent
UserMessage struct {
Name string `json:"name"`
Content string `json:"content"`
}
// NewUser message will be received when new user join room
NewUser struct {
Content string `json:"content"`
}
// AllMembers contains all members uid
AllMembers struct {
Members []string `json:"members"`
}
// JoinResponse represents the result of joining room
JoinResponse struct {
Code int `json:"code"`
Result string `json:"result"`
}
)
// NewRoom returns a Handler Base implementation
func NewRoom() *Room {
return &Room{}
}
// AfterInit component lifetime callback
func (r *Room) AfterInit() {
r.timer = pitaya.NewTimer(time.Minute, func() {
count, err := pitaya.GroupCountMembers(context.Background(), "room")
logger.Log.Debugf("UserCount: Time=> %s, Count=> %d, Error=> %q", time.Now().String(), count, err)
})
}
// Join room
func (r *Room) Join(ctx context.Context, msg []byte) (*JoinResponse, error) {
s := pitaya.GetSessionFromCtx(ctx)
fakeUID := s.ID() // just use s.ID as uid !!!
err := s.Bind(ctx, strconv.Itoa(int(fakeUID))) // binding session uid
if err != nil {
return nil, pitaya.Error(err, "RH-000", map[string]string{"failed": "bind"})
}
uids, err := pitaya.GroupMembers(ctx, "room")
if err != nil {
return nil, err
}
s.Push("onMembers", &AllMembers{Members: uids})
// notify others
pitaya.GroupBroadcast(ctx, "chat", "room", "onNewUser", &NewUser{Content: fmt.Sprintf("New user: %s", s.UID())})
// new user join group
pitaya.GroupAddMember(ctx, "room", s.UID()) // add session to group
// on session close, remove it from group
s.OnClose(func() {
pitaya.GroupRemoveMember(ctx, "room", s.UID())
})
return &JoinResponse{Result: "success"}, nil
}
// Message sync last message to all members
func (r *Room) Message(ctx context.Context, msg *UserMessage) {
err := pitaya.GroupBroadcast(ctx, "chat", "room", "onMessage", msg)
if err != nil {
fmt.Println("error broadcasting message", err)
}
}
func main() {
defer pitaya.Shutdown()
s := json.NewSerializer()
conf := configApp()
pitaya.SetSerializer(s)
gsi := groups.NewMemoryGroupService(config.NewConfig(conf))
pitaya.InitGroups(gsi)
err := pitaya.GroupCreate(context.Background(), "room")
if err != nil {
panic(err)
}
// rewrite component and handler name
room := NewRoom()
pitaya.Register(room,
component.WithName("room"),
component.WithNameFunc(strings.ToLower),
)
log.SetFlags(log.LstdFlags | log.Llongfile)
http.Handle("/web/", http.StripPrefix("/web/", http.FileServer(http.Dir("web"))))
go http.ListenAndServe(":3251", nil)
t := acceptor.NewWSAcceptor(":3250")
pitaya.AddAcceptor(t)
pitaya.Configure(true, "chat", pitaya.Cluster, map[string]string{}, conf)
pitaya.Start()
}
func configApp() *viper.Viper {
conf := viper.New()
conf.SetEnvPrefix("chat") // allows using env vars in the CHAT_PITAYA_ format
conf.SetDefault("pitaya.buffer.handler.localprocess", 15)
conf.Set("pitaya.heartbeat.interval", "15s")
conf.Set("pitaya.buffer.agent.messages", 32)
conf.Set("pitaya.handler.messages测试数据pression", false)
return conf
}
查看更多关于golang -Pitaya 游戏服务器框架中文API教程的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did18513