Files
open-im-server/internal/msggateway/client.go
T

219 lines
5.9 KiB
Go
Raw Normal View History

2023-03-08 18:39:18 +08:00
package msggateway
2023-02-14 21:08:36 +08:00
import (
"context"
"errors"
"fmt"
2023-03-23 15:42:31 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
2023-03-22 20:24:13 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
2023-03-23 15:42:31 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
2023-03-16 10:46:06 +08:00
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
2023-03-23 20:05:49 +08:00
"github.com/golang/protobuf/proto"
2023-02-14 21:08:36 +08:00
"runtime/debug"
"sync"
)
const (
// MessageText is for UTF-8 encoded text messages like JSON.
2023-02-15 19:57:16 +08:00
MessageText = iota + 1
2023-02-14 21:08:36 +08:00
// MessageBinary is for binary messages like protobufs.
MessageBinary
// CloseMessage denotes a close control message. The optional message
// payload contains a numeric code and text. Use the FormatCloseMessage
// function to format a close message payload.
CloseMessage = 8
// PingMessage denotes a ping control message. The optional message payload
// is UTF-8 encoded text.
PingMessage = 9
// PongMessage denotes a pong control message. The optional message payload
// is UTF-8 encoded text.
PongMessage = 10
)
type Client struct {
2023-02-15 19:57:16 +08:00
w *sync.Mutex
conn LongConn
2023-02-16 16:32:31 +08:00
platformID int
isCompress bool
2023-02-15 19:57:16 +08:00
userID string
2023-02-16 16:32:31 +08:00
isBackground bool
2023-03-23 15:14:50 +08:00
ctx *UserConnContext
2023-02-15 19:57:16 +08:00
onlineAt int64 // 上线时间戳(毫秒)
2023-03-08 18:39:18 +08:00
longConnServer LongConnServer
2023-02-15 19:57:16 +08:00
closed bool
2023-02-14 21:08:36 +08:00
}
2023-03-08 18:39:18 +08:00
func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
2023-02-14 21:08:36 +08:00
return &Client{
2023-03-08 18:39:18 +08:00
w: new(sync.Mutex),
conn: conn,
platformID: utils.StringToInt(ctx.GetPlatformID()),
isCompress: isCompress,
userID: ctx.GetUserID(),
2023-03-23 15:14:50 +08:00
ctx: ctx,
2023-03-08 18:39:18 +08:00
onlineAt: utils.GetCurrentTimestampByMill(),
2023-02-14 21:08:36 +08:00
}
}
2023-03-08 18:39:18 +08:00
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isCompress bool, longConnServer LongConnServer) {
2023-02-16 16:32:31 +08:00
c.w = new(sync.Mutex)
c.conn = conn
c.platformID = utils.StringToInt(ctx.GetPlatformID())
c.isCompress = isCompress
c.userID = ctx.GetUserID()
2023-03-23 15:14:50 +08:00
c.ctx = ctx
2023-02-16 16:32:31 +08:00
c.onlineAt = utils.GetCurrentTimestampByMill()
2023-03-08 18:39:18 +08:00
c.longConnServer = longConnServer
2023-02-16 16:32:31 +08:00
}
2023-02-15 19:57:16 +08:00
func (c *Client) readMessage() {
2023-02-14 21:08:36 +08:00
defer func() {
2023-02-15 19:57:16 +08:00
if r := recover(); r != nil {
2023-02-14 21:08:36 +08:00
fmt.Println("socket have panic err:", r, string(debug.Stack()))
}
2023-03-23 17:51:38 +08:00
c.close()
2023-02-14 21:08:36 +08:00
}()
2023-02-22 21:06:55 +08:00
//var returnErr error
2023-02-15 19:57:16 +08:00
for {
messageType, message, returnErr := c.conn.ReadMessage()
if returnErr != nil {
break
}
2023-02-16 16:32:31 +08:00
if c.closed == true { //连接刚置位已经关闭,但是协程还没退出的场景
2023-02-14 21:08:36 +08:00
break
}
switch messageType {
case PingMessage:
case PongMessage:
case CloseMessage:
return
case MessageText:
case MessageBinary:
if len(message) == 0 {
continue
}
returnErr = c.handleMessage(message)
2023-02-15 19:57:16 +08:00
if returnErr != nil {
2023-03-22 20:33:37 +08:00
log.ZError(context.Background(), "WSGetNewestSeq", returnErr)
2023-02-14 21:08:36 +08:00
break
}
}
}
}
2023-02-15 19:57:16 +08:00
func (c *Client) handleMessage(message []byte) error {
2023-02-22 21:06:55 +08:00
if c.isCompress {
2023-02-14 21:08:36 +08:00
var decompressErr error
2023-03-08 18:39:18 +08:00
message, decompressErr = c.longConnServer.DeCompress(message)
2023-02-14 21:08:36 +08:00
if decompressErr != nil {
2023-02-15 19:57:16 +08:00
return utils.Wrap(decompressErr, "")
2023-02-14 21:08:36 +08:00
}
}
2023-02-15 19:57:16 +08:00
var binaryReq Req
2023-03-08 18:39:18 +08:00
err := c.longConnServer.Decode(message, &binaryReq)
2023-02-14 21:08:36 +08:00
if err != nil {
2023-02-15 19:57:16 +08:00
return utils.Wrap(err, "")
2023-02-14 21:08:36 +08:00
}
2023-03-08 18:39:18 +08:00
if err := c.longConnServer.Validate(binaryReq); err != nil {
2023-02-15 19:57:16 +08:00
return utils.Wrap(err, "")
2023-02-14 21:08:36 +08:00
}
if binaryReq.SendID != c.userID {
return errors.New("exception conn userID not same to req userID")
}
2023-03-23 15:42:31 +08:00
ctx := mcontext.WithMustInfoCtx([]string{binaryReq.OperationID, binaryReq.SendID, constant.PlatformIDToName(c.platformID), c.ctx.GetConnID()})
2023-02-14 21:08:36 +08:00
var messageErr error
2023-02-15 19:57:16 +08:00
var resp []byte
2023-02-14 21:08:36 +08:00
switch binaryReq.ReqIdentifier {
2023-03-08 18:39:18 +08:00
case WSGetNewestSeq:
resp, messageErr = c.longConnServer.GetSeq(ctx, binaryReq)
2023-03-22 20:24:13 +08:00
log.ZError(ctx, "WSGetNewestSeq", messageErr, "resp", resp)
2023-03-08 18:39:18 +08:00
case WSSendMsg:
resp, messageErr = c.longConnServer.SendMessage(ctx, binaryReq)
case WSSendSignalMsg:
resp, messageErr = c.longConnServer.SendSignalMessage(ctx, binaryReq)
case WSPullMsgBySeqList:
resp, messageErr = c.longConnServer.PullMessageBySeqList(ctx, binaryReq)
case WsLogoutMsg:
resp, messageErr = c.longConnServer.UserLogout(ctx, binaryReq)
case WsSetBackgroundStatus:
2023-02-22 21:06:55 +08:00
resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
2023-02-14 21:08:36 +08:00
default:
2023-02-15 19:57:16 +08:00
return errors.New(fmt.Sprintf("ReqIdentifier failed,sendID:%d,msgIncr:%s,reqIdentifier:%s", binaryReq.SendID, binaryReq.MsgIncr, binaryReq.ReqIdentifier))
2023-02-14 21:08:36 +08:00
}
2023-02-22 21:06:55 +08:00
c.replyMessage(&binaryReq, messageErr, resp)
2023-02-15 19:57:16 +08:00
return nil
2023-02-14 21:08:36 +08:00
2023-02-22 21:06:55 +08:00
}
func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) {
2023-03-08 18:39:18 +08:00
resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req)
2023-02-22 21:06:55 +08:00
if messageErr != nil {
return nil, messageErr
}
c.isBackground = isBackground
//todo callback
return resp, nil
2023-02-14 21:08:36 +08:00
}
2023-02-15 19:57:16 +08:00
func (c *Client) close() {
c.w.Lock()
defer c.w.Unlock()
2023-03-23 20:05:49 +08:00
c.closed = true
2023-02-15 19:57:16 +08:00
c.conn.Close()
2023-03-08 18:39:18 +08:00
c.longConnServer.UnRegister(c)
2023-02-14 21:08:36 +08:00
}
2023-02-22 21:06:55 +08:00
func (c *Client) replyMessage(binaryReq *Req, err error, resp []byte) {
2023-02-15 19:57:16 +08:00
mReply := Resp{
ReqIdentifier: binaryReq.ReqIdentifier,
MsgIncr: binaryReq.MsgIncr,
OperationID: binaryReq.OperationID,
Data: resp,
}
_ = c.writeMsg(mReply)
}
2023-03-08 18:39:18 +08:00
func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error {
2023-03-23 20:05:49 +08:00
data, err := proto.Marshal(msgData)
if err != nil {
return err
}
resp := Resp{
ReqIdentifier: WSPushMsg,
OperationID: mcontext.GetOperationID(ctx),
Data: data,
}
return c.writeMsg(resp)
2023-03-08 18:39:18 +08:00
}
func (c *Client) KickOnlineMessage(ctx context.Context) error {
return nil
}
2023-02-15 19:57:16 +08:00
func (c *Client) writeMsg(resp Resp) error {
c.w.Lock()
defer c.w.Unlock()
if c.closed == true {
return nil
}
encodedBuf := bufferPool.Get().([]byte)
resultBuf := bufferPool.Get().([]byte)
2023-03-08 18:39:18 +08:00
encodeBuf, err := c.longConnServer.Encode(resp)
2023-02-15 19:57:16 +08:00
if err != nil {
return utils.Wrap(err, "")
}
_ = c.conn.SetWriteTimeout(60)
2023-02-16 16:32:31 +08:00
if c.isCompress {
2023-02-15 19:57:16 +08:00
var compressErr error
2023-03-08 18:39:18 +08:00
resultBuf, compressErr = c.longConnServer.Compress(encodeBuf)
2023-02-15 19:57:16 +08:00
if compressErr != nil {
return utils.Wrap(compressErr, "")
}
return c.conn.WriteMessage(MessageBinary, resultBuf)
} else {
return c.conn.WriteMessage(MessageBinary, encodedBuf)
}
2023-02-14 21:08:36 +08:00
}