forked from topfreegames/pitaya
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
144 lines (118 loc) · 3.64 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package main
import (
"context"
"fmt"
"log"
"net/http"
"strconv"
"time"
"strings"
"github.com/topfreegames/pitaya/v2"
"github.com/topfreegames/pitaya/v2/acceptor"
"github.com/topfreegames/pitaya/v2/component"
"github.com/topfreegames/pitaya/v2/config"
"github.com/topfreegames/pitaya/v2/groups"
"github.com/topfreegames/pitaya/v2/logger"
"github.com/topfreegames/pitaya/v2/timer"
)
type (
// Room represents a component that contains a bundle of room related handler
// like Join/Message
Room struct {
component.Base
timer *timer.Timer
app pitaya.Pitaya
}
// 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(app pitaya.Pitaya) *Room {
return &Room{
app: app,
}
}
// AfterInit component lifetime callback
func (r *Room) AfterInit() {
r.timer = pitaya.NewTimer(time.Minute, func() {
count, err := r.app.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 := r.app.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 := r.app.GroupMembers(ctx, "room")
if err != nil {
return nil, err
}
s.Push("onMembers", &AllMembers{Members: uids})
// notify others
r.app.GroupBroadcast(ctx, "chat", "room", "onNewUser", &NewUser{Content: fmt.Sprintf("New user: %s", s.UID())})
// new user join group
r.app.GroupAddMember(ctx, "room", s.UID()) // add session to group
// on session close, remove it from group
s.OnClose(func() {
r.app.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 := r.app.GroupBroadcast(ctx, "chat", "room", "onMessage", msg)
if err != nil {
fmt.Println("error broadcasting message", err)
}
}
var app pitaya.Pitaya
func main() {
conf := configApp()
builder := pitaya.NewDefaultBuilder(true, "chat", pitaya.Cluster, map[string]string{}, *conf)
builder.AddAcceptor(acceptor.NewWSAcceptor(":3250"))
builder.Groups = groups.NewMemoryGroupService(*config.NewDefaultMemoryGroupConfig())
app = builder.Build()
defer app.Shutdown()
err := app.GroupCreate(context.Background(), "room")
if err != nil {
panic(err)
}
// rewrite component and handler name
room := NewRoom(app)
app.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)
app.Start()
}
func configApp() *config.BuilderConfig {
conf := config.NewDefaultBuilderConfig()
conf.Pitaya.Buffer.Handler.LocalProcess = 15
conf.Pitaya.Heartbeat.Interval = time.Duration(15 * time.Second)
conf.Pitaya.Buffer.Agent.Messages = 32
conf.Pitaya.Handler.Messages.Compression = false
return conf
}