fix to Websockets, working player, working sync, working server

master
Evgeny Kovalev 1 year ago
parent 4f965ddefb
commit d7ea636fe4
  1. 24
      internal/gameServer/gameServer.go
  2. 25
      internal/player/player.go
  3. 19
      internal/room/room.go
  4. 35
      internal/server/server.go
  5. 38
      main.go

@ -24,11 +24,14 @@ type GameServer struct {
playerConns map[*player.Player]bool playerConns map[*player.Player]bool
// Notify Game Server a New Player // Notify Game Server a New Player
connection chan *player.Player Connection chan *player.Player
//Quit the loops correctly and shut down the Game Server //Quit the loops correctly and shut down the Game Server
Shutdown chan bool Shutdown chan bool
//1 Second Update planning
OneSecond chan bool
//sync threads //sync threads
WG sync.WaitGroup WG sync.WaitGroup
} }
@ -41,20 +44,37 @@ func (m *GameServer) Init(logger *utils.Logger, config *config.S_Config) {
m.maxPlayers = m.Config.MaxPlayers m.maxPlayers = m.Config.MaxPlayers
m.Shutdown = make(chan bool) m.Shutdown = make(chan bool)
m.OneSecond = make(chan bool)
m.currentLobbies = 0 m.currentLobbies = 0
m.currentPlayers = 0 m.currentPlayers = 0
m.WG.Add(1) m.Connection = make(chan *player.Player)
m.playerConns = make(map[*player.Player]bool)
m.WG.Add(2)
} }
func (m *GameServer) Update() { func (m *GameServer) Update() {
for { for {
select { select {
case pl := <-m.Connection:
m.playerConns[pl] = true
go pl.Receiver()
case <-m.Shutdown: case <-m.Shutdown:
m.ShutdownServer() m.ShutdownServer()
m.WG.Done() m.WG.Done()
case <-m.OneSecond:
fmt.Println("OneSecond yikes")
fmt.Println(m.playerConns)
default:
// default actions
} }
} }
} }

@ -1,12 +1,16 @@
package player package player
import "github.com/gorilla/websocket" import (
"fmt"
"github.com/gorilla/websocket"
)
type Player struct { type Player struct {
Name string `json:"Name"` Name string `json:"Name"`
Password string `json:"Password"` Password string `json:"Password"`
//Connection WS variable TODO //Connection
Conn *websocket.Conn Conn *websocket.Conn
AuthString string `json:"AuthString"` AuthString string `json:"AuthString"`
@ -22,3 +26,20 @@ type Player struct {
Health int `json:"Health"` Health int `json:"Health"`
} }
func (pc *Player) Receiver() {
for {
fmt.Println("ticker")
_, command, err := pc.Conn.ReadMessage()
if err != nil {
fmt.Println("pc err: " + err.Error())
}
pc.Conn.WriteMessage(websocket.TextMessage, []byte("otvet"))
fmt.Println(command)
}
}

@ -52,15 +52,16 @@ func (r *Room) TextAnnounce() {
func (r *Room) Update() { func (r *Room) Update() {
for { for {
select { /*
case pj := <-r.join: select {
// player joins case pj := <-r.join:
case pl := <-r.leave: // player joins
// player leaves case pl := <-r.leave:
case <-r.updateAll: // player leaves
// update the room case <-r.updateAll:
} // update the room
}
*/
} }
} }

@ -6,10 +6,13 @@ import (
"log" "log"
"net/http" "net/http"
"daydev.org/shipsgs/internal/gameServer"
"daydev.org/shipsgs/internal/player" "daydev.org/shipsgs/internal/player"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
) )
var GS *gameServer.GameServer
type Health struct { type Health struct {
Health string `json:"Health"` Health string `json:"Health"`
Lobbies int `json:"Lobbies"` Lobbies int `json:"Lobbies"`
@ -40,24 +43,28 @@ func wsEndpoint(w http.ResponseWriter, r *http.Request) {
return return
} }
player := player.Player{ player := &player.Player{
Conn: conn, Conn: conn,
} }
player.Name = "Yale" player.Name = "Yale"
log.Println(r.RemoteAddr) GS.Connection <- player
for { /*
messageType, p, err := conn.ReadMessage() log.Println(r.RemoteAddr)
if err != nil {
log.Println(err) for {
return messageType, p, err := conn.ReadMessage()
} if err != nil {
if err := conn.WriteMessage(messageType, p); err != nil { log.Println(err)
log.Println(err) return
return }
if err := conn.WriteMessage(messageType, p); err != nil {
log.Println(err)
return
}
} }
} */
} }
@ -67,9 +74,11 @@ func setupRoutes() {
} }
func SetupAndRun(port string, sighup *chan bool) { func SetupAndRun(port string, sighup *chan bool, gs *gameServer.GameServer) {
setupRoutes() setupRoutes()
GS = gs
srv := &http.Server{Addr: port} srv := &http.Server{Addr: port}
go func() { go func() {

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log" "log"
"os" "os"
"time"
"daydev.org/shipsgs/internal/config" "daydev.org/shipsgs/internal/config"
"daydev.org/shipsgs/internal/gameServer" "daydev.org/shipsgs/internal/gameServer"
@ -15,6 +16,9 @@ import (
var Logger *utils.Logger var Logger *utils.Logger
var ch_sighup *chan bool var ch_sighup *chan bool
//channel to shutdown oneSecUpdater
var ch_oneSecUpdaterShutdown chan bool
//GameServer Public Global Instance //GameServer Public Global Instance
var GS *gameServer.GameServer var GS *gameServer.GameServer
@ -33,6 +37,8 @@ func main() {
sighup := make(chan bool) sighup := make(chan bool)
ch_sighup = &sighup ch_sighup = &sighup
ch_oneSecUpdaterShutdown = make(chan bool)
//If debug - fill Stdout too - LOG to use? //If debug - fill Stdout too - LOG to use?
//Logger = utils.New(os.Stdout, utils.LevelInfo) //Logger = utils.New(os.Stdout, utils.LevelInfo)
@ -42,10 +48,15 @@ func main() {
GS.Init(Logger, &config.Config) GS.Init(Logger, &config.Config)
go GS.Update() go GS.Update()
//Starting oneSecUpdater after GameServer is ready, because oneSecUpdater
// is depending on GameServer.Shutdown channel which
// is IF uninitialized we will get "invalid memory address or nil pointer dereference"
go oneSecUpdater()
log.Println("Starting Healthy") log.Println("Starting Healthy")
//closer.Hold() //closer.Hold()
server.SetupAndRun(":8080", ch_sighup) server.SetupAndRun(":8080", ch_sighup, GS)
GS.WG.Wait() GS.WG.Wait()
@ -54,6 +65,9 @@ func main() {
func cleanup() { func cleanup() {
fmt.Println("Shutting down ") fmt.Println("Shutting down ")
//Shutting down oneSecUpdater
ch_oneSecUpdaterShutdown <- true
//Investigate why no messages on correct closing //Investigate why no messages on correct closing
GS.Shutdown <- true GS.Shutdown <- true
@ -65,3 +79,25 @@ func cleanup() {
}) })
} }
func oneSecUpdater() {
//The intention here is to awake after 1 second and send an update to GameServer to update everything
for {
select {
case <-ch_oneSecUpdaterShutdown:
fmt.Println("Shutdown One Sec Updater")
GS.WG.Done()
// Goroutine will wait untill the DEFAULT: will happen before shutdown will take
// any effect
case <-time.After(time.Second * 1):
fmt.Println("1 Sec Timer")
default:
//*** maybe try this 10 secs in a CASE segment ?
// This blocks whole goroutine
<-time.After(time.Second * 2)
GS.OneSecond <- true
}
}
}

Loading…
Cancel
Save