/
dispatchercluster.go
153 lines (128 loc) · 4.99 KB
/
dispatchercluster.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
145
146
147
148
149
150
151
152
153
package dispatchercluster
import (
"time"
"github.com/xiaonanln/goworld/engine/common"
"github.com/xiaonanln/goworld/engine/config"
"github.com/xiaonanln/goworld/engine/dispatchercluster/dispatcherclient"
"github.com/xiaonanln/goworld/engine/gwlog"
"github.com/xiaonanln/goworld/engine/gwutils"
"github.com/xiaonanln/goworld/engine/netutil"
"github.com/xiaonanln/goworld/engine/proto"
)
var (
dispatcherConns []*dispatcherclient.DispatcherConnMgr
dispatcherNum int
gid uint16
)
func Initialize(_gid uint16, dctype dispatcherclient.DispatcherClientType, isRestoreGame, isBanBootEntity bool, delegate dispatcherclient.IDispatcherClientDelegate) {
gid = _gid
dispIds := config.GetDispatcherIDs()
dispatcherNum = len(dispIds)
dispatcherConns = make([]*dispatcherclient.DispatcherConnMgr, dispatcherNum)
for _, dispid := range dispIds {
dispatcherConns[dispid-1] = dispatcherclient.NewDispatcherConnMgr(gid, dctype, dispid, isRestoreGame, isBanBootEntity, delegate)
}
for _, dispConn := range dispatcherConns {
dispConn.Connect()
}
go gwutils.RepeatUntilPanicless(autoFlushRoutine)
}
func SendNotifyDestroyEntity(id common.EntityID) error {
return SelectByEntityID(id).SendNotifyDestroyEntity(id)
}
func SendDeclareService(id common.EntityID, serviceName string) error {
return SelectByEntityID(id).SendDeclareService(id, serviceName)
}
func SendClearClientFilterProp(gateid uint16, clientid common.ClientID) (err error) {
return SelectByGateID(gateid).SendClearClientFilterProp(gateid, clientid)
}
func SendSetClientFilterProp(gateid uint16, clientid common.ClientID, key, val string) (err error) {
return SelectByGateID(gateid).SendSetClientFilterProp(gateid, clientid, key, val)
}
func SendMigrateRequest(entityID common.EntityID, spaceID common.EntityID, spaceGameID uint16) error {
return SelectByEntityID(entityID).SendMigrateRequest(entityID, spaceID, spaceGameID)
}
func SendRealMigrate(eid common.EntityID, targetGame uint16, targetSpace common.EntityID, x, y, z float32,
typeName string, migrateData map[string]interface{}, timerData []byte, clientid common.ClientID, clientsrv uint16) error {
return SelectByEntityID(eid).SendRealMigrate(eid, targetGame, targetSpace, x, y, z, typeName, migrateData, timerData, clientid, clientsrv)
}
func SendCallFilterClientProxies(op proto.FilterClientsOpType, key, val string, method string, args []interface{}) (anyerror error) {
for _, dcm := range dispatcherConns {
err := dcm.GetDispatcherClientForSend().SendCallFilterClientProxies(op, key, val, method, args)
if err != nil && anyerror == nil {
anyerror = err
}
}
return
}
func SendNotifyCreateEntity(id common.EntityID) error {
return SelectByEntityID(id).SendNotifyCreateEntity(id)
}
func SendLoadEntityAnywhere(typeName string, entityID common.EntityID) error {
return SelectByEntityID(entityID).SendLoadEntityAnywhere(typeName, entityID)
}
func SendCreateEntityAnywhere(entityid common.EntityID, typeName string, data map[string]interface{}) error {
return SelectByEntityID(entityid).SendCreateEntityAnywhere(entityid, typeName, data)
}
func SendStartFreezeGame(gameid uint16) (anyerror error) {
for _, dcm := range dispatcherConns {
err := dcm.GetDispatcherClientForSend().SendStartFreezeGame(gameid)
if err != nil {
anyerror = err
}
}
return
}
func SendCallNilSpaces(exceptGameID uint16, method string, args []interface{}) (anyerror error) {
// construct one packet for multiple sending
packet := netutil.NewPacket()
packet.AppendUint16(proto.MT_CALL_NIL_SPACES)
packet.AppendUint16(exceptGameID)
packet.AppendVarStr(method)
packet.AppendArgs(args)
for _, dcm := range dispatcherConns {
err := dcm.GetDispatcherClientForSend().SendPacket(packet)
if err != nil {
anyerror = err
}
}
packet.Release()
return
}
func EntityIDToDispatcherID(entityid common.EntityID) uint16 {
return uint16((hashEntityID(entityid) % dispatcherNum) + 1)
}
func SelectByEntityID(entityid common.EntityID) *dispatcherclient.DispatcherClient {
idx := hashEntityID(entityid) % dispatcherNum
return dispatcherConns[idx].GetDispatcherClientForSend()
}
func SelectByGateID(gateid uint16) *dispatcherclient.DispatcherClient {
idx := hashGateID(gateid) % dispatcherNum
return dispatcherConns[idx].GetDispatcherClientForSend()
}
func SelectByDispatcherID(dispid uint16) *dispatcherclient.DispatcherClient {
return dispatcherConns[dispid-1].GetDispatcherClientForSend()
}
func Select(dispidx int) *dispatcherclient.DispatcherClient {
return dispatcherConns[dispidx].GetDispatcherClientForSend()
}
//func Flush(reason string) (anyerror error) {
// for _, dispconn := range dispatcherConns {
// err := dispconn.GetDispatcherClientForSend().Flush(reason)
// if err != nil {
// anyerror = err
// }
// }
// return
//}
func autoFlushRoutine() {
for {
time.Sleep(10 * time.Millisecond)
for _, dispconn := range dispatcherConns {
err := dispconn.GetDispatcherClientForSend().Flush("dispatchercluster")
if err != nil {
gwlog.Errorf("dispatchercluster: %s flush failed: %v", dispconn, err)
}
}
}
}