Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: code cleanup #12

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 3 additions & 19 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,18 @@ type Database struct {
conn *sql.DB
}

type Websocket struct {
Address string `json:"address"`
Timestamp int64 `json:"timestamp_online_since"`
Secret string `json:"secret"`
}

func NewWebsocket(address string, timestamp int64, secret string) *Websocket {
websocket := new(Websocket)

websocket.Address = address
websocket.Timestamp = timestamp
websocket.Secret = secret

return websocket
}

func NewDatabase() (*Database, error) {
database := new(Database)
d := new(Database)

db, err := sql.Open("mysql", dbUser+":"+dbPassword+"@tcp("+dbAddress+":"+dbPort+")/"+dbName)

if err != nil {
return nil, err
}

database.conn = db
d.conn = db

return database, err
return d, err
}

func (database Database) insertWebsocket(websocket Websocket) error {
Expand Down
26 changes: 26 additions & 0 deletions response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

type Response struct {
Error bool `json:"error"`
Message *string `json:"message"`
Method *string `json:"method"`
Data *map[string]interface{} `json:"data"`
}

func NewResponse(error bool, message string, method string, data *map[string]interface{}) *Response {
response := new(Response)

response.Error = error

if len(message) > 0 {
response.Message = &message
}

if len(method) > 0 {
response.Method = &method
}

response.Data = data

return response
}
17 changes: 17 additions & 0 deletions websocket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

type Websocket struct {
Address string `json:"address"`
Timestamp int64 `json:"timestamp_online_since"`
Secret string `json:"secret"`
}

func NewWebsocket(address string, timestamp int64, secret string) *Websocket {
websocket := new(Websocket)

websocket.Address = address
websocket.Timestamp = timestamp
websocket.Secret = secret

return websocket
}
138 changes: 56 additions & 82 deletions websocket_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,10 @@ var wsUpgrader = websocket.Upgrader{
WriteBufferSize: 1024,
}

var connections []*websocket.Conn
var backendConnections []*websocket.Conn

type WebsocketHandler struct {
backendKey string
}

type Response struct {
Error bool `json:"error"`
Message *string `json:"message"`
Method *string `json:"method"`
Data *map[string]interface{} `json:"data"`
}

func NewResponse(error bool, message string, method string, data *map[string]interface{}) *Response {
response := new(Response)

response.Error = error

if len(message) > 0 {
response.Message = &message
}

if len(method) > 0 {
response.Method = &method
}

response.Data = data

return response
backendKey string
connections []*websocket.Conn
backendConnections []*websocket.Conn
}

func NewWebsocketHandler() *WebsocketHandler {
Expand All @@ -55,38 +29,38 @@ func NewWebsocketHandler() *WebsocketHandler {
return handler
}

func (websocketHandler WebsocketHandler) handler(c *gin.Context) {
func (w *WebsocketHandler) handler(c *gin.Context) {
conn, err := wsUpgrader.Upgrade(c.Writer, c.Request, nil)

if err != nil {
fmt.Printf("failed to set websocket upgrade: %+v\n", err)
return
}

connections = append(connections, conn)
websocketHandler.log("new connection", 200, time.Now(), c.ClientIP())
w.connections = append(w.connections, conn)
w.log("new connection", 200, time.Now(), c.ClientIP())

for {
t, bytes, err := conn.ReadMessage()

since := time.Now()

if t != websocket.TextMessage {
err = websocketHandler.sendResponse(conn, NewResponse(true, "message must be textmessage", "", nil))
websocketHandler.log("", 400, since, c.ClientIP())
err = w.sendResponse(conn, NewResponse(true, "message must be textmessage", "", nil))
w.log("", 400, since, c.ClientIP())
return
}

var body map[string]interface{}
err = json.Unmarshal(bytes, &body)

if err != nil {
err = websocketHandler.sendResponse(conn, NewResponse(true, "could not parse json body", "", nil))
websocketHandler.log("", 400, since, c.ClientIP())
err = w.sendResponse(conn, NewResponse(true, "could not parse json body", "", nil))
w.log("", 400, since, c.ClientIP())
return
}

method, err := websocketHandler.methodHandler(conn, body)
method, err := w.methodHandler(conn, body)

status := 0

Expand All @@ -96,11 +70,11 @@ func (websocketHandler WebsocketHandler) handler(c *gin.Context) {
status = 400
}

websocketHandler.log(method, status, since, c.ClientIP())
w.log(method, status, since, c.ClientIP())

if err != nil {
connections = remove(connections, conn)
backendConnections = remove(backendConnections, conn)
w.connections = remove(w.connections, conn)
w.backendConnections = remove(w.backendConnections, conn)

err = conn.Close()

Expand All @@ -113,7 +87,7 @@ func (websocketHandler WebsocketHandler) handler(c *gin.Context) {
}
}

func (websocketHandler WebsocketHandler) sendResponse(conn *websocket.Conn, response *Response) error {
func (w *WebsocketHandler) sendResponse(conn *websocket.Conn, response *Response) error {
dataBytes, err := json.Marshal(response)

if err != nil {
Expand All @@ -123,102 +97,112 @@ func (websocketHandler WebsocketHandler) sendResponse(conn *websocket.Conn, resp
return conn.WriteMessage(websocket.TextMessage, dataBytes)
}

func (websocketHandler WebsocketHandler) methodHandler(conn *websocket.Conn, body map[string]interface{}) (string, error) {
func (w *WebsocketHandler) methodHandler(conn *websocket.Conn, body map[string]interface{}) (string, error) {
if body["method"] == nil {
return "", websocketHandler.sendResponse(conn, NewResponse(true, "no method in json body", "", nil))
return "", w.sendResponse(conn, NewResponse(true, "no method in json body", "", nil))
}

method, s := body["method"].(string)

if !s {
return "", websocketHandler.sendResponse(conn, NewResponse(true, "method is not a string", "", nil))
return "", w.sendResponse(conn, NewResponse(true, "method is not a string", "", nil))
}

switch method {
case "login":
return method, websocketHandler.loginMethod(conn, body)
return method, w.loginMethod(conn, body)
case "broadcast":
return method, websocketHandler.broadcastMethod(conn, body)
return method, w.broadcastMethod(conn, body)
case "count":
return method, websocketHandler.countMethod(conn)
return method, w.countMethod(conn)
}

return method, websocketHandler.sendResponse(conn, NewResponse(true, "could not find method", method, nil))
return method, w.sendResponse(conn, NewResponse(true, "could not find method", method, nil))
}

func (websocketHandler WebsocketHandler) loginMethod(conn *websocket.Conn, body map[string]interface{}) error {
func (w *WebsocketHandler) loginMethod(conn *websocket.Conn, body map[string]interface{}) error {
if body["key"] == nil {
return websocketHandler.sendResponse(conn, NewResponse(true, "no key in json body", "login", nil))
return w.sendResponse(conn, NewResponse(true, "no key in json body", "login", nil))
}

key, s := body["key"].(string)

if !s {
return websocketHandler.sendResponse(conn, NewResponse(true, "key is not a string", "login", nil))
return w.sendResponse(conn, NewResponse(true, "key is not a string", "login", nil))
}

if key != websocketHandler.backendKey {
return websocketHandler.sendResponse(conn, NewResponse(true, "key is not correct", "login", nil))
if key != w.backendKey {
return w.sendResponse(conn, NewResponse(true, "key is not correct", "login", nil))
}

connections = remove(connections, conn)
backendConnections = append(backendConnections, conn)
w.connections = remove(w.connections, conn)
w.backendConnections = append(w.backendConnections, conn)

return websocketHandler.sendResponse(conn, NewResponse(false, "backend logged in", "login", nil))
return w.sendResponse(conn, NewResponse(false, "backend logged in", "login", nil))
}

func (websocketHandler WebsocketHandler) broadcastMethod(conn *websocket.Conn, body map[string]interface{}) error {
connectionIsBackend := websocketHandler.connectionIsBackend(conn)
func (w *WebsocketHandler) broadcastMethod(conn *websocket.Conn, body map[string]interface{}) error {
connectionIsBackend := w.connectionIsBackend(conn)

if !connectionIsBackend {
return websocketHandler.sendResponse(conn, NewResponse(true, "only backend is allowed to broadcast", "broadcast", nil))
return w.sendResponse(conn, NewResponse(true, "only backend is allowed to broadcast", "broadcast", nil))
}

if body["data"] == nil {
return websocketHandler.sendResponse(conn, NewResponse(true, "no data in json body", "broadcast", nil))
return w.sendResponse(conn, NewResponse(true, "no data in json body", "broadcast", nil))
}

data, s := body["data"].(map[string]interface{})

if !s {
return websocketHandler.sendResponse(conn, NewResponse(true, "data is not json object", "broadcast", nil))
return w.sendResponse(conn, NewResponse(true, "data is not json object", "broadcast", nil))
}

dataBytes, err := json.Marshal(data)

if err != nil {
return websocketHandler.sendResponse(conn, NewResponse(true, "failed to stringify data json", "broadcast", nil))
return w.sendResponse(conn, NewResponse(true, "failed to stringify data json", "broadcast", nil))
}

for _, c := range connections {
for _, c := range w.connections {
err = c.WriteMessage(websocket.TextMessage, dataBytes)

if err != nil {
connections = remove(connections, c)
w.connections = remove(w.connections, c)
}

err = nil
}

return websocketHandler.sendResponse(conn, NewResponse(false, "broadcasted message", "broadcast", nil))
return w.sendResponse(conn, NewResponse(false, "broadcasted message", "broadcast", nil))
}

func (websocketHandler WebsocketHandler) countMethod(conn *websocket.Conn) error {
connectionIsBackend := websocketHandler.connectionIsBackend(conn)
func (w *WebsocketHandler) countMethod(conn *websocket.Conn) error {
connectionIsBackend := w.connectionIsBackend(conn)

if !connectionIsBackend {
return websocketHandler.sendResponse(conn, NewResponse(true, "only backend is allowed to count", "count", nil))
return w.sendResponse(conn, NewResponse(true, "only backend is allowed to count", "count", nil))
}

response := make(map[string]interface{})

response["connectionCount"] = len(connections)
response["backendConnectionCount"] = len(backendConnections)
response["connectionCount"] = len(w.connections)
response["backendConnectionCount"] = len(w.backendConnections)

return w.sendResponse(conn, NewResponse(false, "connections count", "count", &response))
}

func (w *WebsocketHandler) connectionIsBackend(conn *websocket.Conn) bool {
for _, c := range w.backendConnections {
if c == conn {
return true
}
}

return websocketHandler.sendResponse(conn, NewResponse(false, "connections count", "count", &response))
return false
}

func (websocketHandler WebsocketHandler) log(method string, statusCode int, since time.Time, clientIp string) {
func (w *WebsocketHandler) log(method string, statusCode int, since time.Time, clientIp string) {
param := new(gin.LogFormatterParams)
param.Path = method
param.Method = http.MethodGet
Expand Down Expand Up @@ -247,13 +231,3 @@ func (websocketHandler WebsocketHandler) log(method string, statusCode int, sinc
param.ErrorMessage,
))
}

func (websocketHandler WebsocketHandler) connectionIsBackend(conn *websocket.Conn) bool {
for _, c := range backendConnections {
if c == conn {
return true
}
}

return false
}