Last active
July 21, 2024 21:54
-
-
Save mrl22/a33e714b5ec941f1f4f8afac1064fadc to your computer and use it in GitHub Desktop.
Connect to Laravel Reverb from Golang for two-way communication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"github.com/gorilla/websocket" | |
"log" | |
"net/url" | |
"os" | |
"os/signal" | |
"syscall" | |
) | |
// I am a Go newbie, so please excuse my lack of knowledge, but this works. It sends and receives messages/events. | |
// I could not find a good example of how to connect to a Pusher WebSocket using Go, so I wrote this. | |
// Important configuration variables | |
var ( | |
webSocketScheme = "ws" // or "wss" for secure | |
webSocketHost = "localhost:8080" | |
webSocketPath = "/app/u9nyjqyzeyj4iy7qegnn" // REVERB_APP_KEY (dont remove /app/) | |
authToken = "ttlw5knw5xaqkwrocpno" // REVERB_APP_SECRET | |
authChannel = "test" // Channel configured in routes/channels.php | |
) | |
func main() { | |
u := url.URL{Scheme: webSocketScheme, Host: webSocketHost, Path: webSocketPath} | |
log.Printf("connecting to %s", u.String()) | |
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) | |
if err != nil { | |
log.Fatalf("dial error: %v", err) | |
} | |
defer c.Close() | |
// Authenticate if needed | |
authPayload := map[string]interface{}{ | |
"event": "pusher:subscribe", | |
"data": map[string]interface{}{ | |
"auth": authToken, | |
"channel": authChannel, | |
}, | |
} | |
authPayloadJSON, err := json.Marshal(authPayload) | |
if err != nil { | |
log.Fatalf("marshal auth error: %v", err) | |
} | |
err = c.WriteMessage(websocket.TextMessage, authPayloadJSON) | |
if err != nil { | |
log.Printf("write auth error: %v", err) | |
return | |
} | |
// Channel to receive messages | |
messageChan := make(chan []byte) | |
// Goroutine to read messages | |
go func() { | |
defer close(messageChan) | |
for { | |
_, message, err := c.ReadMessage() | |
if err != nil { | |
log.Printf("read error: %v", err) | |
return | |
} | |
messageChan <- message | |
} | |
}() | |
// Handle system signals for graceful shutdown | |
signalChan := make(chan os.Signal, 1) | |
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) | |
for { | |
select { | |
case message := <-messageChan: | |
log.Printf("recv: %s", message) | |
handlePing(c, message) | |
handleMessage(c, message) | |
case <-signalChan: | |
log.Println("shutdown signal received") | |
return | |
} | |
} | |
} | |
func handlePing(c *websocket.Conn, message []byte) { | |
// If the server sends a ping, we need to respond with a pong or we will be disconnected | |
if string(message) == `{"event":"pusher:ping"}` { | |
payload := `{"event":"pusher:pong","data":{}}` | |
err := c.WriteMessage(websocket.TextMessage, []byte(payload)) | |
if err != nil { | |
return | |
} | |
log.Println("sent: " + payload) | |
} | |
} | |
func handleMessage(c *websocket.Conn, message []byte) { | |
// Parse the incoming message | |
var msg map[string]interface{} | |
if err := json.Unmarshal(message, &msg); err != nil { | |
log.Printf("unmarshal error: %v", err) | |
return | |
} | |
// Handle events | |
//if event, ok := msg["event"].(string); ok { | |
// | |
//} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment