event subscribing

alpha
alex 2022-12-18 00:45:18 +01:00
parent cf5e6a2904
commit 4dc3840f67
6 changed files with 124 additions and 31 deletions

View File

@ -4,11 +4,12 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"time" "time"
"clickandjoin.app/websocketserver/modules/config" "clickandjoin.app/websocketserver/modules/config"
"clickandjoin.app/websocketserver/modules/structs" "clickandjoin.app/websocketserver/modules/structs"
"clickandjoin.app/websocketserver/modules/utils"
"clickandjoin.app/websocketserver/socketclients"
"github.com/google/uuid" "github.com/google/uuid"
amqp "github.com/rabbitmq/amqp091-go" amqp "github.com/rabbitmq/amqp091-go"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -17,9 +18,10 @@ import (
var Conn *amqp.Connection var Conn *amqp.Connection
var Channel *amqp.Channel var Channel *amqp.Channel
var MessagesQueue amqp.Queue const (
exchangeWebsocketMessages = "cnj.websocketserver.messages"
const exchangeWebsocketMessages = "cnj.websocketserver.messages" exchangeBroadcastMessages = "cnj.api.broadcast.messages"
)
func getConnectionString() string { func getConnectionString() string {
cfg := &config.Cfg.RabbitMq cfg := &config.Cfg.RabbitMq
@ -42,6 +44,9 @@ func Init() {
Channel = ch Channel = ch
/*
* websocketserver messages
*/
// creates a new exchange if one does not already exist // creates a new exchange if one does not already exist
err = ch.ExchangeDeclare( err = ch.ExchangeDeclare(
@ -57,6 +62,66 @@ func Init() {
if err != nil { if err != nil {
logrus.Fatalln("Failed to declare exchange, err:", err) logrus.Fatalln("Failed to declare exchange, err:", err)
} }
/*
* api broadcast messages
*/
q, err := ch.QueueDeclare(
"", // name
false, // durable
false, // delete when unused
true, // exclusive
false, // no-wait
nil, // arguments
)
if err != nil {
logrus.Fatalln("Failed to declare queue, err:", err)
}
err = ch.QueueBind(
q.Name, // queue name
"", // routing key
exchangeBroadcastMessages, // exchange
false,
nil,
)
if err != nil {
logrus.Fatalln("Failed to declare queue, err:", err)
}
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
if err != nil {
logrus.Fatalln("Failed to register consumer, err:", err)
}
go func() {
for d := range msgs {
var receivedMessage structs.ReceivedMessage
err = utils.UnmarshalReceivedMessage(d.Body, &receivedMessage)
if err != nil {
logrus.Errorln("Failed to unmarshal received msg, err:", err)
}
logrus.Debugln("RABBITMQ RECEIVED BROADCAST MESSAGE:", receivedMessage)
socketclients.BroadcastMessage(structs.SendSocketMessage{Cmd: receivedMessage.Cmd, Body: receivedMessage.Body})
}
}()
} }
func CreateClientBinding(socketClient *structs.SocketClient, id string) (queueName string, err error) { func CreateClientBinding(socketClient *structs.SocketClient, id string) (queueName string, err error) {
@ -107,11 +172,9 @@ func CreateClientBinding(socketClient *structs.SocketClient, id string) (queueNa
go func() { go func() {
for d := range msgs { for d := range msgs {
log.Printf(" [x] %s", d.Body) var receivedMessage structs.ReceivedMessage
var receivedMessage structs.ReceivedSocketMessage err = utils.UnmarshalReceivedMessage(d.Body, &receivedMessage)
err := json.Unmarshal(d.Body, &receivedMessage)
if err != nil { if err != nil {
logrus.Errorln("Failed to unmarshal received msg, err:", err) logrus.Errorln("Failed to unmarshal received msg, err:", err)
@ -179,6 +242,7 @@ func PublishClientMessage(rabbitMqMessage structs.RabbitMqMessage) error {
return nil return nil
} }
/*
func PublishBroadcastMessage(rabbitMqMessage structs.RabbitMqMessage) error { func PublishBroadcastMessage(rabbitMqMessage structs.RabbitMqMessage) error {
msg, err := json.Marshal(rabbitMqMessage) msg, err := json.Marshal(rabbitMqMessage)
@ -214,7 +278,7 @@ func publishMessage(body []byte, channelName string) error {
logrus.Printf("[x] Sent %s\n", body) logrus.Printf("[x] Sent %s\n", body)
return nil return nil
} } */
/* /*
func declareQueue(channel *amqp.Channel, name string, queue *amqp.Queue) { func declareQueue(channel *amqp.Channel, name string, queue *amqp.Queue) {

View File

@ -0,0 +1,7 @@
package structs
type ReceivedMessage struct {
Cmd int
Rec string // represent receiver user id
Body any
}

View File

@ -50,9 +50,3 @@ type SocketMessageTest struct {
Cmd int Cmd int
Body string Body string
} }
type ReceivedSocketMessage struct {
Cmd int
Rec string // represent receiver user id
Body any
}

30
modules/utils/utils.go Normal file
View File

@ -0,0 +1,30 @@
package utils
import (
"encoding/json"
"clickandjoin.app/websocketserver/modules/structs"
"github.com/sirupsen/logrus"
)
func MarshalMessage(message any) (marshaledMessage []byte, err error) {
marshaledMessage, err = json.Marshal(message)
if err != nil {
logrus.Errorln("Failed to marshal send message, err:", err)
return nil, err
}
return marshaledMessage, nil
}
func UnmarshalReceivedMessage(body []byte, receivedMessage *structs.ReceivedMessage) error {
err := json.Unmarshal(body, &receivedMessage)
if err != nil {
logrus.Errorln("Failed to unmarshal received message, err:", err)
return err
}
return nil
}

View File

@ -3,12 +3,11 @@ package socketclients
import ( import (
"clickandjoin.app/websocketserver/modules/cache" "clickandjoin.app/websocketserver/modules/cache"
"clickandjoin.app/websocketserver/modules/structs" "clickandjoin.app/websocketserver/modules/structs"
"github.com/gofiber/websocket/v2"
) )
func BroadcastMessage(message []byte) { func BroadcastMessage(sendSocketMessage structs.SendSocketMessage) {
for _, client := range cache.SocketClients { for _, client := range cache.SocketClients {
client.Conn.WriteMessage(websocket.TextMessage, message) client.SendMessage(sendSocketMessage)
} }
} }

View File

@ -1,11 +1,10 @@
package socketserver package socketserver
import ( import (
"encoding/json"
"clickandjoin.app/websocketserver/modules/cache" "clickandjoin.app/websocketserver/modules/cache"
"clickandjoin.app/websocketserver/modules/rabbitmq" "clickandjoin.app/websocketserver/modules/rabbitmq"
"clickandjoin.app/websocketserver/modules/structs" "clickandjoin.app/websocketserver/modules/structs"
"clickandjoin.app/websocketserver/modules/utils"
"clickandjoin.app/websocketserver/socketclients" "clickandjoin.app/websocketserver/socketclients"
"github.com/gofiber/websocket/v2" "github.com/gofiber/websocket/v2"
"github.com/google/uuid" "github.com/google/uuid"
@ -25,7 +24,7 @@ func RunHub() {
queueName, err := rabbitmq.CreateClientBinding(newSocketClient, uuid) queueName, err := rabbitmq.CreateClientBinding(newSocketClient, uuid)
if err != nil { if err != nil {
logrus.Fatalln("Failed to create client binding, err:", err) logrus.Errorln("Failed to create client binding, err:", err)
break break
} }
@ -36,7 +35,7 @@ func RunHub() {
logrus.Debugln("REGISTER CLIENT:", uuid) logrus.Debugln("REGISTER CLIENT:", uuid)
// for testing // for testing
marshaled, err := json.Marshal(structs.SocketMessageTest{Cmd: 99999, Body: uuid}) marshaled, err := utils.MarshalMessage(structs.SocketMessageTest{Cmd: 99999, Body: uuid})
if err != nil { if err != nil {
logrus.Errorln("Failed to marshal uuid, err:", err) logrus.Errorln("Failed to marshal uuid, err:", err)
@ -46,30 +45,30 @@ func RunHub() {
newSocketClient.Conn.WriteMessage(websocket.TextMessage, []byte(marshaled)) newSocketClient.Conn.WriteMessage(websocket.TextMessage, []byte(marshaled))
case data := <-broadcast: case data := <-broadcast:
recMsg := structs.ReceivedSocketMessage{} var receivedMessage structs.ReceivedMessage
err := json.Unmarshal(data.Msg, &recMsg) err := utils.UnmarshalReceivedMessage(data.Msg, &receivedMessage)
if err != nil { if err != nil {
logrus.Errorln("Failed err:", err) logrus.Errorln("Failed to unmarshal received msg, err:", err)
} }
logrus.Debugln("RECEIVED MESSAGE:", recMsg) logrus.Debugln("RECEIVED WEBSOCKET MESSAGE:", receivedMessage)
if recMsg.Rec != "" { if receivedMessage.Rec != "" {
isConnected, recSocketClient := socketclients.IsReceiverConnectedToThisServer(recMsg.Rec) isConnected, recSocketClient := socketclients.IsReceiverConnectedToThisServer(receivedMessage.Rec)
// send message to target receiver when connected to this server // send message to target receiver when connected to this server
if isConnected { if isConnected {
logrus.Debugln("FORWARDING MESSAGE: receiver is on connected to this server") logrus.Debugln("FORWARDING MESSAGE: receiver is on connected to this server")
recSocketClient.SendMessage(structs.SendSocketMessage{Cmd: recMsg.Cmd, Body: recMsg.Body}) recSocketClient.SendMessage(structs.SendSocketMessage{Cmd: receivedMessage.Cmd, Body: receivedMessage.Body})
} else { } else {
logrus.Debugln("FORWARDING MESSAGE: receiver connected to other server") logrus.Debugln("FORWARDING MESSAGE: receiver connected to other server")
err = rabbitmq.PublishClientMessage(structs.RabbitMqMessage{Cmd: recMsg.Cmd, Rec: recMsg.Rec, Body: recMsg.Body}) err = rabbitmq.PublishClientMessage(structs.RabbitMqMessage{Cmd: receivedMessage.Cmd, Rec: receivedMessage.Rec, Body: receivedMessage.Body})
if err != nil { if err != nil {
logrus.Fatalln("Failed to publish client message, err:", err) logrus.Errorln("Failed to publish client message, err:", err)
} }
} }
} }