meowlib/server/router.go

170 lines
4.6 KiB
Go
Raw Normal View History

package server
import (
"context"
"time"
"forge.redroom.link/yves/meowlib"
"github.com/go-redis/redis"
2022-10-22 22:40:03 +02:00
"google.golang.org/protobuf/proto"
)
type RedisRouter struct {
2023-08-31 23:38:03 +02:00
Name string
ServerIdentity *Identity
Client *redis.Client
InvitationTimeout int
Context context.Context
}
2023-08-31 23:43:36 +02:00
func NewRedisRouter(server *Identity, redisUrl string, password string, db int, invitationTimeout int) *RedisRouter {
var r RedisRouter
r.ServerIdentity = server
r.Name = "Redis"
r.Client = redis.NewClient(&redis.Options{
2023-08-31 23:43:36 +02:00
Addr: redisUrl,
Password: password,
DB: db,
})
2023-08-31 23:43:36 +02:00
r.InvitationTimeout = invitationTimeout
r.Context = context.Background()
// set start for uptime
err := r.Client.Set("statistics:start", time.Now().UTC().Format(time.RFC3339), 0).Err()
if err != nil {
panic(err)
}
return &r
}
2022-10-22 22:40:03 +02:00
func (r *RedisRouter) Route(msg *meowlib.ToServerMessage) (*meowlib.FromServerMessage, error) {
var from_server meowlib.FromServerMessage
// update messages counter
err := r.Client.Incr("statistics:messages:total").Err()
if err != nil {
panic(err)
}
2023-08-31 23:38:03 +02:00
// user message
if len(msg.Messages) > 0 {
// update messages counter
err := r.Client.Incr("statistics:messages:usermessages").Err()
if err != nil {
panic(err)
}
for _, usrmsg := range msg.Messages {
2022-10-22 22:40:03 +02:00
// serialize the message to store it as byte array into redis
out, err := proto.Marshal(usrmsg)
2022-10-22 22:40:03 +02:00
if err != nil {
return nil, err
}
r.Client.ZAdd(usrmsg.Destination, redis.Z{Score: float64(time.Now().Unix()), Member: out})
}
from_server.UuidAck = msg.Uuid
}
2023-08-31 23:38:03 +02:00
// check for messages
if len(msg.PullRequest) > 0 {
// update messages counter
err := r.Client.Incr("statistics:messages:messagelookups").Err()
if err != nil {
panic(err)
}
for _, rq := range msg.PullRequest {
2022-10-22 22:40:03 +02:00
msgcnt, err := r.Client.ZCount(rq.LookupKey, "-inf", "+inf").Result()
if err != nil {
return nil, err
}
res, err := r.Client.ZPopMin(rq.LookupKey, msgcnt).Result()
if err != nil {
return nil, err
}
for _, redismsg := range res {
2022-12-18 19:47:44 +01:00
//println(redismsg.Score)
2022-12-17 12:56:34 +01:00
val := redismsg.Member
2022-12-17 13:00:28 +01:00
test := val.(string)
2022-10-22 22:40:03 +02:00
var usrmsg meowlib.PackedUserMessage
2022-12-17 13:00:28 +01:00
err := proto.Unmarshal([]byte(test), &usrmsg)
2022-10-22 22:40:03 +02:00
if err != nil {
return nil, err
}
// add server timestamp
usrmsg.ServerTimestamp = append(usrmsg.ServerTimestamp, int64(redismsg.Score))
from_server.Chat = append(from_server.Chat, &usrmsg)
}
}
2022-10-24 18:44:21 +02:00
}
2023-08-31 23:38:03 +02:00
// manage Matriochka
if msg.MatriochkaMessage != nil {
// update messages counter
err := r.Client.Incr("statistics:messages:matriochka").Err()
if err != nil {
panic(err)
}
out, err := proto.Marshal(msg)
if err != nil {
return nil, err
}
r.Client.ZAdd("mtk", redis.Z{Score: float64(time.Now().Unix()), Member: out})
if msg.MatriochkaMessage.LookupKey != "" {
//r.Client.ZAdd("trk:" + msg.MatriochkaMessage.Next.Uuid,{})
}
from_server.UuidAck = msg.Uuid
}
2023-08-31 23:38:03 +02:00
// Server list exchange
2022-10-24 18:44:21 +02:00
if len(msg.KnownServers) > 0 {
2023-08-31 23:38:03 +02:00
}
// Through server invitation process
if msg.Invitation != nil {
// update messages counter
err := r.Client.Incr("statistics:messages:invitation").Err()
if err != nil {
panic(err)
}
2023-08-31 23:38:03 +02:00
switch msg.Invitation.Step {
case 1: // create invitation
2023-11-14 16:32:50 +01:00
url, expiry := r.CreateInvitation(msg.Invitation.Payload, int(msg.Invitation.Timeout), msg.Invitation.Password, r.InvitationTimeout, int(msg.Invitation.ShortcodeLen))
2023-12-30 19:08:44 +01:00
from_server.Invitation = &meowlib.Invitation{}
2023-11-14 16:32:50 +01:00
from_server.Invitation.Shortcode = url
2023-08-31 23:38:03 +02:00
from_server.Invitation.Expiry = expiry.UTC().Unix()
case 2: // get invitation
2023-12-31 20:33:01 +01:00
from_server.Invitation = &meowlib.Invitation{}
2023-12-31 23:28:10 +01:00
from_server.Invitation.Payload, err = r.GetInvitation(msg.Invitation.Shortcode, msg.Invitation.Password)
2023-08-31 23:38:03 +02:00
if err != nil {
if err.Error() == "auth failed" {
from_server.Invitation.Payload = []byte("authentication failure")
} else {
from_server.Invitation.Payload = []byte("invitation expired")
}
}
2023-11-14 16:32:50 +01:00
/* should not happen
case 3: // answer invitation
expiry := r.AnswerInvitation(msg.Invitation.Id, int(msg.Invitation.Timeout), msg.Invitation.Payload, r.InvitationTimeout)
from_server.Invitation.Expiry = expiry.UTC().Unix()
case 4: // get answer
answer, err := r.GetInvitationAnswer(msg.Invitation.Id)
if err != nil {
from_server.Invitation.Payload = []byte("invitation expired")
} else {
from_server.Invitation.Payload = answer
}
*/
2023-08-31 23:38:03 +02:00
}
}
/*
case "s": // servers list
2022-10-22 22:40:03 +02:00
breakmsgs
case "m": // matriochka
break
case "b": // broadcast
break
case "a": // admin
break
}
*/
2022-10-22 22:40:03 +02:00
return &from_server, nil
}