Skip to content
This repository has been archived by the owner on Oct 30, 2022. It is now read-only.

Commit

Permalink
some code refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
roby2014 committed Mar 1, 2022
1 parent 3c5f810 commit cd4a71f
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 62 deletions.
4 changes: 2 additions & 2 deletions controller/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ func Login(w http.ResponseWriter, r *http.Request) {
// login success
user, err := opId.ValidateAndGetUser(config.STEAM_API_KEY)
if err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{http.StatusInternalServerError, err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusInternalServerError, err.Error()))
return
}

if err = CreateSteamUser(user); err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{http.StatusInternalServerError, err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusInternalServerError, err.Error()))
return
}

Expand Down
2 changes: 1 addition & 1 deletion controller/player.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func GetPlayerStats(w http.ResponseWriter, r *http.Request) {

player, err := model.GetPlayerStats(mux.Vars(r)["steamid"])
if err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{Code: http.StatusNotFound, ErrorMsg: err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusNotFound, err.Error()))
return
}

Expand Down
8 changes: 4 additions & 4 deletions controller/steam_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func GetSteamUser(w http.ResponseWriter, r *http.Request) {

player, err := model.GetSteamUser(mux.Vars(r)["steamid"])
if err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{Code: http.StatusNotFound, ErrorMsg: err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusNotFound, err.Error()))
return
}

Expand All @@ -39,13 +39,13 @@ func UpdateSteamUser(w http.ResponseWriter, r *http.Request) {

exists, err := model.DoesSteamUserExist(steamID)
if err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{Code: http.StatusInternalServerError, ErrorMsg: err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusInternalServerError, err.Error()))
return
}

updatedUser, err := steam_go.GetPlayerSummaries(steamID, config.STEAM_API_KEY)
if err != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{Code: http.StatusInternalServerError, ErrorMsg: err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusInternalServerError, err.Error()))
return
}

Expand All @@ -58,7 +58,7 @@ func UpdateSteamUser(w http.ResponseWriter, r *http.Request) {
}

if result != nil {
utils.APIErrorRespond(w, utils.ErrorResponse{Code: http.StatusInternalServerError, ErrorMsg: err.Error()})
utils.APIErrorRespond(w, utils.NewAPIError(http.StatusInternalServerError, err.Error()))
return
}

Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ func setupRouter() {
// player stats
router.HandleFunc("/api/playerstats/{steamid}", controller.GetPlayerStats).Methods("GET")

// create rooms and run them (TODO: database integration)
// create rooms and run them (TODO: database rooms integration)
for _, uid := range []uint{1, 2, 3, 4, 5} {
newRoom := websocket.NewRoom(uid)
roomRoute := fmt.Sprintf("/chat/%d", uid)
router.HandleFunc(roomRoute, newRoom.ServeHTTP)
router.HandleFunc(roomRoute, newRoom.HandleWebsocket)
go newRoom.Run()
}
}
7 changes: 7 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ type ErrorResponse struct {
ErrorMsg string
}

func NewAPIError(c int, m string) ErrorResponse {
return ErrorResponse{
Code: c,
ErrorMsg: m,
}
}

// Error response in JSON format
func APIErrorRespond(w http.ResponseWriter, res ErrorResponse) {
w.Header().Set("Content-Type", "application/json")
Expand Down
11 changes: 10 additions & 1 deletion websocket/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@ import "github.com/gorilla/websocket"

type Client struct {
socket *websocket.Conn
send chan []byte
room *Room
send chan []byte
}

// Create new client
func newClient(s *websocket.Conn, r *Room) *Client {
return &Client{
socket: s,
room: r,
send: make(chan []byte, messageBufferSize),
}
}

// Read client messages (from frontend)
Expand Down
84 changes: 32 additions & 52 deletions websocket/room.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,37 @@ import (
"github.com/gorilla/websocket"
)

const (
socketBufferSize = 1024
messageBufferSize = 256
)

// Room represents a single chat room
type Room struct {
id uint
clients map[*Client]bool
forward chan []byte
join chan *Client
leave chan *Client
clients map[*Client]bool
}

const (
socketBufferSize = 1024
messageBufferSize = 256
)

var upgrader = &websocket.Upgrader{
ReadBufferSize: socketBufferSize,
WriteBufferSize: socketBufferSize,
CheckOrigin: func(r *http.Request) bool {
// TODO: change origin to frontend
return true
},
}

func (room *Room) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// create socket to client
socket, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}

// create new user
client := &Client{
socket: socket,
send: make(chan []byte, messageBufferSize),
room: room,
}

// join the room
room.join <- client

// executed at end of this function
defer func() {
room.leave <- client
}()

// run write and read function in 2 separate goroutines
go client.write()
client.read()
}

// Create a new chat room
func NewRoom(uid uint) *Room {
func NewRoom(id uint) *Room {
return &Room{
id: id,
clients: make(map[*Client]bool),
forward: make(chan []byte),
join: make(chan *Client),
leave: make(chan *Client),
clients: make(map[*Client]bool),
id: uid,
}
}

Expand All @@ -72,23 +46,12 @@ func (r *Room) Run() {
log.Printf("running chat room %d", r.id)
for {
select {
case Client := <-r.join:
r.joinRoom(Client)
case Client := <-r.leave:
r.leaveRoom(Client)
case client := <-r.join:
r.joinRoom(client)
case client := <-r.leave:
r.leaveRoom(client)
case msg := <-r.forward:
data := FromJSON(msg)
log.Printf("Client '%v' writing message to room %v, message: %v", data.Sender, r.id, data.Message)

// broadcast message to all
for client := range r.clients {
select {
case client.send <- msg:
default:
delete(r.clients, client)
close(client.send)
}
}
r.printToChatAll(msg)
}
}
}
Expand All @@ -105,3 +68,20 @@ func (r *Room) leaveRoom(c *Client) {
delete(r.clients, c)
close(c.send)
}

// Print message to all in the current room
func (r *Room) printToChatAll(msg []byte) {
data := FromJSON(msg)
log.Printf("[room %v] %v: %v", r.id, data.Sender, data.Message)

for client := range r.clients {
select {
case client.send <- msg:
log.Println("client.send <- msg")
default:
// not sure if this is possible
delete(r.clients, client)
close(client.send)
}
}
}
26 changes: 26 additions & 0 deletions websocket/server.go
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
package websocket

import "net/http"

// /api/rooms/{room_id} - create a client websocket, associating it with a room
func (room *Room) HandleWebsocket(w http.ResponseWriter, r *http.Request) {
// create client socket
socket, err := upgrader.Upgrade(w, r, nil)
if err != nil {
return
}

// create new client associated to a room
client := newClient(socket, room)

// join the room
room.join <- client

// executed at end of this function (after goroutines stop)
defer func() {
room.leave <- client
}()

// run write and read in 2 separate goroutines
go client.write()
client.read()
}

0 comments on commit cd4a71f

Please sign in to comment.