|
@@ -3,10 +3,14 @@ package server
|
|
import (
|
|
import (
|
|
"encoding/json"
|
|
"encoding/json"
|
|
"sync"
|
|
"sync"
|
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/nats-io/nats.go"
|
|
"github.com/nats-io/nats.go"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap"
|
|
|
|
+ "sikey.com/websocket/repositories"
|
|
|
|
+ "x.sikey.com.cn/serverx/dbx"
|
|
"x.sikey.com.cn/serverx/natx"
|
|
"x.sikey.com.cn/serverx/natx"
|
|
|
|
+ "x.sikey.com.cn/serverx/rdbx"
|
|
)
|
|
)
|
|
|
|
|
|
const (
|
|
const (
|
|
@@ -39,6 +43,8 @@ type Nats struct {
|
|
Send chan *natsMessage
|
|
Send chan *natsMessage
|
|
Subscribe chan *subscriber
|
|
Subscribe chan *subscriber
|
|
Unsubscribe chan *subscriber
|
|
Unsubscribe chan *subscriber
|
|
|
|
+
|
|
|
|
+ Repositories *repositories.Repositories
|
|
}
|
|
}
|
|
|
|
|
|
type subscriber struct {
|
|
type subscriber struct {
|
|
@@ -60,6 +66,9 @@ func NewNats(addr string) *Nats {
|
|
Subscribers: make(map[string]*subscriber),
|
|
Subscribers: make(map[string]*subscriber),
|
|
Subscribe: make(chan *subscriber),
|
|
Subscribe: make(chan *subscriber),
|
|
Unsubscribe: make(chan *subscriber),
|
|
Unsubscribe: make(chan *subscriber),
|
|
|
|
+
|
|
|
|
+ // db
|
|
|
|
+ Repositories: repositories.NewRepositories(dbx.GetConnect(), rdbx.GetConnect()),
|
|
}
|
|
}
|
|
|
|
|
|
_, err := nc.ChanSubscribe(subject, n.ch)
|
|
_, err := nc.ChanSubscribe(subject, n.ch)
|
|
@@ -76,7 +85,8 @@ func (n *Nats) run() {
|
|
select {
|
|
select {
|
|
case nMsg := <-n.Send:
|
|
case nMsg := <-n.Send:
|
|
bytes := serializationMessage(nMsg.message)
|
|
bytes := serializationMessage(nMsg.message)
|
|
- if err := n.nc.PublishMsg(&nats.Msg{
|
|
|
|
|
|
+ timeout := 5 * time.Second
|
|
|
|
+ if _, err := n.nc.RequestMsg(&nats.Msg{
|
|
Subject: subject,
|
|
Subject: subject,
|
|
Data: bytes,
|
|
Data: bytes,
|
|
Header: nats.Header{
|
|
Header: nats.Header{
|
|
@@ -84,45 +94,65 @@ func (n *Nats) run() {
|
|
"sender": []string{nMsg.message.sender},
|
|
"sender": []string{nMsg.message.sender},
|
|
"request_id": []string{nMsg.message.RequestId},
|
|
"request_id": []string{nMsg.message.RequestId},
|
|
},
|
|
},
|
|
- }); err != nil {
|
|
|
|
|
|
+ }, timeout); err != nil {
|
|
zap.L().Error("[nats] unable to message send",
|
|
zap.L().Error("[nats] unable to message send",
|
|
zap.Error(err),
|
|
zap.Error(err),
|
|
zap.String("user_id", nMsg.userId))
|
|
zap.String("user_id", nMsg.userId))
|
|
}
|
|
}
|
|
case msg := <-n.ch:
|
|
case msg := <-n.ch:
|
|
- userIds := msg.Header.Values(headerUserId)
|
|
|
|
- if len(userIds) == 0 {
|
|
|
|
- zap.L().Info("[nats] received empty userIds")
|
|
|
|
|
|
+ requestId := msg.Header.Get("request_id")
|
|
|
|
+ sender := msg.Header.Get("sender")
|
|
|
|
+ ids := msg.Header.Values("user_id")
|
|
|
|
+ if len(ids) == 0 {
|
|
|
|
+ zap.L().Info("[nats] received empty userIds",
|
|
|
|
+ zap.String("request_id", requestId))
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ message := deserializeMessage(msg.Data)
|
|
|
|
+ message.sender = sender
|
|
|
|
+
|
|
|
|
+ // Error handler
|
|
|
|
+ if message.Type == MessageTypeError {
|
|
|
|
+ zap.L().Error("[nats] received error message",
|
|
|
|
+ zap.String("request_id", requestId),
|
|
|
|
+ zap.ByteString("message", serializationMessage(message)))
|
|
|
|
+ resp := RespondStructural{
|
|
|
|
+ RequestId: message.RequestId,
|
|
|
|
+ Ok: false,
|
|
|
|
+ ErrMsg: message.Content.(string),
|
|
|
|
+ }
|
|
|
|
+ _ = msg.Respond([]byte(resp.Marshaler()))
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
zap.L().Info("[nats] received nats message",
|
|
zap.L().Info("[nats] received nats message",
|
|
- zap.Strings("ids", userIds),
|
|
|
|
- zap.String("request_id", msg.Header.Get("request_id")))
|
|
|
|
|
|
+ zap.Strings("ids", ids), zap.String("request_id", requestId))
|
|
|
|
|
|
n.mutex.RLock()
|
|
n.mutex.RLock()
|
|
- for _, uid := range userIds {
|
|
|
|
|
|
+ for _, uid := range ids {
|
|
if s, ok := n.Subscribers[uid]; ok {
|
|
if s, ok := n.Subscribers[uid]; ok {
|
|
- c := s.client
|
|
|
|
- message := deserializeMessage(uid, msg.Data)
|
|
|
|
- ctx := c.withRequestIdContext(c.ctx.Copy(), message.RequestId)
|
|
|
|
- sender := msg.Header.Get("sender")
|
|
|
|
|
|
+ clt := s.client
|
|
|
|
+ ctx := clt.withRequestIdContext(clt.ctx.Copy(), message.RequestId)
|
|
|
|
|
|
|
|
+ // Sender
|
|
message.sender = sender
|
|
message.sender = sender
|
|
if message.Receiver == "" {
|
|
if message.Receiver == "" {
|
|
message.Receiver = uid
|
|
message.Receiver = uid
|
|
}
|
|
}
|
|
- if err := c.persistenceMessage(ctx, message); err != nil {
|
|
|
|
|
|
+
|
|
|
|
+ // Save message
|
|
|
|
+ if err := clt.persistenceMessage(ctx, message); err != nil {
|
|
zap.L().Error("[nats] unable to message",
|
|
zap.L().Error("[nats] unable to message",
|
|
zap.Error(err),
|
|
zap.Error(err),
|
|
zap.String("request_id", message.RequestId))
|
|
zap.String("request_id", message.RequestId))
|
|
|
|
+ resp := RespondStructural{
|
|
|
|
+ RequestId: message.RequestId,
|
|
|
|
+ Ok: false,
|
|
|
|
+ ErrMsg: err.Error(),
|
|
|
|
+ }
|
|
|
|
+ _ = msg.Respond([]byte(resp.Marshaler()))
|
|
continue
|
|
continue
|
|
- // resp := RespondStructural{
|
|
|
|
- // RequestId: message.MessageId,
|
|
|
|
- // Ok: false,
|
|
|
|
- // ErrMsg: err.Error(),
|
|
|
|
- // }
|
|
|
|
- // _ = msg.Respond([]byte(resp.Marshaler()))
|
|
|
|
- // continue
|
|
|
|
}
|
|
}
|
|
|
|
|
|
zap.L().Info("[nats] relay received message",
|
|
zap.L().Info("[nats] relay received message",
|
|
@@ -130,13 +160,15 @@ func (n *Nats) run() {
|
|
zap.String("message_id", message.MessageId),
|
|
zap.String("message_id", message.MessageId),
|
|
zap.ByteString("message", serializationMessage(message)),
|
|
zap.ByteString("message", serializationMessage(message)),
|
|
zap.String("request_id", message.RequestId))
|
|
zap.String("request_id", message.RequestId))
|
|
- c.Send <- message
|
|
|
|
|
|
|
|
- // response
|
|
|
|
- // resp := RespondStructural{RequestId: message.MessageId, Ok: true}
|
|
|
|
- // _ = msg.Respond([]byte(resp.Marshaler()))
|
|
|
|
|
|
+ // Message to client channel
|
|
|
|
+ clt.Send <- message
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // response
|
|
|
|
+ resp := RespondStructural{RequestId: message.MessageId, Ok: true}
|
|
|
|
+ _ = msg.Respond([]byte(resp.Marshaler()))
|
|
|
|
+
|
|
n.mutex.RUnlock()
|
|
n.mutex.RUnlock()
|
|
case s := <-n.Subscribe:
|
|
case s := <-n.Subscribe:
|
|
n.mutex.Lock()
|
|
n.mutex.Lock()
|