-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.go
145 lines (114 loc) · 2.96 KB
/
server.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
package goreal
import (
"fmt"
"log"
"net/http"
)
//Game server manager.
type GameServer struct {
// running port
Port int16
// all rooms in game server
rooms map[string]*RoomManager
clientRoom map[*Client]string
// handle client's first connection
InitClient func(w http.ResponseWriter, r *http.Request, client *Client)
}
// create a new server
func NewGameServer(port int16) *GameServer {
server := &GameServer{Port: port}
server.rooms = make(map[string]*RoomManager)
server.clientRoom = make(map[*Client]string)
server.init()
return server
}
func (gs *GameServer) init() {
}
func (gs *GameServer) Start() {
log.Println("server starting..")
hub := newHub()
go hub.run(gs)
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
log.Println("ws request detected")
//client connection starting
client := serveWs(hub, w, r)
if client == nil {
panic("something went wrong.")
}
if gs.InitClient != nil {
gs.InitClient(w, r, client)
}
})
// connection string addr:port
connectionString := fmt.Sprintf(":%d", gs.Port)
err := http.ListenAndServe(connectionString, nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
// add room to server
func (gs *GameServer) RegisterRoom(path string, roomInterface interface{}) {
// gs.rooms[path] = room
if roomInterface == nil {
log.Println("room instance not null")
return
}
roomEvents, ok := roomInterface.(RoomEvents)
if !ok {
log.Printf("wrong room type")
panic("wrong room type")
return
}
if _, ok := gs.rooms[path]; ok {
log.Println("Room already created. {}", path)
return
}
roomManager := newRoomManager(path, roomEvents)
gs.rooms[path] = roomManager
gs.bootstrapRoom(roomManager)
}
func (gs *GameServer) bootstrapRoom(roomManager *RoomManager) {
roomManager.OnInit(gs)
roomManager.RoomEvents.OnInit()
go roomManager.run()
}
// change the client's room
func (gs *GameServer) JoinRoom(roomName string, client *Client) bool {
// todo check if room created
// todo if client is another room, must be leave current room
room, ok := gs.rooms[roomName]
if !ok {
log.Printf("Room not found! %s", roomName)
return false
}
canJoin := room.CanJoinTheRoom(client)
if !canJoin {
log.Println("Room is not available for client")
return false
}
// send client to room information
//client.SendMessageStr("{\"join_room\":\"" + roomName + "\"}")
// keep clients room
gs.clientRoom[client]=roomName
room.AddClientToRoom(client)
return true
}
func (gs *GameServer) LeaveFromRoom(client *Client, room *Room ) {
client.RemoveListener(room)
}
// client disconnect unexpectedly
func (gs *GameServer) DisconnectClient(client *Client) {
log.Println("Client disconnected unexpectedly")
roomName, ok := gs.clientRoom[client]
if !ok {
// client not be found any room
log.Println("client not be found any room")
return
}
room, isFound := gs.rooms[roomName]
if !isFound {
log.Printf("%s room not found.", roomName)
return
}
room.DisconnectClient(client)
}