alpha
alex 2023-03-11 21:08:22 +01:00
parent b34c3e389b
commit b633c31ee8
6 changed files with 81 additions and 13 deletions

2
go.mod
View File

@ -3,7 +3,7 @@ module clickandjoin.app/websocketserver
go 1.19 go 1.19
require ( require (
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.75 git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.82
github.com/gocql/gocql v1.3.1 github.com/gocql/gocql v1.3.1
github.com/gofiber/fiber/v2 v2.42.0 github.com/gofiber/fiber/v2 v2.42.0
github.com/gofiber/websocket/v2 v2.1.4 github.com/gofiber/websocket/v2 v2.1.4

4
go.sum
View File

@ -4,6 +4,10 @@ git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.54 h1:bAB8Z9qJgX/H+P
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.54/go.mod h1:/CvzIeBG4vJK/MgXzwmwCYwodiTGTMOYGDF3ao/fFLM= git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.54/go.mod h1:/CvzIeBG4vJK/MgXzwmwCYwodiTGTMOYGDF3ao/fFLM=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.75 h1:Ei003kPBpKVqukqQIGg111vz82G9toIvTbfnYzhVQ0k= git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.75 h1:Ei003kPBpKVqukqQIGg111vz82G9toIvTbfnYzhVQ0k=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.75/go.mod h1:rnEM9rcZy2dg4SaDCGmSf34fp7ECzdyxxnRut2HBmrs= git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.75/go.mod h1:rnEM9rcZy2dg4SaDCGmSf34fp7ECzdyxxnRut2HBmrs=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.81 h1:idNch20NsLGt/nOFvLmJJObYh3eifgYWlZF3j12pgjs=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.81/go.mod h1:rnEM9rcZy2dg4SaDCGmSf34fp7ECzdyxxnRut2HBmrs=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.82 h1:Q92bABF1YoSaLXXWcGGGYQ0MjLjoU/ymicKrPUpSpLQ=
git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper v1.0.82/go.mod h1:rnEM9rcZy2dg4SaDCGmSf34fp7ECzdyxxnRut2HBmrs=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=

View File

@ -1,9 +1,11 @@
package cache package cache
import ( import (
"errors"
"sync" "sync"
"clickandjoin.app/websocketserver/modules/structs" "clickandjoin.app/websocketserver/modules/structs"
"github.com/gofiber/websocket/v2"
) )
var socketClients = make(map[string]*structs.SocketClient) var socketClients = make(map[string]*structs.SocketClient)
@ -36,3 +38,16 @@ func GetSocketClient(wsSessionId string) (socketClient *structs.SocketClient, ok
return client, ok return client, ok
} }
func GetSocketClientByConn(conn *websocket.Conn) (socketClient *structs.SocketClient, err error) {
mu.RLock()
defer mu.RUnlock()
for _, client := range socketClients {
if client.Conn == conn {
return client, nil
}
}
return nil, errors.New("Failed to find socket client by ws conn")
}

View File

@ -1,7 +1,8 @@
package structs package structs
type ReceivedMessage struct { type ReceivedMessage struct {
Cmd int Cmd int
Rec string // represent receiver user id RecUser string `json:"rec_user"` // represent receiver user id
Body any RecRoom string `json:"rec_room"` // represent receiver room id
Body any
} }

View File

@ -2,6 +2,7 @@ package utils
const ( const (
LenWebSocketSession = 36 LenWebSocketSession = 36
LenRoomId = 36
WsCmdTest = 99999 // only for testing - userId is sent WsCmdTest = 99999 // only for testing - userId is sent

View File

@ -6,10 +6,12 @@ import (
"clickandjoin.app/websocketserver/modules/cache" "clickandjoin.app/websocketserver/modules/cache"
"clickandjoin.app/websocketserver/modules/rabbitmq" "clickandjoin.app/websocketserver/modules/rabbitmq"
"clickandjoin.app/websocketserver/modules/redis" "clickandjoin.app/websocketserver/modules/redis"
"clickandjoin.app/websocketserver/modules/scylladb"
"clickandjoin.app/websocketserver/modules/structs" "clickandjoin.app/websocketserver/modules/structs"
"clickandjoin.app/websocketserver/modules/utils" "clickandjoin.app/websocketserver/modules/utils"
"clickandjoin.app/websocketserver/socketclients" "clickandjoin.app/websocketserver/socketclients"
gocnjhelper "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper" gocnjhelper "git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper"
"git.clickandjoin.umbach.dev/ClickandJoin/go-cnj-helper/dbstructs"
"github.com/gofiber/websocket/v2" "github.com/gofiber/websocket/v2"
) )
@ -69,16 +71,47 @@ func RunHub() {
case data := <-broadcast: case data := <-broadcast:
var receivedMessage structs.ReceivedMessage var receivedMessage structs.ReceivedMessage
err := utils.UnmarshalReceivedMessage(data.Msg, &receivedMessage) if err := utils.UnmarshalReceivedMessage(data.Msg, &receivedMessage); err != nil {
if err != nil {
gocnjhelper.LogErrorf("Failed to unmarshal received msg, err: %s", err) gocnjhelper.LogErrorf("Failed to unmarshal received msg, err: %s", err)
continue
} }
gocnjhelper.LogDebugf("RECEIVED WEBSOCKET MESSAGE: %s", receivedMessage) if len(receivedMessage.RecUser) == utils.LenWebSocketSession {
gocnjhelper.LogDebug("type: user message")
// TODO: check if the user is allowed to sent a message to target user. For example: privacy settings, friend relationship
// TODO: handle when client not connected to websocket. eg. Push Notification
SendMessageToClient(receivedMessage.RecUser, structs.SendSocketMessage{Cmd: receivedMessage.Cmd, Body: receivedMessage.Body})
} else if len(receivedMessage.RecRoom) == utils.LenRoomId {
gocnjhelper.LogDebug("type: room message")
if len(receivedMessage.Rec) == utils.LenWebSocketSession { var roomUsers []dbstructs.RoomUsers
SendMessageToClient(receivedMessage.Rec, structs.SendSocketMessage{Cmd: receivedMessage.Cmd, Body: receivedMessage.Body})
if err := scylladb.Session.Query(gocnjhelper.DbMRoomUsersHelperPKRoomId.Select("user_id")).BindStruct(dbstructs.RoomUsers{RoomId: receivedMessage.RecRoom}).SelectRelease(&roomUsers); err != nil {
gocnjhelper.LogErrorf("Failed to get room users, err: %s", err.Error())
continue
}
client, err := cache.GetSocketClientByConn(data.Conn)
if err != nil {
gocnjhelper.LogError(err.Error())
continue
}
// check if user is really in the room and has not faked the room id
if !isUserInRoom(client.UserId, roomUsers) {
gocnjhelper.LogError("User not in room")
continue
}
for _, roomUser := range roomUsers {
// TODO: handle when client not connected to websocket. eg. Push Notification
/*connToWs :=*/
SendMessageToClient(roomUser.UserId, structs.SendSocketMessage{
Cmd: receivedMessage.Cmd,
Body: receivedMessage.Body,
})
}
} }
case connection := <-unregister: case connection := <-unregister:
@ -96,7 +129,16 @@ func RunHub() {
} }
} }
func SendMessageToClient(targetUserId string, msg structs.SendSocketMessage) { func isUserInRoom(userId string, roomUsers []dbstructs.RoomUsers) bool {
for _, roomUser := range roomUsers {
if roomUser.UserId == userId {
return true
}
}
return false
}
func SendMessageToClient(targetUserId string, msg structs.SendSocketMessage) (connectedToWebSocket bool) {
if isConnected, socketClients := socketclients.IsReceiverConnectedToThisServer(targetUserId); isConnected { if isConnected, socketClients := socketclients.IsReceiverConnectedToThisServer(targetUserId); isConnected {
// send message to target receiver which is connected to this server // send message to target receiver which is connected to this server
gocnjhelper.LogDebug("FORWARDING MESSAGE: receiver is connected to this server") gocnjhelper.LogDebug("FORWARDING MESSAGE: receiver is connected to this server")
@ -105,6 +147,8 @@ func SendMessageToClient(targetUserId string, msg structs.SendSocketMessage) {
gocnjhelper.LogDebugf("send to %s", socketClient.UserId) gocnjhelper.LogDebugf("send to %s", socketClient.UserId)
socketClient.SendMessage(msg) socketClient.SendMessage(msg)
} }
return true
} else { // send message to target receiver which is connected to any other server } else { // send message to target receiver which is connected to any other server
gocnjhelper.LogDebug("FORWARDING MESSAGE: receiver connected to other server") gocnjhelper.LogDebug("FORWARDING MESSAGE: receiver connected to other server")
@ -114,8 +158,11 @@ func SendMessageToClient(targetUserId string, msg structs.SendSocketMessage) {
if err != nil { if err != nil {
gocnjhelper.LogErrorf("Failed to publish client message, err: %s", err) gocnjhelper.LogErrorf("Failed to publish client message, err: %s", err)
} }
} else {
gocnjhelper.LogDebug("rec user not connected to any other websocket server") return true
} }
gocnjhelper.LogDebug("rec user not connected to any other websocket server")
} }
return false
} }