From e1308a7ebe468fae570433783ec7547fab2e6665 Mon Sep 17 00:00:00 2001 From: vaporvee Date: Wed, 17 Apr 2024 01:48:18 +0200 Subject: [PATCH] added basic websocket broadcasting functionality --- project/.gitignore | 2 +- server/.env.example | 1 + server/.gitignore | 1 + server/cert.pem | 59 +++++++++++++++++++++++++++++++++ server/go.mod | 1 + server/go.sum | 2 ++ server/key.pem | 28 ++++++++++++++++ server/main.go | 79 ++++++++++++++++++--------------------------- 8 files changed, 124 insertions(+), 49 deletions(-) create mode 100644 server/.env.example create mode 100644 server/.gitignore create mode 100644 server/cert.pem create mode 100644 server/key.pem diff --git a/project/.gitignore b/project/.gitignore index 4709183..68462ed 100644 --- a/project/.gitignore +++ b/project/.gitignore @@ -1,2 +1,2 @@ # Godot 4+ specific ignores -.godot/ +.godot/ \ No newline at end of file diff --git a/server/.env.example b/server/.env.example new file mode 100644 index 0000000..2f304be --- /dev/null +++ b/server/.env.example @@ -0,0 +1 @@ +PORT="" \ No newline at end of file diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/server/cert.pem b/server/cert.pem new file mode 100644 index 0000000..571bcbb --- /dev/null +++ b/server/cert.pem @@ -0,0 +1,59 @@ +-----BEGIN CERTIFICATE----- +MIIE9DCCA9ygAwIBAgISBGWkqtdNCc+jeRTeb/d4fuTwMA0GCSqGSIb3DQEBCwUA +MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD +EwJSMzAeFw0yNDA0MTQxMjExMzRaFw0yNDA3MTMxMjExMzNaMBYxFDASBgNVBAMT +C2FjZWNvcmUubG9sMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwF4J +sM5tbCzv1jlCGZbVdOeCjr9uLZlN0rYmkVTfAsHZKEIlYgkq/cyR9Qo/aTqEHZ0+ +SsEZbVkHxRZqPjS/uWE8zmZKf9wBEJb84y2UvqvMhRAaxkbsMORca6yg2wa2DTZ4 +fz/KocuVHANF2wxh2+WlcauIYxNDVcva4juZpLQkyzecWW9Fa4uPML8FCnUvGQGx +H/eG2eZSopHtQiiIUt6TRrp/UVkEH48Cg0fGBe+M+PwcTKRPF5BSWnrHJR7vPme6 +0pow+NVP3kJgtPoT3pbh7V58DpBGgAupkaUnA0DWLPy4NRoS0jj4XkYPRAEKTnQ8 +g69UBjpxZzCYLNjCEQIDAQABo4ICHjCCAhowDgYDVR0PAQH/BAQDAgWgMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW +BBTS29cy4yP8aFUt/tpEYQneqMWT8zAfBgNVHSMEGDAWgBQULrMXt1hWy65QCUDm +H6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9yMy5v +LmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3JnLzAn +BgNVHREEIDAeggthY2Vjb3JlLmxvbIIPd3d3LmFjZWNvcmUubG9sMBMGA1UdIAQM +MAowCAYGZ4EMAQIBMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHYA7s3QZNXbGs7F +XLedtM0TojKHRny87N7DUUhZRnEftZsAAAGO3LwLbQAABAMARzBFAiAt08qhrle3 +cnP18fLYdGRLdM1lPTiCiM92RH+cBjp2YAIhAJFFvfQEyxzv+QAzh4IF0gxhdFSV +W6EFiZBGTxxWUKAsAHYAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcA +AAGO3LwLcQAABAMARzBFAiBIlK7hX9D7J3G8WUAbINIF9IFvVEh0BHmq0tyEi84E +EQIhAJ1he+XDjxi/7DITNh+KPYQQH/ZB9e4zZA207bHqOEBCMA0GCSqGSIb3DQEB +CwUAA4IBAQC3AqMVOts0LUAhKUkrpu4XPRwpVEVRw+3eg96T5nkTXpOyjEN2cHIv +EOh5E1fzj7KTbfykAb6VtCi0Sl+xgJaVVYRgbmqzTDIHt6TDRlhElTBTqknapRjN +3XwyXov+KhgrM0u2Pnhyk/n0ib8lRmWXPwnSNEYDJ9CFtWfIf6RFWMG1VGbUNgL1 +9U+GTiUDJIUL3mGx1SeqMPmR7fKTlwbJ7ez2Mat94JBdIh0i5PG5eTwCn7tpC9v8 +gsiOcPaORVvXyykwOHryQB5NqRzOAu+YVPsb6gOgfw6DRfAN71eJteePiPZL3BlP +NimyksnMKDH5qXK2oEnWYc6al7CUI0M5 +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- diff --git a/server/go.mod b/server/go.mod index 7679732..ec730c8 100644 --- a/server/go.mod +++ b/server/go.mod @@ -4,5 +4,6 @@ go 1.21.0 require ( github.com/gorilla/websocket v1.5.1 // indirect + github.com/joho/godotenv v1.5.1 // indirect golang.org/x/net v0.17.0 // indirect ) diff --git a/server/go.sum b/server/go.sum index 272772f..737d760 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,4 +1,6 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= diff --git a/server/key.pem b/server/key.pem new file mode 100644 index 0000000..307dbd0 --- /dev/null +++ b/server/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAXgmwzm1sLO/W +OUIZltV054KOv24tmU3StiaRVN8CwdkoQiViCSr9zJH1Cj9pOoQdnT5KwRltWQfF +Fmo+NL+5YTzOZkp/3AEQlvzjLZS+q8yFEBrGRuww5FxrrKDbBrYNNnh/P8qhy5Uc +A0XbDGHb5aVxq4hjE0NVy9riO5mktCTLN5xZb0Vri48wvwUKdS8ZAbEf94bZ5lKi +ke1CKIhS3pNGun9RWQQfjwKDR8YF74z4/BxMpE8XkFJaesclHu8+Z7rSmjD41U/e +QmC0+hPeluHtXnwOkEaAC6mRpScDQNYs/Lg1GhLSOPheRg9EAQpOdDyDr1QGOnFn +MJgs2MIRAgMBAAECggEAWqM0T7FDz2dw7e/2nBX8p2N5mYbLBAMqrvCSRYHGvgbW +KejYslN9hS4BS4KzlAI1Q7rWIeTP9Tyws4U3M+4os9EEFIAP9CSV/9oUd3n/jsNl +zwBijS/Xk8XVYgpplCmaV6llpxdIg2ln7VYBcQ9pgHG4vVFEJuJppKAzlsrcPsSt +M1oA36dCmHle0N2HCeKiHpN4gOd0PBq30+TbifGhrLfJ2VinMnlmffEJjIb132Si +41kpQP6orM/XJPkIv472MiwO6ZhgZte1RoK7cGVEB/VcG+04yaaOuyAQ6J0aOYR8 +XqbMAA9w7RLM6RnwmjVtyYVr/0A55xsyQW+GWdXKAQKBgQDicqV0hgAPmtVFpPfL +CWYfzAUUapuRC/czEdg6iIRjSS9Q+LjOtup3YpcTLZ0FWPzdgJoj6M4GhonHdLbO +Wb9zKzB4ThW0MJUX0mfxXM3C5rV6Y+JbAPdpaXQbW1BlySCWUBRCiGWLNvywIyR8 +QPwiFpj/34Kt4BxR8H0KYMSqcQKBgQDZeM1p5SiB5hGHf5alPuIb6sHGO2hNr8P/ +QKJbZT5GbcNEc2ipJAxEXkM5doJqmfmsA2Vn4viu5CyasTxkf6rQQUI+cy4LD4fw +O5slcUmJV1/oT1EHkcS7vy3xit5RsvpWmjfvPyCDOYsbjgDjOG0CjqnnkVQTtl7G +5E+W+MEhoQKBgQC4bonFgtIP45pqc7cCHfCYWzGT9FQp6aX3aUREQCYbO2MXPsw+ +SIpkm97R1ue5kEW7Hl/seVM7y13yHmQ5Yq1kXrvGcEqLDLqRwWO5GE3ZvM/4E9wr +JHld2G6hTVkI3av14Njva2nQ3gMmbijsLn1sQh1w4RjtBsfqEMW2qyPicQKBgCio +wlcDJkCrICniO+snR6UKjjIe11B3BUEK94/47NzEFtcMcMv21mhN62mp85Y0tY5o +kCQNNouUU5aUfoMXr3sCSH1ekYQ14ieTLV2hwarw8BiCA9dTdKHZi6B2YzyJJu7c +JIsRlWWTc6OyOA5DdXYd8DxAWqTY2v16oDrMxWchAoGBAK55a3Gqn1cgEPkirmfy +c9zCsX9BeM+fNkWpOb3B1sTt9oOQzx/X4k+uJ5aUnA+kr0iasB4Akgf41w3QPwrl +0cG3unctdSlpwA2Rx2NPHU+sDHzEdJBPvjndAFF+/gq9n7oPLyUQhpA3g6Mq0BMh +ZolMMzd24J4yz6a5BoF+7w6K +-----END PRIVATE KEY----- diff --git a/server/main.go b/server/main.go index bff705d..ae9cf6c 100644 --- a/server/main.go +++ b/server/main.go @@ -2,10 +2,11 @@ package main import ( "fmt" - "log" "net/http" + "os" "github.com/gorilla/websocket" + "github.com/joho/godotenv" ) var upgrader = websocket.Upgrader{ @@ -13,63 +14,45 @@ var upgrader = websocket.Upgrader{ WriteBufferSize: 1024, } -// UserToken represents a user token in the database. -type UserToken struct { - UserID string - Token string +var clients = make(map[*websocket.Conn]bool) // connected clients +var broadcast = make(chan []byte) // broadcast channel + +func main() { + godotenv.Load() + http.HandleFunc("/ws", handleConnections) + go handleMessages() + fmt.Println("Server running on " + os.Getenv("PORT")) + http.ListenAndServeTLS(os.Getenv("PORT"), "cert.pem", "key.pem", nil) } -// userTokens is a simple in-memory map for demonstration purposes. -var userTokens = make(map[string]UserToken) - -// generateItchOAuthURL generates an OAuth URL for itch.io. -func generateItchOAuthURL(clientID string) string { - return fmt.Sprintf("https://itch.io/user/oauth?client_id=%s&response_type=token", clientID) -} - -// redirectToItchOAuth sends the OAuth URL to the client. -func redirectToItchOAuth(conn *websocket.Conn, clientID string) { - oauthURL := generateItchOAuthURL(clientID) - err := conn.WriteMessage(websocket.TextMessage, []byte(oauthURL)) - if err != nil { - log.Println(err) - } -} - -// saveUserToken saves the user token in the database. -func saveUserToken(userID, token string) { - userTokens[userID] = UserToken{UserID: userID, Token: token} -} - -// handler handles WebSocket connections. -func handler(w http.ResponseWriter, r *http.Request) { +func handleConnections(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { - log.Println(err) + fmt.Println(err) return } defer conn.Close() - // Example client ID. Replace with your actual client ID. - clientID := "your_client_id_here" + clients[conn] = true - // Redirect the user to the OAuth URL. - redirectToItchOAuth(conn, clientID) - - // Simulate receiving the token from the client. - // In a real application, you would parse the token from the redirect URL. - userID := "example_user_id" - token := "example_token" - saveUserToken(userID, token) - - // Send a confirmation message to the client. - err = conn.WriteMessage(websocket.TextMessage, []byte("Token saved successfully.")) - if err != nil { - log.Println(err) + for { + _, msg, err := conn.ReadMessage() + if err != nil { + delete(clients, conn) + break + } + broadcast <- msg } } -func main() { - http.HandleFunc("/ws", handler) - log.Fatal(http.ListenAndServe(":8080", nil)) +func handleMessages() { + for { + msg := <-broadcast + for client := range clients { + if err := client.WriteMessage(websocket.TextMessage, msg); err != nil { + client.Close() + delete(clients, client) + } + } + } }