Merge remote-tracking branch 'origin/errcode' into errcode

This commit is contained in:
withchao 2023-03-09 14:42:21 +08:00
commit 7776db83ea
81 changed files with 769 additions and 2001 deletions

@ -1 +1 @@
Subproject commit 1667b0f4e205fc4ed7c690ab55b662087d61c277 Subproject commit 48fd66a6eea7ff4c5ccacddd7929bf8d7b5b40fa

View File

@ -28,7 +28,7 @@ func run(port int) error {
if port == 0 { if port == 0 {
port = config.Config.Api.GinPort[0] port = config.Config.Api.GinPort[0]
} }
zk, err := openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, "", 10, "", "") zk, err := openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema, 10, config.Config.Zookeeper.UserName, config.Config.Zookeeper.Password)
if err != nil { if err != nil {
return err return err
} }

View File

@ -8,9 +8,9 @@ import (
func main() { func main() {
msgGatewayCmd := cmd.NewMsgGatewayCmd() msgGatewayCmd := cmd.NewMsgGatewayCmd()
msgGatewayCmd.AddWsPortFlag()
msgGatewayCmd.AddPortFlag() msgGatewayCmd.AddPortFlag()
msgGatewayCmd.AddPrometheusPortFlag() msgGatewayCmd.AddPrometheusPortFlag()
msgGatewayCmd.AddWsPortFlag()
if err := msgGatewayCmd.Exec(); err != nil { if err := msgGatewayCmd.Exec(); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)

View File

@ -9,10 +9,14 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImAuthName) authCmd := cmd.NewAuthCmd()
rpcCmd.AddPortFlag() authCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() authCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(auth.Start); err != nil { if err := authCmd.Execute(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
if err := authCmd.StartSvr(config.Config.RpcRegisterName.OpenImAuthName, auth.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImConversationName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(conversation.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImConversationName, conversation.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImFriendName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(friend.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImFriendName, friend.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImGroupName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(friend.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImGroupName, friend.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImMsgName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(msg.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImMsgName, msg.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImThirdName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(third.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImThirdName, third.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -9,10 +9,10 @@ import (
) )
func main() { func main() {
rpcCmd := cmd.NewRpcCmd(config.Config.RpcRegisterName.OpenImUserName) rpcCmd := cmd.NewRpcCmd()
rpcCmd.AddPortFlag() rpcCmd.AddPortFlag()
rpcCmd.AddPrometheusPortFlag() rpcCmd.AddPrometheusPortFlag()
if err := rpcCmd.Exec(user.Start); err != nil { if err := rpcCmd.Exec(config.Config.RpcRegisterName.OpenImUserName, user.Start); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
os.Exit(1) os.Exit(1)
} }

View File

@ -3,24 +3,24 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
auth "OpenIM/pkg/proto/auth" auth "OpenIM/pkg/proto/auth"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewAuth(zk *openKeeper.ZkClient) *Auth { func NewAuth(c discoveryregistry.SvcDiscoveryRegistry) *Auth {
return &Auth{zk: zk} return &Auth{c: c}
} }
type Auth struct { type Auth struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *Auth) client() (auth.AuthClient, error) { func (o *Auth) client() (auth.AuthClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImAuthName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImAuthName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,24 +3,24 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/proto/conversation" "OpenIM/pkg/proto/conversation"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewConversation(zk *openKeeper.ZkClient) *Conversation { func NewConversation(c discoveryregistry.SvcDiscoveryRegistry) *Conversation {
return &Conversation{zk: zk} return &Conversation{c: c}
} }
type Conversation struct { type Conversation struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *Conversation) client() (conversation.ConversationClient, error) { func (o *Conversation) client() (conversation.ConversationClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImConversationName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImConversationName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,24 +3,25 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/proto/friend" "OpenIM/pkg/proto/friend"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewFriend(zk *openKeeper.ZkClient) *Friend { func NewFriend(c discoveryregistry.SvcDiscoveryRegistry) *Friend {
return &Friend{zk: zk} return &Friend{c: c}
} }
type Friend struct { type Friend struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *Friend) client() (friend.FriendClient, error) { func (o *Friend) client() (friend.FriendClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImFriendName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImFriendName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,24 +3,25 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/proto/group" "OpenIM/pkg/proto/group"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewGroup(zk *openKeeper.ZkClient) *Group { func NewGroup(c discoveryregistry.SvcDiscoveryRegistry) *Group {
return &Group{zk: zk} return &Group{c: c}
} }
type Group struct { type Group struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *Group) client() (group.GroupClient, error) { func (o *Group) client() (group.GroupClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImGroupName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImGroupName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,13 +7,13 @@ import (
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant" "OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log" "OpenIM/pkg/common/log"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/errs" "OpenIM/pkg/errs"
"OpenIM/pkg/proto/msg" "OpenIM/pkg/proto/msg"
"OpenIM/pkg/proto/sdkws" "OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils" "OpenIM/pkg/utils"
"context" "context"
"errors" "errors"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
@ -22,12 +22,12 @@ import (
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewMsg(zk *openKeeper.ZkClient) *Msg { func NewMsg(c discoveryregistry.SvcDiscoveryRegistry) *Msg {
return &Msg{zk: zk, validate: validator.New()} return &Msg{c: c, validate: validator.New()}
} }
type Msg struct { type Msg struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
validate *validator.Validate validate *validator.Validate
} }
@ -107,7 +107,7 @@ func newUserSendMsgReq(params *apistruct.ManagementSendMsgReq) *msg.SendMsgReq {
} }
func (o *Msg) client() (msg.MsgClient, error) { func (o *Msg) client() (msg.MsgClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImMsgName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImMsgName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -214,7 +214,7 @@ func (o *Msg) ManagementSendMsg(c *gin.Context) {
} }
log.NewInfo(params.OperationID, "Ws call success to ManagementSendMsgReq", params) log.NewInfo(params.OperationID, "Ws call success to ManagementSendMsgReq", params)
pbData := newUserSendMsgReq(&params) pbData := newUserSendMsgReq(&params)
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImMsgName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImMsgName)
if err != nil { if err != nil {
apiresp.GinError(c, errs.ErrInternalServer) apiresp.GinError(c, errs.ErrInternalServer)
return return

View File

@ -5,13 +5,13 @@ import (
"OpenIM/pkg/common/log" "OpenIM/pkg/common/log"
"OpenIM/pkg/common/mw" "OpenIM/pkg/common/mw"
"OpenIM/pkg/common/prome" "OpenIM/pkg/common/prome"
"github.com/OpenIMSDK/openKeeper" "OpenIM/pkg/discoveryregistry"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"io" "io"
"os" "os"
) )
func NewGinRouter(zk *openKeeper.ZkClient) *gin.Engine { func NewGinRouter(zk discoveryregistry.SvcDiscoveryRegistry) *gin.Engine {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
f, _ := os.Create("../logs/api.log") f, _ := os.Create("../logs/api.log")
gin.DefaultWriter = io.MultiWriter(f) gin.DefaultWriter = io.MultiWriter(f)
@ -27,7 +27,6 @@ func NewGinRouter(zk *openKeeper.ZkClient) *gin.Engine {
r.GET("/metrics", prome.PrometheusHandler()) r.GET("/metrics", prome.PrometheusHandler())
} }
zk.AddOption(mw.GrpcClient()) // 默认RPC中间件 zk.AddOption(mw.GrpcClient()) // 默认RPC中间件
userRouterGroup := r.Group("/user") userRouterGroup := r.Group("/user")
{ {
u := NewUser(zk) u := NewUser(zk)

View File

@ -3,24 +3,25 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/proto/third" "OpenIM/pkg/proto/third"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewThird(zk *openKeeper.ZkClient) *Third { func NewThird(c discoveryregistry.SvcDiscoveryRegistry) *Third {
return &Third{zk: zk} return &Third{c: c}
} }
type Third struct { type Third struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *Third) client() (third.ThirdClient, error) { func (o *Third) client() (third.ThirdClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImThirdName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImThirdName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -3,24 +3,24 @@ package api
import ( import (
"OpenIM/internal/api/a2r" "OpenIM/internal/api/a2r"
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/proto/user" "OpenIM/pkg/proto/user"
"context" "context"
"github.com/OpenIMSDK/openKeeper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var _ context.Context // 解决goland编辑器bug var _ context.Context // 解决goland编辑器bug
func NewUser(zk *openKeeper.ZkClient) *User { func NewUser(client discoveryregistry.SvcDiscoveryRegistry) *User {
return &User{zk: zk} return &User{c: client}
} }
type User struct { type User struct {
zk *openKeeper.ZkClient c discoveryregistry.SvcDiscoveryRegistry
} }
func (o *User) client() (user.UserClient, error) { func (o *User) client() (user.UserClient, error) {
conn, err := o.zk.GetConn(config.Config.RpcRegisterName.OpenImUserName) conn, err := o.c.GetConn(config.Config.RpcRegisterName.OpenImUserName)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,9 +2,7 @@ package check
import ( import (
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant"
discoveryRegistry "OpenIM/pkg/discoveryregistry" discoveryRegistry "OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/errs"
"OpenIM/pkg/proto/friend" "OpenIM/pkg/proto/friend"
sdkws "OpenIM/pkg/proto/sdkws" sdkws "OpenIM/pkg/proto/sdkws"
"context" "context"
@ -51,26 +49,15 @@ func (f *FriendChecker) IsFriend(ctx context.Context, possibleFriendUserID, user
} }
func (f *FriendChecker) GetAllPageFriends(ctx context.Context, ownerUserID string) (resp []*sdkws.FriendInfo, err error) { func (f *FriendChecker) GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) {
cc, err := f.getConn() cc, err := f.getConn()
if err != nil { if err != nil {
return nil, err return nil, err
} }
page := int32(0) req := friend.GetFriendIDsReq{UserID: ownerUserID}
req := friend.GetPaginationFriendsReq{UserID: ownerUserID} resp, err := friend.NewFriendClient(cc).GetFriendIDs(ctx, &req)
for { if err != nil {
req.Pagination = &sdkws.RequestPagination{PageNumber: page, ShowNumber: constant.ShowNumber} return nil, err
tmp, err := friend.NewFriendClient(cc).GetPaginationFriends(ctx, &req)
if err != nil {
return nil, err
}
if len(tmp.FriendsInfo) == 0 {
if tmp.Total == int32(len(resp)) {
return resp, nil
}
return nil, errs.ErrData.Wrap("The total number of results and expectations are different, but result is nil")
}
resp = append(resp, tmp.FriendsInfo...)
page++
} }
return resp.FriendIDs, err
} }

View File

@ -47,21 +47,3 @@ func (m *MsgCheck) PullMessageBySeqList(ctx context.Context, req *sdkws.PullMess
resp, err := msg.NewMsgClient(cc).PullMessageBySeqs(ctx, req) resp, err := msg.NewMsgClient(cc).PullMessageBySeqs(ctx, req)
return resp, err return resp, err
} }
//func (m *MsgCheck) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
// cc, err := m.getConn()
// if err != nil {
// return nil, err
// }
// resp, err := msg.NewMsgClient(cc).SendMsg(ctx, req)
// return resp, err
//}
//
//func (m *MsgCheck) SendMsg(ctx context.Context, req *msg.SendMsgReq) (*msg.SendMsgResp, error) {
// cc, err := m.getConn()
// if err != nil {
// return nil, err
// }
// resp, err := msg.NewMsgClient(cc).SendMsg(ctx, req)
// return resp, err
//}

View File

@ -1,108 +0,0 @@
package msggateway
import (
"OpenIM/pkg/common/log"
pbChat "OpenIM/pkg/proto/msg"
sdkws "OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils"
"context"
"google.golang.org/grpc"
)
var MaxPullMsgNum = 100
func (r *RPCServer) GenPullSeqList(currentSeq uint32, operationID string, userID string) ([]uint32, error) {
maxSeq, err := db.DB.GetUserMaxSeq(userID)
if err != nil {
log.Error(operationID, "GetUserMaxSeq failed ", userID, err.Error())
return nil, utils.Wrap(err, "")
}
var seqList []uint32
num := 0
for i := currentSeq + 1; i < uint32(maxSeq); i++ {
seqList = append(seqList, i)
num++
if num == MaxPullMsgNum {
break
}
}
log.Info(operationID, "GenPullSeqList ", seqList, "current seq", currentSeq)
return seqList, nil
}
func (r *RPCServer) GetSingleUserMsgForPushPlatforms(operationID string, msgData *sdkws.MsgData, pushToUserID string, platformIDList []int) map[int]*sdkws.MsgDataList {
user2PushMsg := make(map[int]*sdkws.MsgDataList, 0)
for _, v := range platformIDList {
user2PushMsg[v] = r.GetSingleUserMsgForPush(operationID, msgData, pushToUserID, v)
//log.Info(operationID, "GetSingleUserMsgForPush", msgData.Seq, pushToUserID, v, "len:", len(user2PushMsg[v]))
}
return user2PushMsg
}
func (r *RPCServer) GetSingleUserMsgForPush(operationID string, msgData *sdkws.MsgData, pushToUserID string, platformID int) *sdkws.MsgDataList {
//msgData.MsgDataList = nil
return &sdkws.MsgDataList{MsgDataList: []*sdkws.MsgData{msgData}}
//userConn := ws.getUserConn(pushToUserID, platformID)
//if userConn == nil {
// log.Debug(operationID, "userConn == nil")
// return []*sdkws.MsgData{msgData}
//}
//
//if msgData.Seq <= userConn.PushedMaxSeq {
// log.Debug(operationID, "msgData.Seq <= userConn.PushedMaxSeq", msgData.Seq, userConn.PushedMaxSeq)
// return nil
//}
//
//msgList := r.GetSingleUserMsg(operationID, msgData.Seq, pushToUserID)
//if msgList == nil {
// log.Debug(operationID, "GetSingleUserMsg msgList == nil", msgData.Seq, userConn.PushedMaxSeq)
// userConn.PushedMaxSeq = msgData.Seq
// return []*sdkws.MsgData{msgData}
//}
//msgList = append(msgList, msgData)
//
//for _, v := range msgList {
// if v.Seq > userConn.PushedMaxSeq {
// userConn.PushedMaxSeq = v.Seq
// }
//}
//log.Debug(operationID, "GetSingleUserMsg msgList len ", len(msgList), userConn.PushedMaxSeq)
//return msgList
}
func (r *RPCServer) GetSingleUserMsg(operationID string, currentMsgSeq uint32, userID string) []*sdkws.MsgData {
seqs, err := r.GenPullSeqList(currentMsgSeq, operationID, userID)
if err != nil {
log.Error(operationID, "GenPullSeqList failed ", err.Error(), currentMsgSeq, userID)
return nil
}
if len(seqs) == 0 {
log.Error(operationID, "GenPullSeqList len == 0 ", currentMsgSeq, userID)
return nil
}
rpcReq := sdkws.PullMessageBySeqsReq{}
//rpcReq.Seqs = seqs
rpcReq.UserID = userID
var grpcConn *grpc.ClientConn
msgClient := pbChat.NewMsgClient(grpcConn)
reply, err := msgClient.PullMessageBySeqs(context.Background(), &rpcReq)
if err != nil {
log.Error(operationID, "PullMessageBySeqList failed ", err.Error(), rpcReq.String())
return nil
}
if len(reply.List) == 0 {
return nil
}
return reply.List
}
//func (r *RPCServer) GetBatchUserMsgForPush(operationID string, msgData *sdkws.MsgData, pushToUserIDList []string, platformID int) map[string][]*sdkws.MsgData {
// user2PushMsg := make(map[string][]*sdkws.MsgData, 0)
// for _, v := range pushToUserIDList {
// user2PushMsg[v] = r.GetSingleUserMsgForPush(operationID, msgData, v, platformID)
// }
// return user2PushMsg
//}

View File

@ -1,12 +1,11 @@
package new package msggateway
import ( import (
"OpenIM/pkg/common/constant" "OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils" "OpenIM/pkg/utils"
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/go-playground/validator/v10"
"runtime/debug" "runtime/debug"
"sync" "sync"
) )
@ -39,45 +38,30 @@ type Client struct {
isBackground bool isBackground bool
connID string connID string
onlineAt int64 // 上线时间戳(毫秒) onlineAt int64 // 上线时间戳(毫秒)
handler MessageHandler longConnServer LongConnServer
unregisterChan chan *Client
compressor Compressor
encoder Encoder
validate *validator.Validate
closed bool closed bool
} }
func newClient(ctx *UserConnContext, conn LongConn, isCompress bool, compressor Compressor, encoder Encoder, func newClient(ctx *UserConnContext, conn LongConn, isCompress bool) *Client {
handler MessageHandler, unregisterChan chan *Client, validate *validator.Validate) *Client {
return &Client{ return &Client{
w: new(sync.Mutex), w: new(sync.Mutex),
conn: conn, conn: conn,
platformID: utils.StringToInt(ctx.GetPlatformID()), platformID: utils.StringToInt(ctx.GetPlatformID()),
isCompress: isCompress, isCompress: isCompress,
userID: ctx.GetUserID(), userID: ctx.GetUserID(),
compressor: compressor, connID: ctx.GetConnID(),
encoder: encoder, onlineAt: utils.GetCurrentTimestampByMill(),
connID: ctx.GetConnID(),
onlineAt: utils.GetCurrentTimestampByMill(),
handler: handler,
unregisterChan: unregisterChan,
validate: validate,
} }
} }
func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isCompress bool, compressor Compressor, encoder Encoder, func (c *Client) ResetClient(ctx *UserConnContext, conn LongConn, isCompress bool, longConnServer LongConnServer) {
handler MessageHandler, unregisterChan chan *Client, validate *validator.Validate) {
c.w = new(sync.Mutex) c.w = new(sync.Mutex)
c.conn = conn c.conn = conn
c.platformID = utils.StringToInt(ctx.GetPlatformID()) c.platformID = utils.StringToInt(ctx.GetPlatformID())
c.isCompress = isCompress c.isCompress = isCompress
c.userID = ctx.GetUserID() c.userID = ctx.GetUserID()
c.compressor = compressor
c.encoder = encoder
c.connID = ctx.GetConnID() c.connID = ctx.GetConnID()
c.onlineAt = utils.GetCurrentTimestampByMill() c.onlineAt = utils.GetCurrentTimestampByMill()
c.handler = handler c.longConnServer = longConnServer
c.unregisterChan = unregisterChan
c.validate = validate
} }
func (c *Client) readMessage() { func (c *Client) readMessage() {
defer func() { defer func() {
@ -117,41 +101,41 @@ func (c *Client) readMessage() {
func (c *Client) handleMessage(message []byte) error { func (c *Client) handleMessage(message []byte) error {
if c.isCompress { if c.isCompress {
var decompressErr error var decompressErr error
message, decompressErr = c.compressor.DeCompress(message) message, decompressErr = c.longConnServer.DeCompress(message)
if decompressErr != nil { if decompressErr != nil {
return utils.Wrap(decompressErr, "") return utils.Wrap(decompressErr, "")
} }
} }
var binaryReq Req var binaryReq Req
err := c.encoder.Decode(message, &binaryReq) err := c.longConnServer.Decode(message, &binaryReq)
if err != nil { if err != nil {
return utils.Wrap(err, "") return utils.Wrap(err, "")
} }
if err := c.validate.Struct(binaryReq); err != nil { if err := c.longConnServer.Validate(binaryReq); err != nil {
return utils.Wrap(err, "") return utils.Wrap(err, "")
} }
if binaryReq.SendID != c.userID { if binaryReq.SendID != c.userID {
return errors.New("exception conn userID not same to req userID") return errors.New("exception conn userID not same to req userID")
} }
ctx := context.Background() ctx := context.Background()
ctx = context.WithValue(ctx, CONN_ID, c.connID) ctx = context.WithValue(ctx, ConnID, c.connID)
ctx = context.WithValue(ctx, OPERATION_ID, binaryReq.OperationID) ctx = context.WithValue(ctx, OperationID, binaryReq.OperationID)
ctx = context.WithValue(ctx, COMMON_USERID, binaryReq.SendID) ctx = context.WithValue(ctx, CommonUserID, binaryReq.SendID)
ctx = context.WithValue(ctx, PLATFORM_ID, c.platformID) ctx = context.WithValue(ctx, PlatformID, c.platformID)
var messageErr error var messageErr error
var resp []byte var resp []byte
switch binaryReq.ReqIdentifier { switch binaryReq.ReqIdentifier {
case constant.WSGetNewestSeq: case WSGetNewestSeq:
resp, messageErr = c.handler.GetSeq(ctx, binaryReq) resp, messageErr = c.longConnServer.GetSeq(ctx, binaryReq)
case constant.WSSendMsg: case WSSendMsg:
resp, messageErr = c.handler.SendMessage(ctx, binaryReq) resp, messageErr = c.longConnServer.SendMessage(ctx, binaryReq)
case constant.WSSendSignalMsg: case WSSendSignalMsg:
resp, messageErr = c.handler.SendSignalMessage(ctx, binaryReq) resp, messageErr = c.longConnServer.SendSignalMessage(ctx, binaryReq)
case constant.WSPullMsgBySeqList: case WSPullMsgBySeqList:
resp, messageErr = c.handler.PullMessageBySeqList(ctx, binaryReq) resp, messageErr = c.longConnServer.PullMessageBySeqList(ctx, binaryReq)
case constant.WsLogoutMsg: case WsLogoutMsg:
resp, messageErr = c.handler.UserLogout(ctx, binaryReq) resp, messageErr = c.longConnServer.UserLogout(ctx, binaryReq)
case constant.WsSetBackgroundStatus: case WsSetBackgroundStatus:
resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq) resp, messageErr = c.setAppBackgroundStatus(ctx, binaryReq)
default: default:
return errors.New(fmt.Sprintf("ReqIdentifier failed,sendID:%d,msgIncr:%s,reqIdentifier:%s", binaryReq.SendID, binaryReq.MsgIncr, binaryReq.ReqIdentifier)) return errors.New(fmt.Sprintf("ReqIdentifier failed,sendID:%d,msgIncr:%s,reqIdentifier:%s", binaryReq.SendID, binaryReq.MsgIncr, binaryReq.ReqIdentifier))
@ -161,7 +145,7 @@ func (c *Client) handleMessage(message []byte) error {
} }
func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) { func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) {
resp, isBackground, messageErr := c.handler.SetUserDeviceBackground(ctx, req) resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req)
if messageErr != nil { if messageErr != nil {
return nil, messageErr return nil, messageErr
} }
@ -174,7 +158,7 @@ func (c *Client) close() {
c.w.Lock() c.w.Lock()
defer c.w.Unlock() defer c.w.Unlock()
c.conn.Close() c.conn.Close()
c.unregisterChan <- c c.longConnServer.UnRegister(c)
} }
func (c *Client) replyMessage(binaryReq *Req, err error, resp []byte) { func (c *Client) replyMessage(binaryReq *Req, err error, resp []byte) {
@ -186,6 +170,13 @@ func (c *Client) replyMessage(binaryReq *Req, err error, resp []byte) {
} }
_ = c.writeMsg(mReply) _ = c.writeMsg(mReply)
} }
func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error {
return nil
}
func (c *Client) KickOnlineMessage(ctx context.Context) error {
return nil
}
func (c *Client) writeMsg(resp Resp) error { func (c *Client) writeMsg(resp Resp) error {
c.w.Lock() c.w.Lock()
@ -195,14 +186,14 @@ func (c *Client) writeMsg(resp Resp) error {
} }
encodedBuf := bufferPool.Get().([]byte) encodedBuf := bufferPool.Get().([]byte)
resultBuf := bufferPool.Get().([]byte) resultBuf := bufferPool.Get().([]byte)
encodeBuf, err := c.encoder.Encode(resp) encodeBuf, err := c.longConnServer.Encode(resp)
if err != nil { if err != nil {
return utils.Wrap(err, "") return utils.Wrap(err, "")
} }
_ = c.conn.SetWriteTimeout(60) _ = c.conn.SetWriteTimeout(60)
if c.isCompress { if c.isCompress {
var compressErr error var compressErr error
resultBuf, compressErr = c.compressor.Compress(encodeBuf) resultBuf, compressErr = c.longConnServer.Compress(encodeBuf)
if compressErr != nil { if compressErr != nil {
return utils.Wrap(compressErr, "") return utils.Wrap(compressErr, "")
} }

View File

@ -1,4 +1,4 @@
package new package msggateway
import ( import (
"OpenIM/pkg/utils" "OpenIM/pkg/utils"

View File

@ -0,0 +1,27 @@
package msggateway
const (
WsUserID = "sendID"
CommonUserID = "userID"
PlatformID = "platformID"
ConnID = "connID"
Token = "token"
OperationID = "operationID"
Compression = "compression"
GzipCompressionProtocol = "gzip"
)
const (
WebSocket = iota + 1
)
const (
//Websocket Protocol
WSGetNewestSeq = 1001
WSPullMsgBySeqList = 1002
WSSendMsg = 1003
WSSendSignalMsg = 1004
WSPushMsg = 2001
WSKickOnlineMsg = 2002
WsLogoutMsg = 2003
WsSetBackgroundStatus = 2004
WSDataError = 3001
)

View File

@ -1,4 +1,4 @@
package new package msggateway
import ( import (
"OpenIM/pkg/utils" "OpenIM/pkg/utils"
@ -47,8 +47,8 @@ func (c *UserConnContext) GetConnID() string {
return c.RemoteAddr + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill())) return c.RemoteAddr + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill()))
} }
func (c *UserConnContext) GetUserID() string { func (c *UserConnContext) GetUserID() string {
return c.Req.URL.Query().Get(WS_USERID) return c.Req.URL.Query().Get(WsUserID)
} }
func (c *UserConnContext) GetPlatformID() string { func (c *UserConnContext) GetPlatformID() string {
return c.Req.URL.Query().Get(PLATFORM_ID) return c.Req.URL.Query().Get(PlatformID)
} }

View File

@ -1,4 +1,4 @@
package new package msggateway
import ( import (
"OpenIM/pkg/utils" "OpenIM/pkg/utils"

View File

@ -1,4 +1,4 @@
package new package msggateway
import ( import (
"OpenIM/pkg/errs" "OpenIM/pkg/errs"

View File

@ -0,0 +1,138 @@
package msggateway
import (
"OpenIM/internal/startrpc"
"OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/prome"
"OpenIM/pkg/common/tokenverify"
"OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/errs"
"OpenIM/pkg/proto/msggateway"
"OpenIM/pkg/utils"
"context"
"google.golang.org/grpc"
)
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
msggateway.RegisterMsgGatewayServer(server, &Server{})
return nil
}
func (s *Server) Start() error {
return startrpc.Start(s.rpcPort, config.Config.RpcRegisterName.OpenImMessageGatewayName, s.prometheusPort, Start)
}
type Server struct {
rpcPort int
prometheusPort int
LongConnServer LongConnServer
pushTerminal []int
//rpcServer *RpcServer
}
func NewServer(rpcPort int, longConnServer LongConnServer) *Server {
return &Server{rpcPort: rpcPort, LongConnServer: longConnServer, pushTerminal: []int{constant.IOSPlatformID, constant.AndroidPlatformID}}
}
func (s *Server) OnlinePushMsg(context context.Context, req *msggateway.OnlinePushMsgReq) (*msggateway.OnlinePushMsgResp, error) {
panic("implement me")
}
func (s *Server) GetUsersOnlineStatus(ctx context.Context, req *msggateway.GetUsersOnlineStatusReq) (*msggateway.GetUsersOnlineStatusResp, error) {
if !tokenverify.IsAppManagerUid(ctx) {
return nil, errs.ErrNoPermission.Wrap("only app manager")
}
var resp msggateway.GetUsersOnlineStatusResp
for _, userID := range req.UserIDs {
clients, ok := s.LongConnServer.GetUserAllCons(userID)
if !ok {
continue
}
temp := new(msggateway.GetUsersOnlineStatusResp_SuccessResult)
temp.UserID = userID
for _, client := range clients {
if client != nil {
ps := new(msggateway.GetUsersOnlineStatusResp_SuccessDetail)
ps.Platform = constant.PlatformIDToName(client.platformID)
ps.Status = constant.OnlineStatus
ps.ConnID = client.connID
ps.IsBackground = client.isBackground
temp.Status = constant.OnlineStatus
temp.DetailPlatformStatus = append(temp.DetailPlatformStatus, ps)
}
}
if temp.Status == constant.OnlineStatus {
resp.SuccessResult = append(resp.SuccessResult, temp)
}
}
return &resp, nil
}
func (s *Server) OnlineBatchPushOneMsg(ctx context.Context, req *msggateway.OnlineBatchPushOneMsgReq) (*msggateway.OnlineBatchPushOneMsgResp, error) {
panic("implement me")
}
func (s *Server) SuperGroupOnlineBatchPushOneMsg(ctx context.Context, req *msggateway.OnlineBatchPushOneMsgReq) (*msggateway.OnlineBatchPushOneMsgResp, error) {
var singleUserResult []*msggateway.SingleMsgToUserResults
for _, v := range req.PushToUserIDs {
var resp []*msggateway.SingleMsgToUserPlatform
tempT := &msggateway.SingleMsgToUserResults{
UserID: v,
}
clients, ok := s.LongConnServer.GetUserAllCons(v)
if !ok {
continue
}
for _, client := range clients {
if client != nil {
temp := &msggateway.SingleMsgToUserPlatform{
RecvID: v,
RecvPlatFormID: int32(client.platformID),
}
if !client.isBackground {
err := client.PushMessage(ctx, req.MsgData)
if err != nil {
temp.ResultCode = -2
resp = append(resp, temp)
} else {
if utils.IsContainInt(client.platformID, s.pushTerminal) {
tempT.OnlinePush = true
prome.Inc(prome.MsgOnlinePushSuccessCounter)
resp = append(resp, temp)
}
}
} else {
temp.ResultCode = -3
resp = append(resp, temp)
}
}
}
tempT.Resp = resp
singleUserResult = append(singleUserResult, tempT)
}
return &msggateway.OnlineBatchPushOneMsgResp{
SinglePushResult: singleUserResult,
}, nil
}
func (s *Server) KickUserOffline(ctx context.Context, req *msggateway.KickUserOfflineReq) (*msggateway.KickUserOfflineResp, error) {
for _, v := range req.KickUserIDList {
if clients, _, ok := s.LongConnServer.GetUserPlatformCons(v, int(req.PlatformID)); ok {
for _, client := range clients {
err := client.KickOnlineMessage(ctx)
if err != nil {
return nil, err
}
}
}
}
return &msggateway.KickUserOfflineResp{}, nil
}
func (s *Server) MultiTerminalLoginCheck(ctx context.Context, req *msggateway.MultiTerminalLoginCheckReq) (*msggateway.MultiTerminalLoginCheckResp, error) {
//TODO implement me
panic("implement me")
}

View File

@ -3,49 +3,28 @@ package msggateway
import ( import (
"OpenIM/pkg/common/config" "OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant" "OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log"
"OpenIM/pkg/statistics"
"fmt" "fmt"
"sync" "sync"
"time"
prome "OpenIM/pkg/common/prome"
"github.com/go-playground/validator/v10"
) )
var ( func RunWsAndServer(rpcPort, wsPort, prometheusPort int) error {
rwLock *sync.RWMutex
validate *validator.Validate
ws WServer
rpcSvr RPCServer
sendMsgAllCount uint64
sendMsgFailedCount uint64
sendMsgSuccessCount uint64
userCount uint64
sendMsgAllCountLock sync.RWMutex
)
func Init(rpcPort, wsPort int) {
rwLock = new(sync.RWMutex)
validate = validator.New()
statistics.NewStatistics(&sendMsgAllCount, config.Config.ModuleName.LongConnSvrName, fmt.Sprintf("%d second recv to msg_gateway sendMsgCount", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
statistics.NewStatistics(&userCount, config.Config.ModuleName.LongConnSvrName, fmt.Sprintf("%d second add user conn", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
ws.onInit(wsPort)
rpcSvr.onInit(rpcPort)
initPrometheus()
}
func Run(prometheusPort int) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(3) wg.Add(1)
go ws.run() log.NewPrivateLog(constant.LogFileName)
go rpcSvr.run() fmt.Println("start rpc/msg_gateway server, port: ", rpcPort, wsPort, prometheusPort, ", OpenIM version: ", config.Version)
go func() { longServer, err := NewWsServer(
err := prome.StartPrometheusSrv(prometheusPort) WithPort(wsPort),
if err != nil { WithMaxConnNum(int64(config.Config.LongConnSvr.WebsocketMaxConnNum)),
panic(err) WithHandshakeTimeout(time.Duration(config.Config.LongConnSvr.WebsocketTimeOut)*time.Second),
} WithMessageMaxMsgLength(config.Config.LongConnSvr.WebsocketMaxMsgLen))
}() if err != nil {
return err
}
hubServer := NewServer(rpcPort, longServer)
go hubServer.Start()
go hubServer.LongConnServer.Run()
wg.Wait() wg.Wait()
return nil
} }

View File

@ -1,404 +0,0 @@
package msggateway
import (
"OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log"
"OpenIM/pkg/common/prome"
pbChat "OpenIM/pkg/proto/msg"
push "OpenIM/pkg/proto/push"
pbRtc "OpenIM/pkg/proto/rtc"
"OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils"
"bytes"
"context"
"encoding/gob"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
"google.golang.org/grpc"
"runtime"
)
func (ws *WServer) msgParse(conn *UserConn, binaryMsg []byte) {
b := bytes.NewBuffer(binaryMsg)
m := Req{}
dec := gob.NewDecoder(b)
err := dec.Decode(&m)
if err != nil {
log.NewError("", "ws Decode err", err.Error())
err = conn.Close()
if err != nil {
log.NewError("", "ws close err", err.Error())
}
return
}
if err := validate.Struct(m); err != nil {
log.NewError("", "ws args validate err", err.Error())
ws.sendErrMsg(conn, 201, err.Error(), m.ReqIdentifier, m.MsgIncr, m.OperationID)
return
}
log.NewInfo(m.OperationID, "Basic Info Authentication Success", m.SendID, m.MsgIncr, m.ReqIdentifier)
if m.SendID != conn.userID {
if err = conn.Close(); err != nil {
log.NewError(m.OperationID, "close ws conn failed", conn.userID, "send id", m.SendID, err.Error())
return
}
}
switch m.ReqIdentifier {
case constant.WSGetNewestSeq:
log.NewInfo(m.OperationID, "getSeqReq ", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.getSeqReq(conn, &m)
prome.Inc(prome.GetNewestSeqTotalCounter)
case constant.WSSendMsg:
log.NewInfo(m.OperationID, "sendMsgReq ", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.sendMsgReq(conn, &m)
prome.Inc(prome.MsgRecvTotalCounter)
case constant.WSSendSignalMsg:
log.NewInfo(m.OperationID, "sendSignalMsgReq ", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.sendSignalMsgReq(conn, &m)
case constant.WSPullMsgBySeqList:
log.NewInfo(m.OperationID, "pullMsgBySeqListReq ", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.pullMsgBySeqListReq(conn, &m)
prome.Inc(prome.PullMsgBySeqListTotalCounter)
case constant.WsLogoutMsg:
log.NewInfo(m.OperationID, "conn.Close()", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.userLogoutReq(conn, &m)
case constant.WsSetBackgroundStatus:
log.NewInfo(m.OperationID, "WsSetBackgroundStatus", m.SendID, m.MsgIncr, m.ReqIdentifier)
ws.setUserDeviceBackground(conn, &m)
default:
log.Error(m.OperationID, "ReqIdentifier failed ", m.SendID, m.MsgIncr, m.ReqIdentifier)
}
log.NewInfo(m.OperationID, "goroutine num is ", runtime.NumGoroutine())
}
func (ws *WServer) getSeqReq(conn *UserConn, m *Req) {
log.NewInfo(m.OperationID, "Ws call success to getNewSeq", m.MsgIncr, m.SendID, m.ReqIdentifier)
nReply := new(sdkws.GetMaxAndMinSeqResp)
isPass, errCode, errMsg, data := ws.argsValidate(m, constant.WSGetNewestSeq, m.OperationID)
log.Info(m.OperationID, "argsValidate ", isPass, errCode, errMsg)
if isPass {
rpcReq := sdkws.GetMaxAndMinSeqReq{}
rpcReq.GroupIDs = data.(sdkws.GetMaxAndMinSeqReq).GroupIDs
rpcReq.UserID = m.SendID
log.Debug(m.OperationID, "Ws call success to getMaxAndMinSeq", m.SendID, m.ReqIdentifier, m.MsgIncr, data.(sdkws.GetMaxAndMinSeqReq).GroupIDs)
var grpcConn *grpc.ClientConn
msgClient := pbChat.NewMsgClient(grpcConn)
rpcReply, err := msgClient.GetMaxAndMinSeq(context.Background(), &rpcReq)
if err != nil {
ws.getSeqResp(conn, m, nReply)
} else {
ws.getSeqResp(conn, m, rpcReply)
}
} else {
log.Error(m.OperationID, "argsValidate failed send resp: ", nReply.String())
ws.getSeqResp(conn, m, nReply)
}
}
func (ws *WServer) getSeqResp(conn *UserConn, m *Req, pb *sdkws.GetMaxAndMinSeqResp) {
b, _ := proto.Marshal(pb)
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
OperationID: m.OperationID,
Data: b,
}
log.Debug(m.OperationID, "getSeqResp come here req: ", pb.String(), "send resp: ",
mReply.ReqIdentifier, mReply.MsgIncr, mReply.ErrCode, mReply.ErrMsg)
ws.sendMsg(conn, mReply)
}
func (ws *WServer) pullMsgBySeqListReq(conn *UserConn, m *Req) {
log.NewInfo(m.OperationID, "Ws call success to pullMsgBySeqListReq start", m.SendID, m.ReqIdentifier, m.MsgIncr, string(m.Data))
nReply := new(sdkws.PullMessageBySeqsResp)
isPass, _, _, data := ws.argsValidate(m, constant.WSPullMsgBySeqList, m.OperationID)
if isPass {
rpcReq := sdkws.PullMessageBySeqsReq{}
rpcReq.Seqs = data.(sdkws.PullMessageBySeqsReq).Seqs
rpcReq.UserID = m.SendID
rpcReq.GroupSeqs = data.(sdkws.PullMessageBySeqsReq).GroupSeqs
log.NewInfo(m.OperationID, "Ws call success to pullMsgBySeqListReq middle", m.SendID, m.ReqIdentifier, m.MsgIncr, data.(sdkws.PullMessageBySeqsReq).Seqs)
var grpcConn *grpc.ClientConn
//grpcConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImMsgName, m.OperationID)
if grpcConn == nil {
ws.pullMsgBySeqListResp(conn, m, nReply)
return
}
msgClient := pbChat.NewMsgClient(grpcConn)
maxSizeOption := grpc.MaxCallRecvMsgSize(1024 * 1024 * 20)
reply, err := msgClient.PullMessageBySeqs(context.Background(), &rpcReq, maxSizeOption)
if err != nil {
ws.pullMsgBySeqListResp(conn, m, nReply)
} else {
//log.NewInfo(rpcReq.OperationID, "rpc call success to pullMsgBySeqListReq", reply.String(), len(reply.List))
ws.pullMsgBySeqListResp(conn, m, reply)
}
} else {
ws.pullMsgBySeqListResp(conn, m, nReply)
}
}
func (ws *WServer) pullMsgBySeqListResp(conn *UserConn, m *Req, pb *sdkws.PullMessageBySeqsResp) {
log.NewInfo(m.OperationID, "pullMsgBySeqListResp come here ", pb.String())
c, _ := proto.Marshal(pb)
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
//ErrCode: pb.GetErrCode(),
//ErrMsg: pb.GetErrMsg(),
OperationID: m.OperationID,
Data: c,
}
log.NewInfo(m.OperationID, "pullMsgBySeqListResp all data is ", mReply.ReqIdentifier, mReply.MsgIncr, mReply.ErrCode, mReply.ErrMsg,
len(mReply.Data))
ws.sendMsg(conn, mReply)
}
func (ws *WServer) userLogoutReq(conn *UserConn, m *Req) {
log.NewInfo(m.OperationID, "Ws call success to userLogoutReq start", m.SendID, m.ReqIdentifier, m.MsgIncr, string(m.Data))
rpcReq := push.DelUserPushTokenReq{}
rpcReq.UserID = m.SendID
rpcReq.PlatformID = conn.PlatformID
//rpcReq.OperationID = m.OperationID
var grpcConn *grpc.ClientConn
//grpcConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImPushName, m.OperationID)
if grpcConn == nil {
//errMsg := rpcReq.OperationID + "getcdv3.GetDefaultConn == nil"
//log.NewError(rpcReq.OperationID, errMsg)
ws.userLogoutResp(conn, m)
return
}
msgClient := push.NewPushMsgServiceClient(grpcConn)
_, err := msgClient.DelUserPushToken(context.Background(), &rpcReq)
if err != nil {
//log.NewError(rpcReq.OperationID, "DelUserPushToken err", err.Error())
ws.userLogoutResp(conn, m)
} else {
//log.NewInfo(rpcReq.OperationID, "rpc call success to DelUserPushToken", reply.String())
ws.userLogoutResp(conn, m)
}
ws.userLogoutResp(conn, m)
}
func (ws *WServer) userLogoutResp(conn *UserConn, m *Req) {
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
OperationID: m.OperationID,
}
ws.sendMsg(conn, mReply)
_ = conn.Close()
}
func (ws *WServer) sendMsgReq(conn *UserConn, m *Req) {
sendMsgAllCountLock.Lock()
sendMsgAllCount++
sendMsgAllCountLock.Unlock()
log.NewInfo(m.OperationID, "Ws call success to sendMsgReq start", m.MsgIncr, m.ReqIdentifier, m.SendID)
nReply := new(pbChat.SendMsgResp)
isPass, _, _, pData := ws.argsValidate(m, constant.WSSendMsg, m.OperationID)
if isPass {
data := pData.(sdkws.MsgData)
pbData := pbChat.SendMsgReq{
//Token: m.Token,
//OperationID: m.OperationID,
MsgData: &data,
}
log.NewInfo(m.OperationID, "Ws call success to sendMsgReq middle", m.ReqIdentifier, m.SendID, m.MsgIncr, data.String())
var grpcConn *grpc.ClientConn
//etcdConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImMsgName, m.OperationID)
if grpcConn == nil {
errMsg := m.OperationID + "getcdv3.GetDefaultConn == nil"
//nReply.ErrCode = 500
//nReply.ErrMsg = errMsg
log.NewError(m.OperationID, errMsg)
ws.sendMsgResp(conn, m, nReply)
return
}
client := pbChat.NewMsgClient(grpcConn)
reply, err := client.SendMsg(context.Background(), &pbData)
if err != nil {
//log.NewError(pbData.OperationID, "UserSendMsg err", err.Error())
//nReply.ErrCode = 200
//nReply.ErrMsg = err.Error()
ws.sendMsgResp(conn, m, nReply)
} else {
//log.NewInfo(pbData.OperationID, "rpc call success to sendMsgReq", reply.String())
ws.sendMsgResp(conn, m, reply)
}
} else {
//nReply.ErrCode = errCode
//nReply.ErrMsg = errMsg
ws.sendMsgResp(conn, m, nReply)
}
}
func (ws *WServer) sendMsgResp(conn *UserConn, m *Req, pb *pbChat.SendMsgResp) {
var mReplyData sdkws.UserSendMsgResp
mReplyData.ClientMsgID = pb.GetClientMsgID()
mReplyData.ServerMsgID = pb.GetServerMsgID()
mReplyData.SendTime = pb.GetSendTime()
b, _ := proto.Marshal(&mReplyData)
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
OperationID: m.OperationID,
Data: b,
}
ws.sendMsg(conn, mReply)
}
func (ws *WServer) sendSignalMsgReq(conn *UserConn, m *Req) {
log.NewInfo(m.OperationID, "Ws call success to sendSignalMsgReq start", m.MsgIncr, m.ReqIdentifier, m.SendID, string(m.Data))
//nReply := new(pbChat.SendMsgResp)
isPass, errCode, errMsg, pData := ws.argsValidate(m, constant.WSSendSignalMsg, m.OperationID)
if isPass {
signalResp := sdkws.SignalResp{}
var grpcConn *grpc.ClientConn
//etcdConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImRtcName, m.OperationID)
if grpcConn == nil {
errMsg := m.OperationID + "getcdv3.GetDefaultConn == nil"
log.NewError(m.OperationID, errMsg)
ws.sendSignalMsgResp(conn, 204, errMsg, m, &signalResp)
return
}
rtcClient := pbRtc.NewRtcServiceClient(grpcConn)
req := &pbRtc.SignalMessageAssembleReq{
SignalReq: pData.(*sdkws.SignalReq),
OperationID: m.OperationID,
}
respPb, err := rtcClient.SignalMessageAssemble(context.Background(), req)
if err != nil {
log.NewError(m.OperationID, utils.GetSelfFuncName(), "SignalMessageAssemble", err.Error(), config.Config.RpcRegisterName.OpenImRtcName)
ws.sendSignalMsgResp(conn, 204, "grpc SignalMessageAssemble failed: "+err.Error(), m, &signalResp)
return
}
signalResp.Payload = respPb.SignalResp.Payload
msgData := sdkws.MsgData{}
utils.CopyStructFields(&msgData, respPb.MsgData)
log.NewInfo(m.OperationID, utils.GetSelfFuncName(), respPb.String())
if respPb.IsPass {
pbData := pbChat.SendMsgReq{
//Token: m.Token,
//OperationID: m.OperationID,
MsgData: &msgData,
}
log.NewInfo(m.OperationID, utils.GetSelfFuncName(), "pbData: ", pbData)
log.NewInfo(m.OperationID, "Ws call success to sendSignalMsgReq middle", m.ReqIdentifier, m.SendID, m.MsgIncr, msgData)
var grpcConn *grpc.ClientConn
//etcdConn := rpc.GetDefaultConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImMsgName, m.OperationID)
if grpcConn == nil {
errMsg := m.OperationID + "getcdv3.GetDefaultConn == nil"
log.NewError(m.OperationID, errMsg)
ws.sendSignalMsgResp(conn, 200, errMsg, m, &signalResp)
return
}
client := pbChat.NewMsgClient(grpcConn)
_, err := client.SendMsg(context.Background(), &pbData)
if err != nil {
//log.NewError(pbData.OperationID, utils.GetSelfFuncName(), "rpc sendMsg err", err.Error())
//nReply.ErrCode = 200
//nReply.ErrMsg = err.Error()
ws.sendSignalMsgResp(conn, 200, err.Error(), m, &signalResp)
} else {
//log.NewInfo(pbData.OperationID, "rpc call success to sendMsgReq", reply.String(), signalResp.String(), m)
ws.sendSignalMsgResp(conn, 0, "", m, &signalResp)
}
} else {
//log.NewError(m.OperationID, utils.GetSelfFuncName(), respPb.IsPass, respPb.CommonResp.ErrCode, respPb.CommonResp.ErrMsg)
//ws.sendSignalMsgResp(conn, respPb.CommonResp.ErrCode, respPb.CommonResp.ErrMsg, m, &signalResp)
}
} else {
ws.sendSignalMsgResp(conn, errCode, errMsg, m, nil)
}
}
func (ws *WServer) sendSignalMsgResp(conn *UserConn, errCode int32, errMsg string, m *Req, pb *sdkws.SignalResp) {
// := make(map[string]interface{})
log.Debug(m.OperationID, "sendSignalMsgResp is", pb.String())
b, _ := proto.Marshal(pb)
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
ErrCode: errCode,
ErrMsg: errMsg,
OperationID: m.OperationID,
Data: b,
}
ws.sendMsg(conn, mReply)
}
func (ws *WServer) sendMsg(conn *UserConn, mReply interface{}) {
var b bytes.Buffer
enc := gob.NewEncoder(&b)
err := enc.Encode(mReply)
if err != nil {
// uid, platform := ws.getUserUid(conn)
log.NewError(mReply.(Resp).OperationID, mReply.(Resp).ReqIdentifier, mReply.(Resp).ErrCode, mReply.(Resp).ErrMsg, "Encode Msg error", conn.RemoteAddr().String(), err.Error())
return
}
err = ws.writeMsg(conn, websocket.BinaryMessage, b.Bytes())
if err != nil {
// uid, platform := ws.getUserUid(conn)
log.NewError(mReply.(Resp).OperationID, mReply.(Resp).ReqIdentifier, mReply.(Resp).ErrCode, mReply.(Resp).ErrMsg, "ws writeMsg error", conn.RemoteAddr().String(), err.Error())
} else {
log.Debug(mReply.(Resp).OperationID, mReply.(Resp).ReqIdentifier, mReply.(Resp).ErrCode, mReply.(Resp).ErrMsg, "ws write response success")
}
}
func (ws *WServer) sendErrMsg(conn *UserConn, errCode int32, errMsg string, reqIdentifier int32, msgIncr string, operationID string) {
mReply := Resp{
ReqIdentifier: reqIdentifier,
MsgIncr: msgIncr,
ErrCode: errCode,
ErrMsg: errMsg,
OperationID: operationID,
}
ws.sendMsg(conn, mReply)
}
func SetTokenKicked(userID string, platformID int, operationID string) {
//m, err := db.DB.GetTokenMapByUidPid(userID, constant.PlatformIDToName(platformID))
//if err != nil {
// log.Error(operationID, "GetTokenMapByUidPid failed ", err.Error(), userID, constant.PlatformIDToName(platformID))
// return
//}
//for k, _ := range m {
// m[k] = constant.KickedToken
//}
//err = db.DB.SetTokenMapByUidPid(userID, platformID, m)
//if err != nil {
// log.Error(operationID, "SetTokenMapByUidPid failed ", err.Error(), userID, constant.PlatformIDToName(platformID))
// return
//}
}
func (ws *WServer) setUserDeviceBackground(conn *UserConn, m *Req) {
isPass, errCode, errMsg, pData := ws.argsValidate(m, constant.WsSetBackgroundStatus, m.OperationID)
if isPass {
req := pData.(*sdkws.SetAppBackgroundStatusReq)
conn.IsBackground = req.IsBackground
//callbackResp := callbackUserOnline(m.OperationID, conn.userID, int(conn.PlatformID), conn.token, conn.IsBackground, conn.connID)
//if callbackResp.ErrCode != 0 {
// log.NewError(m.OperationID, utils.GetSelfFuncName(), "callbackUserOffline failed", callbackResp)
//}
log.NewInfo(m.OperationID, "SetUserDeviceBackground", "success", *conn, req.IsBackground)
}
ws.setUserDeviceBackgroundResp(conn, m, errCode, errMsg)
}
func (ws *WServer) setUserDeviceBackgroundResp(conn *UserConn, m *Req, errCode int32, errMsg string) {
mReply := Resp{
ReqIdentifier: m.ReqIdentifier,
MsgIncr: m.MsgIncr,
OperationID: m.OperationID,
ErrCode: errCode,
ErrMsg: errMsg,
}
ws.sendMsg(conn, mReply)
}

View File

@ -1,4 +1,4 @@
package new package msggateway
import ( import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"

View File

@ -1,9 +1,8 @@
package new package msggateway
import ( import (
"OpenIM/internal/common/notification" "OpenIM/internal/common/notification"
"OpenIM/pkg/proto/msg" "OpenIM/pkg/proto/msg"
pbRtc "OpenIM/pkg/proto/rtc"
"OpenIM/pkg/proto/sdkws" "OpenIM/pkg/proto/sdkws"
"context" "context"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
@ -86,7 +85,7 @@ func (g GrpcHandler) SendMessage(context context.Context, data Req) ([]byte, err
} }
func (g GrpcHandler) SendSignalMessage(context context.Context, data Req) ([]byte, error) { func (g GrpcHandler) SendSignalMessage(context context.Context, data Req) ([]byte, error) {
signalReq := pbRtc.SignalReq{} signalReq := sdkws.SignalReq{}
if err := proto.Unmarshal(data.Data, &signalReq); err != nil { if err := proto.Unmarshal(data.Data, &signalReq); err != nil {
return nil, err return nil, err
} }
@ -107,7 +106,7 @@ func (g GrpcHandler) SendSignalMessage(context context.Context, data Req) ([]byt
} }
func (g GrpcHandler) PullMessageBySeqList(context context.Context, data Req) ([]byte, error) { func (g GrpcHandler) PullMessageBySeqList(context context.Context, data Req) ([]byte, error) {
req := sdkws.PullMessageBySeqListReq{} req := sdkws.PullMessageBySeqsReq{}
if err := proto.Unmarshal(data.Data, &req); err != nil { if err := proto.Unmarshal(data.Data, &req); err != nil {
return nil, err return nil, err
} }

View File

@ -1,55 +1,71 @@
package new package msggateway
import ( import (
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/tokenverify" "OpenIM/pkg/common/tokenverify"
"OpenIM/pkg/errs" "OpenIM/pkg/errs"
"OpenIM/pkg/utils" "OpenIM/pkg/utils"
"errors" "errors"
"fmt" "fmt"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/gorilla/websocket"
"net/http" "net/http"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
) )
type LongConnServer interface {
Run() error
wsHandler(w http.ResponseWriter, r *http.Request)
GetUserAllCons(userID string) ([]*Client, bool)
GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool)
Validate(s interface{}) error
UnRegister(c *Client)
Compressor
Encoder
MessageHandler
}
var bufferPool = sync.Pool{ var bufferPool = sync.Pool{
New: func() interface{} { New: func() interface{} {
return make([]byte, 1024) return make([]byte, 1024)
}, },
} }
type LongConnServer interface {
Run() error
}
type Server struct {
rpcPort int
wsMaxConnNum int
longConnServer *LongConnServer
//rpcServer *RpcServer
}
type WsServer struct { type WsServer struct {
port int port int
wsMaxConnNum int64 wsMaxConnNum int64
wsUpGrader *websocket.Upgrader
registerChan chan *Client registerChan chan *Client
unregisterChan chan *Client unregisterChan chan *Client
clients *UserMap clients *UserMap
clientPool sync.Pool clientPool sync.Pool
onlineUserNum int64 onlineUserNum int64
onlineUserConnNum int64 onlineUserConnNum int64
gzipCompressor Compressor
encoder Encoder
handler MessageHandler
handshakeTimeout time.Duration handshakeTimeout time.Duration
readBufferSize, WriteBufferSize int readBufferSize, WriteBufferSize int
validate *validator.Validate validate *validator.Validate
Compressor
Encoder
MessageHandler
} }
func newWsServer(opts ...Option) (*WsServer, error) { func (ws *WsServer) UnRegister(c *Client) {
ws.unregisterChan <- c
}
func (ws *WsServer) Validate(s interface{}) error {
//TODO implement me
panic("implement me")
}
func (ws *WsServer) GetUserAllCons(userID string) ([]*Client, bool) {
return ws.clients.GetAll(userID)
}
func (ws *WsServer) GetUserPlatformCons(userID string, platform int) ([]*Client, bool, bool) {
return ws.clients.Get(userID, platform)
}
func NewWsServer(opts ...Option) (*WsServer, error) {
var config configs var config configs
for _, o := range opts { for _, o := range opts {
o(&config) o(&config)
@ -58,6 +74,7 @@ func newWsServer(opts ...Option) (*WsServer, error) {
return nil, errors.New("port not allow to listen") return nil, errors.New("port not allow to listen")
} }
v := validator.New()
return &WsServer{ return &WsServer{
port: config.port, port: config.port,
wsMaxConnNum: config.maxConnNum, wsMaxConnNum: config.maxConnNum,
@ -68,8 +85,13 @@ func newWsServer(opts ...Option) (*WsServer, error) {
return new(Client) return new(Client)
}, },
}, },
validate: validator.New(), registerChan: make(chan *Client, 1000),
clients: newUserMap(), unregisterChan: make(chan *Client, 1000),
validate: v,
clients: newUserMap(),
Compressor: NewGzipCompressor(),
Encoder: NewGobEncoder(),
MessageHandler: NewGrpcHandler(v, nil),
//handler: NewGrpcHandler(validate), //handler: NewGrpcHandler(validate),
}, nil }, nil
} }
@ -93,7 +115,7 @@ func (ws *WsServer) registerClient(client *Client) {
var ( var (
userOK bool userOK bool
clientOK bool clientOK bool
cli *Client cli []*Client
) )
cli, userOK, clientOK = ws.clients.Get(client.userID, client.platformID) cli, userOK, clientOK = ws.clients.Get(client.userID, client.platformID)
if !userOK { if !userOK {
@ -116,10 +138,11 @@ func (ws *WsServer) registerClient(client *Client) {
} }
func (ws *WsServer) multiTerminalLoginChecker(client *Client) { func (ws *WsServer) multiTerminalLoginChecker(client []*Client) {
} }
func (ws *WsServer) unregisterClient(client *Client) { func (ws *WsServer) unregisterClient(client *Client) {
defer ws.clientPool.Put(client)
isDeleteUser := ws.clients.delete(client.userID, client.platformID) isDeleteUser := ws.clients.delete(client.userID, client.platformID)
if isDeleteUser { if isDeleteUser {
atomic.AddInt64(&ws.onlineUserNum, -1) atomic.AddInt64(&ws.onlineUserNum, -1)
@ -141,20 +164,19 @@ func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) {
platformID string platformID string
exists bool exists bool
compression bool compression bool
compressor Compressor
) )
token, exists = context.Query(TOKEN) token, exists = context.Query(Token)
if !exists { if !exists {
httpError(context, errs.ErrConnArgsErr) httpError(context, errs.ErrConnArgsErr)
return return
} }
userID, exists = context.Query(WS_USERID) userID, exists = context.Query(WsUserID)
if !exists { if !exists {
httpError(context, errs.ErrConnArgsErr) httpError(context, errs.ErrConnArgsErr)
return return
} }
platformID, exists = context.Query(PLATFORM_ID) platformID, exists = context.Query(PlatformID)
if !exists { if !exists {
httpError(context, errs.ErrConnArgsErr) httpError(context, errs.ErrConnArgsErr)
return return
@ -164,28 +186,26 @@ func (ws *WsServer) wsHandler(w http.ResponseWriter, r *http.Request) {
httpError(context, err) httpError(context, err)
return return
} }
wsLongConn := newGWebSocket(constant.WebSocket, ws.handshakeTimeout, ws.readBufferSize) wsLongConn := newGWebSocket(WebSocket, ws.handshakeTimeout, ws.readBufferSize)
err = wsLongConn.GenerateLongConn(w, r) err = wsLongConn.GenerateLongConn(w, r)
if err != nil { if err != nil {
httpError(context, err) httpError(context, err)
return return
} }
compressProtoc, exists := context.Query(COMPRESSION) compressProtoc, exists := context.Query(Compression)
if exists { if exists {
if compressProtoc == GZIP_COMPRESSION_PROTOCAL { if compressProtoc == GzipCompressionProtocol {
compression = true compression = true
compressor = ws.gzipCompressor
} }
} }
compressProtoc, exists = context.GetHeader(COMPRESSION) compressProtoc, exists = context.GetHeader(Compression)
if exists { if exists {
if compressProtoc == GZIP_COMPRESSION_PROTOCAL { if compressProtoc == GzipCompressionProtocol {
compression = true compression = true
compressor = ws.gzipCompressor
} }
} }
client := ws.clientPool.Get().(*Client) client := ws.clientPool.Get().(*Client)
client.ResetClient(context, wsLongConn, compression, compressor, ws.encoder, ws.handler, ws.unregisterChan, ws.validate) client.ResetClient(context, wsLongConn, compression, ws)
ws.registerChan <- client ws.registerChan <- client
go client.readMessage() go client.readMessage()
} }

View File

@ -1,12 +0,0 @@
package new
const (
WS_USERID = "sendID"
COMMON_USERID = "userID"
PLATFORM_ID = "platformID"
CONN_ID = "connID"
TOKEN = "token"
OPERATION_ID = "operationID"
COMPRESSION = "compression"
GZIP_COMPRESSION_PROTOCAL = "gzip"
)

View File

@ -1,4 +1,4 @@
package new package msggateway
import "time" import "time"

View File

@ -1,373 +0,0 @@
package msggateway
import (
"OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log"
"OpenIM/pkg/common/prome"
"OpenIM/pkg/common/tokenverify"
"OpenIM/pkg/proto/msggateway"
"OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils"
"bytes"
"context"
"encoding/gob"
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
"google.golang.org/grpc"
"net"
"strconv"
"strings"
)
type RPCServer struct {
rpcPort int
rpcRegisterName string
etcdSchema string
etcdAddr []string
platformList []int
pushTerminal []int
target string
}
func initPrometheus() {
prome.NewMsgRecvTotalCounter()
prome.NewGetNewestSeqTotalCounter()
prome.NewPullMsgBySeqListTotalCounter()
prome.NewMsgOnlinePushSuccessCounter()
prome.NewOnlineUserGauges()
//prome.NewSingleChatMsgRecvSuccessCounter()
//prome.NewGroupChatMsgRecvSuccessCounter()
//prome.NewWorkSuperGroupChatMsgRecvSuccessCounter()
}
func (r *RPCServer) onInit(rpcPort int) {
r.rpcPort = rpcPort
r.rpcRegisterName = config.Config.RpcRegisterName.OpenImMessageGatewayName
r.platformList = genPlatformArray()
r.pushTerminal = []int{constant.IOSPlatformID, constant.AndroidPlatformID}
}
func (r *RPCServer) run() {
listenIP := ""
if config.Config.ListenIP == "" {
listenIP = constant.LocalHost
} else {
listenIP = config.Config.ListenIP
}
address := listenIP + ":" + strconv.Itoa(r.rpcPort)
listener, err := net.Listen("tcp", address)
if err != nil {
panic("listening err:" + err.Error() + r.rpcRegisterName)
}
defer listener.Close()
var grpcOpts []grpc.ServerOption
if config.Config.Prometheus.Enable {
prome.NewGrpcRequestCounter()
prome.NewGrpcRequestFailedCounter()
prome.NewGrpcRequestSuccessCounter()
grpcOpts = append(grpcOpts, []grpc.ServerOption{
// grpc.UnaryInterceptor(prome.UnaryServerInterceptorProme),
grpc.StreamInterceptor(grpcPrometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpcPrometheus.UnaryServerInterceptor),
}...)
}
srv := grpc.NewServer(grpcOpts...)
defer srv.GracefulStop()
msggateway.RegisterMsgGatewayServer(srv, r)
rpcRegisterIP := config.Config.RpcRegisterIP
if config.Config.RpcRegisterIP == "" {
rpcRegisterIP, err = utils.GetLocalIP()
if err != nil {
log.Error("", "GetLocalIP failed ", err.Error())
}
}
err = rpc.RegisterEtcd4Unique(r.etcdSchema, strings.Join(r.etcdAddr, ","), rpcRegisterIP, r.rpcPort, r.rpcRegisterName, 10)
if err != nil {
log.Error("", "register push message rpc to etcd err", "", "err", err.Error(), r.etcdSchema, strings.Join(r.etcdAddr, ","), rpcRegisterIP, r.rpcPort, r.rpcRegisterName)
panic(utils.Wrap(err, "register msg_gataway module rpc to etcd err"))
}
r.target = rpc.GetTarget(r.etcdSchema, rpcRegisterIP, r.rpcPort, r.rpcRegisterName)
err = srv.Serve(listener)
if err != nil {
log.Error("", "push message rpc listening err", "", "err", err.Error())
return
}
}
func (r *RPCServer) OnlinePushMsg(ctx context.Context, in *msggateway.OnlinePushMsgReq) (*msggateway.OnlinePushMsgResp, error) {
log.NewInfo(in.OperationID, "PushMsgToUser is arriving", in.String())
var resp []*msggateway.SingleMsgToUserPlatform
msgBytes, _ := proto.Marshal(in.MsgData)
mReply := Resp{
ReqIdentifier: constant.WSPushMsg,
OperationID: in.OperationID,
Data: msgBytes,
}
var replyBytes bytes.Buffer
enc := gob.NewEncoder(&replyBytes)
err := enc.Encode(mReply)
if err != nil {
log.NewError(in.OperationID, "data encode err", err.Error())
}
var tag bool
recvID := in.PushToUserID
for _, v := range r.platformList {
if conn := ws.getUserConn(recvID, v); conn != nil {
tag = true
resultCode := sendMsgToUser(conn, replyBytes.Bytes(), in, v, recvID)
temp := &msggateway.SingleMsgToUserPlatform{
ResultCode: resultCode,
RecvID: recvID,
RecvPlatFormID: int32(v),
}
resp = append(resp, temp)
} else {
temp := &msggateway.SingleMsgToUserPlatform{
ResultCode: -1,
RecvID: recvID,
RecvPlatFormID: int32(v),
}
resp = append(resp, temp)
}
}
if !tag {
log.NewDebug(in.OperationID, "push err ,no matched ws conn not in map", in.String())
}
return &msggateway.OnlinePushMsgResp{
Resp: resp,
}, nil
}
func (r *RPCServer) GetUsersOnlineStatus(_ context.Context, req *msggateway.GetUsersOnlineStatusReq) (*msggateway.GetUsersOnlineStatusResp, error) {
log.NewInfo(req.OperationID, "rpc GetUsersOnlineStatus arrived server", req.String())
if !tokenverify.IsManagerUserID(req.OpUserID) {
log.NewError(req.OperationID, "no permission GetUsersOnlineStatus ", req.OpUserID)
return &msggateway.GetUsersOnlineStatusResp{ErrCode: errs.ErrAccess.ErrCode, ErrMsg: errs.ErrAccess.ErrMsg}, nil
}
var resp msggateway.GetUsersOnlineStatusResp
for _, userID := range req.UserIDList {
temp := new(msggateway.GetUsersOnlineStatusResp_SuccessResult)
temp.UserID = userID
userConnMap := ws.getUserAllCons(userID)
for platform, userConn := range userConnMap {
if userConn != nil {
ps := new(msggateway.GetUsersOnlineStatusResp_SuccessDetail)
ps.Platform = constant.PlatformIDToName(platform)
ps.Status = constant.OnlineStatus
ps.ConnID = userConn.connID
ps.IsBackground = userConn.IsBackground
temp.Status = constant.OnlineStatus
temp.DetailPlatformStatus = append(temp.DetailPlatformStatus, ps)
}
}
if temp.Status == constant.OnlineStatus {
resp.SuccessResult = append(resp.SuccessResult, temp)
}
}
log.NewInfo(req.OperationID, "GetUsersOnlineStatus rpc return ", resp.String())
return &resp, nil
}
func (r *RPCServer) SuperGroupOnlineBatchPushOneMsg(_ context.Context, req *msggateway.OnlineBatchPushOneMsgReq) (*msggateway.OnlineBatchPushOneMsgResp, error) {
log.NewInfo(req.OperationID, "BatchPushMsgToUser is arriving", req.String())
var singleUserResult []*msggateway.SingleMsgToUserResultList
//r.GetBatchMsgForPush(req.OperationID,req.MsgData,req.PushToUserIDList,)
msgBytes, _ := proto.Marshal(req.MsgData)
mReply := Resp{
ReqIdentifier: constant.WSPushMsg,
OperationID: req.OperationID,
Data: msgBytes,
}
var replyBytes bytes.Buffer
enc := gob.NewEncoder(&replyBytes)
err := enc.Encode(mReply)
if err != nil {
log.NewError(req.OperationID, "data encode err", err.Error())
}
for _, v := range req.PushToUserIDList {
var resp []*msggateway.SingleMsgToUserPlatform
tempT := &msggateway.SingleMsgToUserResultList{
UserID: v,
}
userConnMap := ws.getUserAllCons(v)
for platform, userConn := range userConnMap {
if userConn != nil {
temp := &msggateway.SingleMsgToUserPlatform{
RecvID: v,
RecvPlatFormID: int32(platform),
}
if !userConn.IsBackground {
resultCode := sendMsgBatchToUser(userConn, replyBytes.Bytes(), req, platform, v)
if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) {
tempT.OnlinePush = true
prome.Inc(prome.MsgOnlinePushSuccessCounter)
log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recvPlatForm", constant.PlatformIDToName(platform), "recvID", v)
temp.ResultCode = resultCode
resp = append(resp, temp)
}
} else {
temp.ResultCode = -2
resp = append(resp, temp)
}
}
}
tempT.Resp = resp
singleUserResult = append(singleUserResult, tempT)
}
return &msggateway.OnlineBatchPushOneMsgResp{
SinglePushResult: singleUserResult,
}, nil
}
func (r *RPCServer) OnlineBatchPushOneMsg(_ context.Context, req *msggateway.OnlineBatchPushOneMsgReq) (*msggateway.OnlineBatchPushOneMsgResp, error) {
log.NewInfo(req.OperationID, "BatchPushMsgToUser is arriving", req.String())
var singleUserResult []*msggateway.SingleMsgToUserResultList
for _, v := range req.PushToUserIDList {
var resp []*msggateway.SingleMsgToUserPlatform
tempT := &msggateway.SingleMsgToUserResultList{
UserID: v,
}
userConnMap := ws.getUserAllCons(v)
var platformList []int
for k, _ := range userConnMap {
platformList = append(platformList, k)
}
log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms begin", req.MsgData.Seq, v, platformList, req.MsgData.String())
needPushMapList := r.GetSingleUserMsgForPushPlatforms(req.OperationID, req.MsgData, v, platformList)
log.Debug(req.OperationID, "GetSingleUserMsgForPushPlatforms end", req.MsgData.Seq, v, platformList, len(needPushMapList))
for platform, list := range needPushMapList {
if list != nil {
log.Debug(req.OperationID, "needPushMapList ", "userID: ", v, "platform: ", platform, "push msg num:")
//for _, v := range list {
// log.Debug(req.OperationID, "req.MsgData.MsgDataList begin", "len: ", len(req.MsgData.MsgDataList), v.String())
// req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v)
// log.Debug(req.OperationID, "req.MsgData.MsgDataList end", "len: ", len(req.MsgData.MsgDataList))
//}
msgBytes, err := proto.Marshal(list)
if err != nil {
log.Error(req.OperationID, "proto marshal err", err.Error())
continue
}
req.MsgData.MsgDataList = msgBytes
//req.MsgData.MsgDataList = append(req.MsgData.MsgDataList, v)
log.Debug(req.OperationID, "r.encodeWsData no string")
//log.Debug(req.OperationID, "r.encodeWsData data0 list ", req.MsgData.MsgDataList[0].String())
log.Debug(req.OperationID, "r.encodeWsData ", req.MsgData.String())
replyBytes, err := r.encodeWsData(req.MsgData, req.OperationID)
if err != nil {
log.Error(req.OperationID, "encodeWsData failed ", req.MsgData.String())
continue
}
log.Debug(req.OperationID, "encodeWsData", "len: ", replyBytes.Len())
resultCode := sendMsgBatchToUser(userConnMap[platform], replyBytes.Bytes(), req, platform, v)
if resultCode == 0 && utils.IsContainInt(platform, r.pushTerminal) {
tempT.OnlinePush = true
log.Info(req.OperationID, "PushSuperMsgToUser is success By Ws", "args", req.String(), "recv PlatForm", constant.PlatformIDToName(platform), "recvID", v)
temp := &msggateway.SingleMsgToUserPlatform{
ResultCode: resultCode,
RecvID: v,
RecvPlatFormID: int32(platform),
}
resp = append(resp, temp)
}
} else {
if utils.IsContainInt(platform, r.pushTerminal) {
tempT.OnlinePush = true
temp := &msggateway.SingleMsgToUserPlatform{
ResultCode: 0,
RecvID: v,
RecvPlatFormID: int32(platform),
}
resp = append(resp, temp)
}
}
}
tempT.Resp = resp
singleUserResult = append(singleUserResult, tempT)
}
return &msggateway.OnlineBatchPushOneMsgResp{
SinglePushResult: singleUserResult,
}, nil
}
func (r *RPCServer) encodeWsData(wsData *sdkws.MsgData, operationID string) (bytes.Buffer, error) {
log.Debug(operationID, "encodeWsData begin", wsData.String())
msgBytes, err := proto.Marshal(wsData)
if err != nil {
log.NewError(operationID, "Marshal", err.Error())
return bytes.Buffer{}, utils.Wrap(err, "")
}
log.Debug(operationID, "encodeWsData begin", wsData.String())
mReply := Resp{
ReqIdentifier: constant.WSPushMsg,
OperationID: operationID,
Data: msgBytes,
}
var replyBytes bytes.Buffer
enc := gob.NewEncoder(&replyBytes)
err = enc.Encode(mReply)
if err != nil {
log.NewError(operationID, "data encode err", err.Error())
return bytes.Buffer{}, utils.Wrap(err, "")
}
return replyBytes, nil
}
func (r *RPCServer) KickUserOffline(_ context.Context, req *msggateway.KickUserOfflineReq) (*msggateway.KickUserOfflineResp, error) {
log.NewInfo(req.OperationID, "KickUserOffline is arriving", req.String())
for _, v := range req.KickUserIDList {
log.NewWarn(req.OperationID, "SetTokenKicked ", v, req.PlatformID, req.OperationID)
SetTokenKicked(v, int(req.PlatformID), req.OperationID)
oldConnMap := ws.getUserAllCons(v)
if conn, ok := oldConnMap[int(req.PlatformID)]; ok { // user->map[platform->conn]
log.NewWarn(req.OperationID, "send kick msg, close connection ", req.PlatformID, v)
ws.sendKickMsg(conn)
conn.Close()
}
}
return &msggateway.KickUserOfflineResp{}, nil
}
func (r *RPCServer) MultiTerminalLoginCheck(ctx context.Context, req *msggateway.MultiTerminalLoginCheckReq) (*msggateway.MultiTerminalLoginCheckResp, error) {
ws.MultiTerminalLoginCheckerWithLock(req.UserID, int(req.PlatformID), req.Token, req.OperationID)
return &msggateway.MultiTerminalLoginCheckResp{}, nil
}
func sendMsgToUser(conn *UserConn, bMsg []byte, in *msggateway.OnlinePushMsgReq, RecvPlatForm int, RecvID string) (ResultCode int64) {
err := ws.writeMsg(conn, websocket.BinaryMessage, bMsg)
if err != nil {
log.NewError(in.OperationID, "PushMsgToUser is failed By Ws", "Addr", conn.RemoteAddr().String(),
"error", err, "senderPlatform", constant.PlatformIDToName(int(in.MsgData.SenderPlatformID)), "recvPlatform", RecvPlatForm, "args", in.String(), "recvID", RecvID)
ResultCode = -2
return ResultCode
} else {
log.NewDebug(in.OperationID, "PushMsgToUser is success By Ws", "args", in.String(), "recvPlatForm", RecvPlatForm, "recvID", RecvID)
ResultCode = 0
return ResultCode
}
}
func sendMsgBatchToUser(conn *UserConn, bMsg []byte, in *msggateway.OnlineBatchPushOneMsgReq, RecvPlatForm int, RecvID string) (ResultCode int64) {
err := ws.writeMsg(conn, websocket.BinaryMessage, bMsg)
if err != nil {
log.NewError(in.OperationID, "PushMsgToUser is failed By Ws", "Addr", conn.RemoteAddr().String(),
"error", err, "senderPlatform", constant.PlatformIDToName(int(in.MsgData.SenderPlatformID)), "recv Platform", RecvPlatForm, "args", in.String(), "recvID", RecvID)
ResultCode = -2
return ResultCode
} else {
log.NewDebug(in.OperationID, "PushMsgToUser is success By Ws", "args", in.String(), "recv PlatForm", RecvPlatForm, "recvID", RecvID)
ResultCode = 0
return ResultCode
}
}
func genPlatformArray() (array []int) {
for i := 1; i <= constant.LinuxPlatformID; i++ {
array = append(array, i)
}
return array
}

View File

@ -1,4 +1,4 @@
package new package msggateway
import "sync" import "sync"
@ -16,15 +16,20 @@ func (u *UserMap) GetAll(key string) ([]*Client, bool) {
} }
return nil, ok return nil, ok
} }
func (u *UserMap) Get(key string, platformID int) (*Client, bool, bool) { func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
allClients, userExisted := u.m.Load(key) allClients, userExisted := u.m.Load(key)
if userExisted { if userExisted {
var clients []*Client
for _, client := range allClients.([]*Client) { for _, client := range allClients.([]*Client) {
if client.platformID == platformID { if client.platformID == platformID {
return client, userExisted, true clients = append(clients, client)
} }
} }
return nil, userExisted, false if len(clients) > 0 {
return clients, userExisted, true
}
return clients, userExisted, false
} }
return nil, userExisted, false return nil, userExisted, false
} }
@ -35,7 +40,7 @@ func (u *UserMap) Set(key string, v *Client) {
oldClients = append(oldClients, v) oldClients = append(oldClients, v)
u.m.Store(key, oldClients) u.m.Store(key, oldClients)
} else { } else {
clients := make([]*Client, 3) var clients []*Client
clients = append(clients, v) clients = append(clients, v)
u.m.Store(key, clients) u.m.Store(key, clients)
} }
@ -44,7 +49,7 @@ func (u *UserMap) delete(key string, platformID int) (isDeleteUser bool) {
allClients, existed := u.m.Load(key) allClients, existed := u.m.Load(key)
if existed { if existed {
oldClients := allClients.([]*Client) oldClients := allClients.([]*Client)
a := make([]*Client, 3) var a []*Client
for _, client := range oldClients { for _, client := range oldClients {
if client.platformID != platformID { if client.platformID != platformID {
a = append(a, client) a = append(a, client)

View File

@ -1,125 +0,0 @@
/*
** description("").
** copyright('OpenIM,www.OpenIM.io').
** author("fg,Gordon@tuoyun.net").
** time(2021/5/21 15:29).
*/
package msggateway
import (
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log"
pbRtc "OpenIM/pkg/proto/rtc"
sdkws "OpenIM/pkg/proto/sdkws"
"github.com/golang/protobuf/proto"
)
type Req struct {
ReqIdentifier int32 `json:"reqIdentifier" validate:"required"`
Token string `json:"token" `
SendID string `json:"sendID" validate:"required"`
OperationID string `json:"operationID" validate:"required"`
MsgIncr string `json:"msgIncr" validate:"required"`
Data []byte `json:"data"`
}
type Resp struct {
ReqIdentifier int32 `json:"reqIdentifier"`
MsgIncr string `json:"msgIncr"`
OperationID string `json:"operationID"`
ErrCode int32 `json:"errCode"`
ErrMsg string `json:"errMsg"`
Data []byte `json:"data"`
}
type SeqData struct {
SeqBegin int64 `mapstructure:"seqBegin" validate:"required"`
SeqEnd int64 `mapstructure:"seqEnd" validate:"required"`
}
type MsgData struct {
PlatformID int32 `mapstructure:"platformID" validate:"required"`
SessionType int32 `mapstructure:"sessionType" validate:"required"`
MsgFrom int32 `mapstructure:"msgFrom" validate:"required"`
ContentType int32 `mapstructure:"contentType" validate:"required"`
RecvID string `mapstructure:"recvID" validate:"required"`
ForceList []string `mapstructure:"forceList"`
Content string `mapstructure:"content" validate:"required"`
Options map[string]interface{} `mapstructure:"options" validate:"required"`
ClientMsgID string `mapstructure:"clientMsgID" validate:"required"`
OfflineInfo map[string]interface{} `mapstructure:"offlineInfo" validate:"required"`
Ext map[string]interface{} `mapstructure:"ext"`
}
type MaxSeqResp struct {
MaxSeq int64 `json:"maxSeq"`
}
type PullMessageResp struct {
}
type SeqListData struct {
SeqList []int64 `mapstructure:"seqList" validate:"required"`
}
func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass bool, errCode int32, errMsg string, returnData interface{}) {
switch r {
case constant.WSGetNewestSeq:
data := sdkws.GetMaxAndMinSeqReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
log.Error(operationID, "data args validate err", err.Error(), r)
return false, 204, err.Error(), nil
}
return true, 0, "", data
case constant.WSSendMsg:
data := sdkws.MsgData{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
log.Error(operationID, "data args validate err", err.Error(), r)
return false, 204, err.Error(), nil
}
return true, 0, "", data
case constant.WSSendSignalMsg:
data := pbRtc.SignalReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
log.Error(operationID, "data args validate err", err.Error(), r)
return false, 204, err.Error(), nil
}
return true, 0, "", &data
case constant.WSPullMsgBySeqList:
data := sdkws.PullMessageBySeqListReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
log.Error(operationID, "data args validate err", err.Error(), r)
return false, 204, err.Error(), nil
}
return true, 0, "", data
case constant.WsSetBackgroundStatus:
data := sdkws.SetAppBackgroundStatusReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
log.Error(operationID, "data args validate err", err.Error(), r)
return false, 204, err.Error(), nil
}
return true, 0, "", &data
default:
}
return false, 204, "args err", nil
}

View File

@ -1,514 +0,0 @@
package msggateway
import (
"OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant"
"OpenIM/pkg/common/log"
"OpenIM/pkg/common/prome"
"OpenIM/pkg/common/tokenverify"
"OpenIM/pkg/errs"
"OpenIM/pkg/proto/msggateway"
"OpenIM/pkg/utils"
"bytes"
"compress/gzip"
"context"
"encoding/gob"
"io/ioutil"
"strconv"
"strings"
go_redis "github.com/go-redis/redis/v8"
"github.com/pkg/errors"
//"gopkg.in/errgo.v2/errors"
"net/http"
"sync"
"time"
"github.com/gorilla/websocket"
)
type UserConn struct {
*websocket.Conn
w *sync.Mutex
PlatformID int32
PushedMaxSeq uint32
IsCompress bool
userID string
IsBackground bool
token string
connID string
}
type WServer struct {
wsAddr string
wsMaxConnNum int
wsUpGrader *websocket.Upgrader
wsConnToUser map[*UserConn]map[int]string
wsUserToConn map[string]map[int]*UserConn
}
func (ws *WServer) onInit(wsPort int) {
ws.wsAddr = ":" + utils.IntToString(wsPort)
ws.wsMaxConnNum = config.Config.LongConnSvr.WebsocketMaxConnNum
ws.wsConnToUser = make(map[*UserConn]map[int]string)
ws.wsUserToConn = make(map[string]map[int]*UserConn)
ws.wsUpGrader = &websocket.Upgrader{
HandshakeTimeout: time.Duration(config.Config.LongConnSvr.WebsocketTimeOut) * time.Second,
ReadBufferSize: config.Config.LongConnSvr.WebsocketMaxMsgLen,
CheckOrigin: func(r *http.Request) bool { return true },
}
}
func (ws *WServer) run() {
http.HandleFunc("/", ws.wsHandler) //Get request from client to handle by wsHandler
err := http.ListenAndServe(ws.wsAddr, nil) //Start listening
if err != nil {
panic("Ws listening err:" + err.Error())
}
}
func (ws *WServer) wsHandler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
operationID := ""
if len(query[constant.OperationID]) != 0 {
operationID = query[constant.OperationID][0]
} else {
operationID = utils.OperationIDGenerator()
}
log.Debug(operationID, utils.GetSelfFuncName(), " args: ", query)
if isPass, compression := ws.headerCheck(w, r, operationID); isPass {
conn, err := ws.wsUpGrader.Upgrade(w, r, nil) //Conn is obtained through the upgraded escalator
if err != nil {
log.Error(operationID, "upgrade http conn err", err.Error(), query)
return
} else {
newConn := &UserConn{conn, new(sync.Mutex), utils.StringToInt32(query["platformID"][0]), 0, compression, query["sendID"][0], false, query["token"][0], conn.RemoteAddr().String() + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill()))}
userCount++
ws.addUserConn(query["sendID"][0], utils.StringToInt(query["platformID"][0]), newConn, query["token"][0], newConn.connID, operationID)
go ws.readMsg(newConn)
}
} else {
log.Error(operationID, "headerCheck failed ")
}
}
func (ws *WServer) readMsg(conn *UserConn) {
for {
messageType, msg, err := conn.ReadMessage()
if messageType == websocket.PingMessage {
log.NewInfo("", "this is a pingMessage")
}
if err != nil {
log.NewWarn("", "WS ReadMsg error ", " userIP", conn.RemoteAddr().String(), "userUid", "platform", "error", err.Error())
userCount--
ws.delUserConn(conn)
return
}
log.NewDebug("", "size", utils.ByteSize(uint64(len(msg))))
if conn.IsCompress {
buff := bytes.NewBuffer(msg)
reader, err := gzip.NewReader(buff)
if err != nil {
log.NewWarn("", "un gzip read failed")
continue
}
msg, err = ioutil.ReadAll(reader)
if err != nil {
log.NewWarn("", "ReadAll failed")
continue
}
err = reader.Close()
if err != nil {
log.NewWarn("", "reader close failed")
}
}
ws.msgParse(conn, msg)
}
}
func (ws *WServer) SetWriteTimeout(conn *UserConn, timeout int) {
conn.w.Lock()
defer conn.w.Unlock()
conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
}
func (ws *WServer) writeMsg(conn *UserConn, a int, msg []byte) error {
conn.w.Lock()
defer conn.w.Unlock()
if conn.IsCompress {
var buffer bytes.Buffer
gz := gzip.NewWriter(&buffer)
if _, err := gz.Write(msg); err != nil {
return utils.Wrap(err, "")
}
if err := gz.Close(); err != nil {
return utils.Wrap(err, "")
}
msg = buffer.Bytes()
}
conn.SetWriteDeadline(time.Now().Add(time.Duration(60) * time.Second))
return conn.WriteMessage(a, msg)
}
func (ws *WServer) SetWriteTimeoutWriteMsg(conn *UserConn, a int, msg []byte, timeout int) error {
conn.w.Lock()
defer conn.w.Unlock()
conn.SetWriteDeadline(time.Now().Add(time.Duration(timeout) * time.Second))
return conn.WriteMessage(a, msg)
}
func (ws *WServer) MultiTerminalLoginRemoteChecker(userID string, platformID int32, token string, operationID string) {
grpcCons := rpc.GetDefaultGatewayConn4Unique(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), operationID)
log.NewInfo(operationID, utils.GetSelfFuncName(), "args grpcCons: ", userID, platformID, grpcCons)
for _, v := range grpcCons {
if v.Target() == rpcSvr.target {
log.Debug(operationID, "Filter out this node ", rpcSvr.target)
continue
}
log.Debug(operationID, "call this node ", v.Target(), rpcSvr.target)
client := msggateway.NewRelayClient(v)
req := &msggateway.MultiTerminalLoginCheckReq{OperationID: operationID, PlatformID: platformID, UserID: userID, Token: token}
log.NewInfo(operationID, "MultiTerminalLoginCheckReq ", client, req.String())
resp, err := client.MultiTerminalLoginCheck(context.Background(), req)
if err != nil {
log.Error(operationID, "MultiTerminalLoginCheck failed ", err.Error())
continue
}
if resp.ErrCode != 0 {
log.Error(operationID, "MultiTerminalLoginCheck errCode, errMsg: ", resp.ErrCode, resp.ErrMsg)
continue
}
log.Debug(operationID, "MultiTerminalLoginCheck resp ", resp.String())
}
}
func (ws *WServer) MultiTerminalLoginCheckerWithLock(uid string, platformID int, token string, operationID string) {
rwLock.Lock()
defer rwLock.Unlock()
log.NewInfo(operationID, utils.GetSelfFuncName(), " rpc args: ", uid, platformID, token)
switch config.Config.MultiLoginPolicy {
case constant.PCAndOther:
if constant.PlatformNameToClass(constant.PlatformIDToName(platformID)) == constant.TerminalPC {
return
}
fallthrough
case constant.AllLoginButSameTermKick:
if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn]
if oldConn, ok := oldConnMap[platformID]; ok {
log.NewDebug(operationID, uid, platformID, "kick old conn")
m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID))
if err != nil && err != go_redis.Nil {
log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID))
return
}
if m == nil {
log.NewError(operationID, "get token from redis err", "m is nil", uid, constant.PlatformIDToName(platformID))
return
}
log.NewDebug(operationID, "get token map is ", m, uid, constant.PlatformIDToName(platformID))
for k, _ := range m {
if k != token {
m[k] = constant.KickedToken
}
}
log.NewDebug(operationID, "set token map is ", m, uid, constant.PlatformIDToName(platformID))
err = db.DB.SetTokenMapByUidPid(uid, platformID, m)
if err != nil {
log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m)
return
}
err = oldConn.Close()
//delete(oldConnMap, platformID)
ws.wsUserToConn[uid] = oldConnMap
if len(oldConnMap) == 0 {
delete(ws.wsUserToConn, uid)
}
delete(ws.wsConnToUser, oldConn)
if err != nil {
log.NewError(operationID, "conn close err", err.Error(), uid, platformID)
}
} else {
log.NewWarn(operationID, "abnormal uid-conn ", uid, platformID, oldConnMap[platformID])
}
} else {
log.NewDebug(operationID, "no other conn", ws.wsUserToConn, uid, platformID)
}
case constant.SingleTerminalLogin:
case constant.WebAndOther:
}
}
func (ws *WServer) MultiTerminalLoginChecker(uid string, platformID int, newConn *UserConn, token string, operationID string) {
switch config.Config.MultiLoginPolicy {
case constant.PCAndOther:
if constant.PlatformNameToClass(constant.PlatformIDToName(platformID)) == constant.TerminalPC {
return
}
fallthrough
case constant.AllLoginButSameTermKick:
if oldConnMap, ok := ws.wsUserToConn[uid]; ok { // user->map[platform->conn]
if oldConn, ok := oldConnMap[platformID]; ok {
log.NewDebug(operationID, uid, platformID, "kick old conn")
ws.sendKickMsg(oldConn)
m, err := db.DB.GetTokenMapByUidPid(uid, constant.PlatformIDToName(platformID))
if err != nil && err != go_redis.Nil {
log.NewError(operationID, "get token from redis err", err.Error(), uid, constant.PlatformIDToName(platformID))
return
}
if m == nil {
log.NewError(operationID, "get token from redis err", "m is nil", uid, constant.PlatformIDToName(platformID))
return
}
log.NewDebug(operationID, "get token map is ", m, uid, constant.PlatformIDToName(platformID))
for k, _ := range m {
if k != token {
m[k] = constant.KickedToken
}
}
log.NewDebug(operationID, "set token map is ", m, uid, constant.PlatformIDToName(platformID))
err = db.DB.SetTokenMapByUidPid(uid, platformID, m)
if err != nil {
log.NewError(operationID, "SetTokenMapByUidPid err", err.Error(), uid, platformID, m)
return
}
err = oldConn.Close()
delete(oldConnMap, platformID)
ws.wsUserToConn[uid] = oldConnMap
if len(oldConnMap) == 0 {
delete(ws.wsUserToConn, uid)
}
delete(ws.wsConnToUser, oldConn)
if err != nil {
log.NewError(operationID, "conn close err", err.Error(), uid, platformID)
}
callbackResp := callbackUserKickOff(operationID, uid, platformID)
if callbackResp.ErrCode != 0 {
log.NewError(operationID, utils.GetSelfFuncName(), "callbackUserOffline failed", callbackResp)
}
} else {
log.Debug(operationID, "normal uid-conn ", uid, platformID, oldConnMap[platformID])
}
} else {
log.NewDebug(operationID, "no other conn", ws.wsUserToConn, uid, platformID)
}
case constant.SingleTerminalLogin:
case constant.WebAndOther:
}
}
func (ws *WServer) sendKickMsg(oldConn *UserConn) {
mReply := Resp{
ReqIdentifier: constant.WSKickOnlineMsg,
ErrCode: int32(errs.ErrTokenInvalid.Code()),
ErrMsg: errs.ErrTokenInvalid.Msg(),
}
var b bytes.Buffer
enc := gob.NewEncoder(&b)
err := enc.Encode(mReply)
if err != nil {
log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "Encode Msg error", oldConn.RemoteAddr().String(), err.Error())
return
}
err = ws.writeMsg(oldConn, websocket.BinaryMessage, b.Bytes())
if err != nil {
log.NewError(mReply.OperationID, mReply.ReqIdentifier, mReply.ErrCode, mReply.ErrMsg, "sendKickMsg WS WriteMsg error", oldConn.RemoteAddr().String(), err.Error())
}
}
func (ws *WServer) addUserConn(uid string, platformID int, conn *UserConn, token string, connID, operationID string) {
rwLock.Lock()
defer rwLock.Unlock()
log.Info(operationID, utils.GetSelfFuncName(), " args: ", uid, platformID, conn, token, "ip: ", conn.RemoteAddr().String())
callbackResp := callbackUserOnline(operationID, uid, platformID, token, false, connID)
if callbackResp.ErrCode != 0 {
log.NewError(operationID, utils.GetSelfFuncName(), "callbackUserOnline resp:", callbackResp)
}
go ws.MultiTerminalLoginRemoteChecker(uid, int32(platformID), token, operationID)
ws.MultiTerminalLoginChecker(uid, platformID, conn, token, operationID)
if oldConnMap, ok := ws.wsUserToConn[uid]; ok {
oldConnMap[platformID] = conn
ws.wsUserToConn[uid] = oldConnMap
log.Debug(operationID, "user not first come in, add conn ", uid, platformID, conn, oldConnMap)
} else {
i := make(map[int]*UserConn)
i[platformID] = conn
ws.wsUserToConn[uid] = i
log.Debug(operationID, "user first come in, new user, conn", uid, platformID, conn, ws.wsUserToConn[uid])
}
if oldStringMap, ok := ws.wsConnToUser[conn]; ok {
oldStringMap[platformID] = uid
ws.wsConnToUser[conn] = oldStringMap
} else {
i := make(map[int]string)
i[platformID] = uid
ws.wsConnToUser[conn] = i
}
count := 0
for _, v := range ws.wsUserToConn {
count = count + len(v)
}
prome.GaugeInc(prome.OnlineUserGauge)
log.Debug(operationID, "WS Add operation", "", "wsUser added", ws.wsUserToConn, "connection_uid", uid, "connection_platform", constant.PlatformIDToName(platformID), "online_user_num", len(ws.wsUserToConn), "online_conn_num", count)
}
func (ws *WServer) delUserConn(conn *UserConn) {
rwLock.Lock()
defer rwLock.Unlock()
operationID := utils.OperationIDGenerator()
var uid string
var platform int
if oldStringMap, okg := ws.wsConnToUser[conn]; okg {
for k, v := range oldStringMap {
platform = k
uid = v
}
if oldConnMap, ok := ws.wsUserToConn[uid]; ok {
delete(oldConnMap, platform)
ws.wsUserToConn[uid] = oldConnMap
if len(oldConnMap) == 0 {
delete(ws.wsUserToConn, uid)
}
count := 0
for _, v := range ws.wsUserToConn {
count = count + len(v)
}
log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn), "online_conn_num", count)
} else {
log.Debug(operationID, "WS delete operation", "", "wsUser deleted", ws.wsUserToConn, "disconnection_uid", uid, "disconnection_platform", platform, "online_user_num", len(ws.wsUserToConn))
}
delete(ws.wsConnToUser, conn)
}
err := conn.Close()
if err != nil {
log.Error(operationID, " close err", "", "uid", uid, "platform", platform)
}
if conn.PlatformID == 0 || conn.connID == "" {
log.NewWarn(operationID, utils.GetSelfFuncName(), "PlatformID or connID is null", conn.PlatformID, conn.connID)
}
callbackResp := callbackUserOffline(operationID, conn.userID, int(conn.PlatformID), conn.connID)
if callbackResp.ErrCode != 0 {
log.NewError(operationID, utils.GetSelfFuncName(), "callbackUserOffline failed", callbackResp)
}
prome.GaugeDec(prome.OnlineUserGauge)
}
func (ws *WServer) getUserConn(uid string, platform int) *UserConn {
rwLock.RLock()
defer rwLock.RUnlock()
if connMap, ok := ws.wsUserToConn[uid]; ok {
if conn, flag := connMap[platform]; flag {
return conn
}
}
return nil
}
func (ws *WServer) getUserAllCons(uid string) map[int]*UserConn {
rwLock.RLock()
defer rwLock.RUnlock()
if connMap, ok := ws.wsUserToConn[uid]; ok {
newConnMap := make(map[int]*UserConn)
for k, v := range connMap {
newConnMap[k] = v
}
return newConnMap
}
return nil
}
// func (ws *WServer) getUserUid(conn *UserConn) (uid string, platform int) {
// rwLock.RLock()
// defer rwLock.RUnlock()
//
// if stringMap, ok := ws.wsConnToUser[conn]; ok {
// for k, v := range stringMap {
// platform = k
// uid = v
// }
// return uid, platform
// }
// return "", 0
// }
func WsVerifyToken(token, uid string, platformID string, operationID string) (bool, error, string) {
}
func (ws *WServer) headerCheck(w http.ResponseWriter, r *http.Request, operationID string) (isPass, compression bool) {
status := http.StatusUnauthorized
query := r.URL.Query()
if len(query["token"]) != 0 && len(query["sendID"]) != 0 && len(query["platformID"]) != 0 {
if ok, err, msg := tokenverify.WsVerifyToken(query["token"][0], query["sendID"][0], query["platformID"][0], operationID); !ok {
if errors.Is(err, errs.ErrTokenExpired) {
status = int(errs.ErrTokenExpired.ErrCode)
}
if errors.Is(err, errs.ErrTokenInvalid) {
status = int(errs.ErrTokenInvalid.ErrCode)
}
if errors.Is(err, errs.ErrTokenMalformed) {
status = int(errs.ErrTokenMalformed.ErrCode)
}
if errors.Is(err, errs.ErrTokenNotValidYet) {
status = int(errs.ErrTokenNotValidYet.ErrCode)
}
if errors.Is(err, errs.ErrTokenUnknown) {
status = int(errs.ErrTokenUnknown.ErrCode)
}
if errors.Is(err, errs.ErrTokenKicked) {
status = int(errs.ErrTokenKicked.ErrCode)
}
if errors.Is(err, errs.ErrTokenDifferentPlatformID) {
status = int(errs.ErrTokenDifferentPlatformID.ErrCode)
}
if errors.Is(err, errs.ErrTokenDifferentUserID) {
status = int(errs.ErrTokenDifferentUserID.ErrCode)
}
//switch errors.Cause(err) {
//case errs.ErrTokenExpired:
// status = int(errs.ErrTokenExpired.ErrCode)
//case errs.ErrTokenInvalid:
// status = int(errs.ErrTokenInvalid.ErrCode)
//case errs.ErrTokenMalformed:
// status = int(errs.ErrTokenMalformed.ErrCode)
//case errs.ErrTokenNotValidYet:
// status = int(errs.ErrTokenNotValidYet.ErrCode)
//case errs.ErrTokenUnknown:
// status = int(errs.ErrTokenUnknown.ErrCode)
//case errs.ErrTokenKicked:
// status = int(errs.ErrTokenKicked.ErrCode)
//case errs.ErrTokenDifferentPlatformID:
// status = int(errs.ErrTokenDifferentPlatformID.ErrCode)
//case errs.ErrTokenDifferentUserID:
// status = int(errs.ErrTokenDifferentUserID.ErrCode)
//}
log.Error(operationID, "Token verify failed ", "query ", query, msg, err.Error(), "status: ", status)
w.Header().Set("Sec-Websocket-Version", "13")
w.Header().Set("ws_err_msg", err.Error())
http.Error(w, err.Error(), status)
return false, false
} else {
if r.Header.Get("compression") == "gzip" {
compression = true
}
if len(query["compression"]) != 0 && query["compression"][0] == "gzip" {
compression = true
}
log.Info(operationID, "Connection Authentication Success", "", "token ", query["token"][0], "userID ", query["sendID"][0], "platformID ", query["platformID"][0], "compression", compression)
return true, compression
}
} else {
status = int(errs.ErrArgs.ErrCode)
log.Error(operationID, "Args err ", "query ", query)
w.Header().Set("Sec-Websocket-Version", "13")
errMsg := "args err, need token, sendID, platformID"
w.Header().Set("ws_err_msg", errMsg)
http.Error(w, errMsg, status)
return false, false
}
}

View File

@ -242,7 +242,7 @@ func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(sess sarama.ConsumerG
func (och *OnlineHistoryRedisConsumerHandler) sendMessageToPushMQ(ctx context.Context, message *pbMsg.MsgDataToMQ, pushToUserID string) { func (och *OnlineHistoryRedisConsumerHandler) sendMessageToPushMQ(ctx context.Context, message *pbMsg.MsgDataToMQ, pushToUserID string) {
mqPushMsg := pbMsg.PushMsgDataToMQ{MsgData: message.MsgData, SourceID: pushToUserID} mqPushMsg := pbMsg.PushMsgDataToMQ{MsgData: message.MsgData, SourceID: pushToUserID}
pid, offset, err := och.producerToPush.SendMessage(ctx, &mqPushMsg, mqPushMsg.SourceID) pid, offset, err := och.producerToPush.SendMessage(ctx, mqPushMsg.SourceID, &mqPushMsg)
if err != nil { if err != nil {
log.Error(tracelog.GetOperationID(ctx), "kafka send failed", "send data", message.String(), "pid", pid, "offset", offset, "err", err.Error()) log.Error(tracelog.GetOperationID(ctx), "kafka send failed", "send data", message.String(), "pid", pid, "offset", offset, "err", err.Error())
} }
@ -251,7 +251,7 @@ func (och *OnlineHistoryRedisConsumerHandler) sendMessageToPushMQ(ctx context.Co
func (och *OnlineHistoryRedisConsumerHandler) sendMessageToModifyMQ(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ) { func (och *OnlineHistoryRedisConsumerHandler) sendMessageToModifyMQ(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ) {
if len(messages) > 0 { if len(messages) > 0 {
pid, offset, err := och.producerToModify.SendMessage(ctx, &pbMsg.MsgDataToModifyByMQ{AggregationID: aggregationID, Messages: messages, TriggerID: triggerID}, aggregationID) pid, offset, err := och.producerToModify.SendMessage(ctx, aggregationID, &pbMsg.MsgDataToModifyByMQ{AggregationID: aggregationID, Messages: messages, TriggerID: triggerID})
if err != nil { if err != nil {
log.Error(triggerID, "kafka send failed", "send data", len(messages), "pid", pid, "offset", offset, "err", err.Error(), "key", aggregationID) log.Error(triggerID, "kafka send failed", "send data", len(messages), "pid", pid, "offset", offset, "err", err.Error(), "key", aggregationID)
} }
@ -260,7 +260,7 @@ func (och *OnlineHistoryRedisConsumerHandler) sendMessageToModifyMQ(ctx context.
func (och *OnlineHistoryRedisConsumerHandler) SendMessageToMongoCH(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ, lastSeq int64) { func (och *OnlineHistoryRedisConsumerHandler) SendMessageToMongoCH(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ, lastSeq int64) {
if len(messages) > 0 { if len(messages) > 0 {
pid, offset, err := och.producerToMongo.SendMessage(ctx, &pbMsg.MsgDataToMongoByMQ{LastSeq: lastSeq, AggregationID: aggregationID, Messages: messages, TriggerID: triggerID}, aggregationID) pid, offset, err := och.producerToMongo.SendMessage(ctx, aggregationID, &pbMsg.MsgDataToMongoByMQ{LastSeq: lastSeq, AggregationID: aggregationID, Messages: messages, TriggerID: triggerID})
if err != nil { if err != nil {
log.Error(triggerID, "kafka send failed", "send data", len(messages), "pid", pid, "offset", offset, "err", err.Error(), "key", aggregationID) log.Error(triggerID, "kafka send failed", "send data", len(messages), "pid", pid, "offset", offset, "err", err.Error(), "key", aggregationID)
} }

View File

@ -24,7 +24,7 @@ func NewOnlineHistoryMongoConsumerHandler(database controller.MsgDatabase) *Onli
mc := &OnlineHistoryMongoConsumerHandler{ mc := &OnlineHistoryMongoConsumerHandler{
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0, historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToMongo.Topic}, OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToMongo.Topic},
config.Config.Kafka.Ws2mschat.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo), config.Config.Kafka.MsgToMongo.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo),
msgDatabase: database, msgDatabase: database,
} }
return mc return mc

View File

@ -39,7 +39,7 @@ func NewClient(cache cache.Model) *Fcm {
panic(err.Error()) panic(err.Error())
return nil return nil
} }
return &Fcm{fcmMsgCli: fcmMsgClient} return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}
} }
func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error { func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string, opts *offlinepush.Opts) error {

View File

@ -95,7 +95,6 @@ func (p *Pusher) MsgToUser(ctx context.Context, userID string, msg *sdkws.MsgDat
return nil return nil
} }
} }
if err := callbackOfflinePush(ctx, userIDs, msg, &[]string{}); err != nil { if err := callbackOfflinePush(ctx, userIDs, msg, &[]string{}); err != nil {
return err return err
} }

View File

@ -9,7 +9,7 @@ import (
"OpenIM/pkg/common/log" "OpenIM/pkg/common/log"
"OpenIM/pkg/common/tokenverify" "OpenIM/pkg/common/tokenverify"
"OpenIM/pkg/common/tracelog" "OpenIM/pkg/common/tracelog"
discoveryRegistry "OpenIM/pkg/discoveryregistry" "OpenIM/pkg/discoveryregistry"
"OpenIM/pkg/errs" "OpenIM/pkg/errs"
pbAuth "OpenIM/pkg/proto/auth" pbAuth "OpenIM/pkg/proto/auth"
"OpenIM/pkg/proto/msggateway" "OpenIM/pkg/proto/msggateway"
@ -21,10 +21,10 @@ import (
type authServer struct { type authServer struct {
authDatabase controller.AuthDatabase authDatabase controller.AuthDatabase
userCheck *check.UserCheck userCheck *check.UserCheck
RegisterCenter discoveryRegistry.SvcDiscoveryRegistry RegisterCenter discoveryregistry.SvcDiscoveryRegistry
} }
func Start(client discoveryRegistry.SvcDiscoveryRegistry, server *grpc.Server) error { func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
rdb, err := cache.NewRedis() rdb, err := cache.NewRedis()
if err != nil { if err != nil {
return err return err

View File

@ -83,13 +83,13 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI
if err != nil { if err != nil {
return nil, err return nil, err
} }
friends, err := s.friendCheck.GetAllPageFriends(ctx, req.UserInfo.UserID) friends, err := s.friendCheck.GetFriendIDs(ctx, req.UserInfo.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
go func() { go func() {
for _, v := range friends { for _, v := range friends {
s.notification.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, v.FriendUser.UserID, tracelog.GetOpUserID(ctx)) s.notification.FriendInfoUpdatedNotification(ctx, req.UserInfo.UserID, v, tracelog.GetOpUserID(ctx))
} }
}() }()
s.notification.UserInfoUpdatedNotification(ctx, tracelog.GetOpUserID(ctx), req.UserInfo.UserID) s.notification.UserInfoUpdatedNotification(ctx, tracelog.GetOpUserID(ctx), req.UserInfo.UserID)

View File

@ -8,7 +8,7 @@ import (
"OpenIM/pkg/common/mw" "OpenIM/pkg/common/mw"
"OpenIM/pkg/common/prome" "OpenIM/pkg/common/prome"
"OpenIM/pkg/discoveryregistry" "OpenIM/pkg/discoveryregistry"
"flag" "OpenIM/pkg/utils"
"fmt" "fmt"
"github.com/OpenIMSDK/openKeeper" "github.com/OpenIMSDK/openKeeper"
grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
@ -16,20 +16,18 @@ import (
"net" "net"
) )
func start(rpcPort int, rpcRegisterName string, prometheusPorts int, rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error, options []grpc.ServerOption) error { func start(rpcPort int, rpcRegisterName string, prometheusPort int, rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error, options []grpc.ServerOption) error {
flagRpcPort := flag.Int("port", rpcPort, "get RpcGroupPort from cmd,default 16000 as port") fmt.Println("start", rpcRegisterName, "rpc server, port: ", rpcPort, "prometheusPort:", prometheusPort, ", OpenIM version: ", config.Version)
flagPrometheusPort := flag.Int("prometheus_port", prometheusPorts, "groupPrometheusPort default listen port")
flag.Parse()
fmt.Println("start group rpc server, port: ", *flagRpcPort, ", OpenIM version: ", config.Version)
log.NewPrivateLog(constant.LogFileName) log.NewPrivateLog(constant.LogFileName)
listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.Config.ListenIP, *flagRpcPort)) listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.Config.ListenIP, rpcPort))
if err != nil { if err != nil {
return err return err
} }
defer listener.Close() defer listener.Close()
fmt.Println(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema, rpcRegisterName)
zkClient, err := openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema, 10, "", "") zkClient, err := openKeeper.NewClient(config.Config.Zookeeper.ZkAddr, config.Config.Zookeeper.Schema, 10, "", "")
if err != nil { if err != nil {
return err return utils.Wrap1(err)
} }
defer zkClient.Close() defer zkClient.Close()
registerIP, err := network.GetRpcRegisterIP(config.Config.RpcRegisterIP) registerIP, err := network.GetRpcRegisterIP(config.Config.RpcRegisterIP)
@ -49,12 +47,12 @@ func start(rpcPort int, rpcRegisterName string, prometheusPorts int, rpcFn func(
} }
srv := grpc.NewServer(options...) srv := grpc.NewServer(options...)
defer srv.GracefulStop() defer srv.GracefulStop()
err = zkClient.Register(rpcRegisterName, registerIP, *flagRpcPort) err = zkClient.Register(rpcRegisterName, registerIP, rpcPort)
if err != nil { if err != nil {
return err return utils.Wrap1(err)
} }
if config.Config.Prometheus.Enable { if config.Config.Prometheus.Enable && prometheusPort != 0 {
err := prome.StartPrometheusSrv(*flagPrometheusPort) err := prome.StartPrometheusSrv(prometheusPort)
if err != nil { if err != nil {
return err return err
} }

View File

@ -11,6 +11,7 @@ import (
"OpenIM/pkg/common/tracelog" "OpenIM/pkg/common/tracelog"
"OpenIM/pkg/utils" "OpenIM/pkg/utils"
"context" "context"
"errors"
"fmt" "fmt"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"math" "math"
@ -22,6 +23,8 @@ type MsgTool struct {
groupDatabase controller.GroupDatabase groupDatabase controller.GroupDatabase
} }
var errSeq = errors.New("cache max seq and mongo max seq is diff > 10")
func NewMsgTool(msgDatabase controller.MsgDatabase, userDatabase controller.UserDatabase, groupDatabase controller.GroupDatabase) *MsgTool { func NewMsgTool(msgDatabase controller.MsgDatabase, userDatabase controller.UserDatabase, groupDatabase controller.GroupDatabase) *MsgTool {
return &MsgTool{ return &MsgTool{
msgDatabase: msgDatabase, msgDatabase: msgDatabase,
@ -125,7 +128,9 @@ func (c *MsgTool) fixGroupSeq(ctx context.Context, groupID string, userIDs []str
continue continue
} }
} }
c.CheckMaxSeqWithMongo(ctx, groupID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion) if err := c.CheckMaxSeqWithMongo(ctx, groupID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
log.NewWarn(tracelog.GetOperationID(ctx), "cache max seq and mongo max seq is diff > 10", groupID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion)
}
return nil return nil
} }
@ -162,10 +167,11 @@ func (c *MsgTool) GetAndFixGroupUserSeq(ctx context.Context, userID string, grou
return minSeqCache, nil return minSeqCache, nil
} }
func (c *MsgTool) CheckMaxSeqWithMongo(ctx context.Context, sourceID string, maxSeqCache, maxSeqMongo int64, diffusionType int) { func (c *MsgTool) CheckMaxSeqWithMongo(ctx context.Context, sourceID string, maxSeqCache, maxSeqMongo int64, diffusionType int) error {
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 { if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
log.NewWarn(tracelog.GetOperationID(ctx), "cache max seq and mongo max seq is diff > 10", sourceID, maxSeqCache, maxSeqMongo, diffusionType) return errSeq
} }
return nil
} }
func (c *MsgTool) ShowUserSeqs(ctx context.Context, userID string) { func (c *MsgTool) ShowUserSeqs(ctx context.Context, userID string) {

View File

@ -2,22 +2,24 @@ package tools
import ( import (
"OpenIM/pkg/common/constant" "OpenIM/pkg/common/constant"
"OpenIM/pkg/common/db/cache"
"OpenIM/pkg/common/tracelog"
"OpenIM/pkg/proto/sdkws" "OpenIM/pkg/proto/sdkws"
"OpenIM/pkg/utils"
"context" "context"
"fmt" "github.com/golang/protobuf/proto"
"go.mongodb.org/mongo-driver/bson"
"strconv" "strconv"
"github.com/go-redis/redis/v8" unRelationTb "OpenIM/pkg/common/db/table/unrelation"
"github.com/golang/protobuf/proto" "OpenIM/pkg/common/db/unrelation"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"testing" "testing"
"time" "time"
) )
func GenUserChat(startSeq, stopSeq, delSeq, index int64, userID string) *mongo2.UserChat { func GenMsgDoc(startSeq, stopSeq, delSeq, index int64, userID string) *unRelationTb.MsgDocModel {
chat := &mongo2.UserChat{UID: userID + strconv.Itoa(int(index))} msgDoc := &unRelationTb.MsgDocModel{DocID: userID + strconv.Itoa(int(index))}
for i := startSeq; i <= stopSeq; i++ { for i := startSeq; i <= stopSeq; i++ {
msg := sdkws.MsgData{ msg := sdkws.MsgData{
SendID: "sendID1", SendID: "sendID1",
@ -31,57 +33,281 @@ func GenUserChat(startSeq, stopSeq, delSeq, index int64, userID string) *mongo2.
SessionType: 1, SessionType: 1,
MsgFrom: 100, MsgFrom: 100,
ContentType: 101, ContentType: 101,
Content: []byte("testFaceURL.com"), Content: []byte("testFaceURL"),
Seq: i, Seq: i,
SendTime: time.Now().Unix(), SendTime: time.Now().Unix(),
CreateTime: time.Now().Unix(), CreateTime: time.Now().Unix(),
Status: 1, Status: 1,
} }
bytes, _ := proto.Marshal(&msg) bytes, _ := proto.Marshal(&msg)
sendTime := 0 var sendTime int64
chat.Msg = append(chat.Msg, mongo2.MsgInfo{SendTime: int64(sendTime), Msg: bytes}) if i <= delSeq {
sendTime = 10000
} else {
sendTime = utils.GetCurrentTimestampByMill()
}
msgDoc.Msg = append(msgDoc.Msg, unRelationTb.MsgInfoModel{SendTime: int64(sendTime), Msg: bytes})
} }
return chat return msgDoc
} }
func SetUserMaxSeq(userID string, seq int) error { func TestDeleteMongoMsgAndResetRedisSeq(t *testing.T) {
return redisClient.Set(context.Background(), "REDIS_USER_INCR_SEQ"+userID, seq, 0).Err() operationID := "test"
}
func CreateChat(userChat *mongo2.UserChat) error { rdb, err := cache.NewRedis()
_, err := mongoClient.InsertOne(context.Background(), userChat)
return err
}
func TestDeleteUserMsgsAndSetMinSeq(t *testing.T) {
operationID := getCronTaskOperationID()
redisClient = redis.NewClient(&redis.Options{
Addr: "127.0.0.1:16379",
Password: "openIM123", // no password set
DB: 13, // use default DB
})
mongoUri := fmt.Sprintf("mongodb://%s:%s@%s/%s?maxPoolSize=%d&authSource=admin",
"root", "openIM123", "127.0.0.1:37017",
"openIM", 100)
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(mongoUri))
mongoClient = client.Database("openIM").Collection("msg")
testUID1 := "test_del_id1"
//testUID2 := "test_del_id2"
//testUID3 := "test_del_id3"
//testUID4 := "test_del_id4"
//testUID5 := "test_del_id5"
//testUID6 := "test_del_id6"
err = SetUserMaxSeq(testUID1, 600)
userChat := GenUserChat(1, 500, 200, 0, testUID1)
err = CreateChat(userChat)
if err := DeleteUserMsgsAndSetMinSeq(operationID, testUID1); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID1)
}
if err := checkMaxSeqWithMongo(operationID, testUID1, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID1)
}
if err != nil { if err != nil {
t.Error("err is not nil", testUID1, err.Error()) return
}
mgo, err := unrelation.NewMongo()
if err != nil {
return
}
cacheModel := cache.NewCacheModel(rdb)
mongoClient := mgo.GetDatabase().Collection(unRelationTb.MsgDocModel{}.TableName())
ctx := context.Background()
tracelog.SetOperationID(ctx, operationID)
testUID1 := "test_del_id1"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID1 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("DeleteOne failed")
return
}
err = cacheModel.SetUserMaxSeq(ctx, testUID1, 600)
if err != nil {
t.Error("SetUserMaxSeq failed")
}
msgDoc := GenMsgDoc(1, 600, 200, 0, testUID1)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID1)
}
msgTools, err := InitMsgTool()
if err != nil {
t.Error("init failed")
return
}
msgTools.ClearUsersMsg(ctx, []string{testUID1})
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err := msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID1)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID1, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID1)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 201 {
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
}
/////// uid2
testUID2 := "test_del_id2"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID2 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID2 + ":" + strconv.Itoa(1)})
if err != nil {
t.Error("delete failed")
}
err = cacheModel.SetUserMaxSeq(ctx, testUID2, 7000)
if err != nil {
t.Error("SetUserMaxSeq failed")
}
msgDoc = GenMsgDoc(1, 4999, 5000, 0, testUID2)
msgDoc2 := GenMsgDoc(5000, 7000, 6000, 1, testUID2)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID1)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
t.Error("InsertOne failed", testUID1)
}
msgTools.ClearUsersMsg(ctx, []string{testUID2})
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID2)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID2, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID2)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 6001 {
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
}
/////// uid3
testUID3 := "test_del_id3"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID3 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("delete failed")
}
err = cacheModel.SetUserMaxSeq(ctx, testUID3, 4999)
if err != nil {
t.Error("SetUserMaxSeq failed")
}
msgDoc = GenMsgDoc(1, 4999, 5000, 0, testUID3)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID3)
}
msgTools.ClearUsersMsg(ctx, []string{testUID3})
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID3)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID3, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID3)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 5000 {
t.Error("test1 is not the same", "minSeq:", minSeqCache, "targetSeq", 201)
}
//// uid4
testUID4 := "test_del_id4"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID4 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID4 + ":" + strconv.Itoa(1)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID4 + ":" + strconv.Itoa(2)})
if err != nil {
t.Error("delete failed")
}
err = cacheModel.SetUserMaxSeq(ctx, testUID4, 12000)
msgDoc = GenMsgDoc(1, 4999, 5000, 0, testUID4)
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, testUID4)
msgDoc3 := GenMsgDoc(10000, 12000, 11000, 2, testUID4)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID4)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
t.Error("InsertOne failed", testUID4)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc3); err != nil {
t.Error("InsertOne failed", testUID4)
}
msgTools.ClearUsersMsg(ctx, []string{testUID4})
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID4)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID4, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID4)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 5000 {
t.Error("test1 is not the same", "minSeq:", minSeqCache)
}
testUID5 := "test_del_id5"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID5 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID5 + ":" + strconv.Itoa(1)})
if err != nil {
t.Error("delete failed")
}
err = cacheModel.SetUserMaxSeq(ctx, testUID5, 9999)
msgDoc = GenMsgDoc(1, 4999, 5000, 0, testUID5)
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, testUID5)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID5)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
t.Error("InsertOne failed", testUID5)
}
msgTools.ClearUsersMsg(ctx, []string{testUID5})
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID5)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID5, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID5)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 10000 {
t.Error("test1 is not the same", "minSeq:", minSeqCache)
}
testUID6 := "test_del_id6"
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID6 + ":" + strconv.Itoa(0)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID6 + ":" + strconv.Itoa(1)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID6 + ":" + strconv.Itoa(2)})
if err != nil {
t.Error("delete failed")
}
_, err = mongoClient.DeleteOne(ctx, bson.M{"uid": testUID6 + ":" + strconv.Itoa(3)})
if err != nil {
t.Error("delete failed")
}
msgDoc = GenMsgDoc(1, 4999, 5000, 0, testUID6)
msgDoc2 = GenMsgDoc(5000, 9999, 10000, 1, testUID6)
msgDoc3 = GenMsgDoc(10000, 14999, 13000, 2, testUID6)
msgDoc4 := GenMsgDoc(15000, 19999, 0, 3, testUID6)
if _, err := mongoClient.InsertOne(ctx, msgDoc); err != nil {
t.Error("InsertOne failed", testUID4)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc2); err != nil {
t.Error("InsertOne failed", testUID4)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc3); err != nil {
t.Error("InsertOne failed", testUID4)
}
if _, err := mongoClient.InsertOne(ctx, msgDoc4); err != nil {
t.Error("InsertOne failed", testUID4)
}
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err = msgTools.msgDatabase.GetUserMinMaxSeqInMongoAndCache(ctx, testUID6)
if err != nil {
t.Error("GetSuperGroupMinMaxSeqInMongoAndCache failed")
return
}
if err := msgTools.CheckMaxSeqWithMongo(ctx, testUID6, maxSeqCache, maxSeqMongo, constant.WriteDiffusion); err != nil {
t.Error("checkMaxSeqWithMongo failed", testUID6)
}
if minSeqMongo != minSeqCache {
t.Error("minSeqMongo != minSeqCache", minSeqMongo, minSeqCache)
}
if minSeqCache != 13001 {
t.Error("test1 is not the same", "minSeq:", minSeqCache)
} }
} }

View File

@ -13,7 +13,6 @@ type UserTokenInfo struct {
ExpiredTime int64 `json:"expiredTime"` ExpiredTime int64 `json:"expiredTime"`
} }
type UserRegisterResp struct { type UserRegisterResp struct {
CommResp
UserToken UserTokenInfo `json:"data"` UserToken UserTokenInfo `json:"data"`
} }
@ -25,7 +24,6 @@ type UserTokenReq struct {
} }
type UserTokenResp struct { type UserTokenResp struct {
CommResp
UserToken UserTokenInfo `json:"data"` UserToken UserTokenInfo `json:"data"`
} }
@ -36,7 +34,6 @@ type ForceLogoutReq struct {
} }
type ForceLogoutResp struct { type ForceLogoutResp struct {
CommResp
} }
type ParseTokenReq struct { type ParseTokenReq struct {
@ -44,7 +41,7 @@ type ParseTokenReq struct {
} }
//type ParseTokenResp struct { //type ParseTokenResp struct {
// CommResp //
// ExpireTime int64 `json:"expireTime" binding:"required"` // ExpireTime int64 `json:"expireTime" binding:"required"`
//} //}
@ -53,7 +50,6 @@ type ExpireTime struct {
} }
type ParseTokenResp struct { type ParseTokenResp struct {
CommResp
Data map[string]interface{} `json:"data" swaggerignore:"true"` Data map[string]interface{} `json:"data" swaggerignore:"true"`
ExpireTime ExpireTime `json:"-"` ExpireTime ExpireTime `json:"-"`
} }

View File

@ -14,7 +14,6 @@ type AwsStorageCredentialRespData struct {
} }
type AwsStorageCredentialResp struct { type AwsStorageCredentialResp struct {
CommResp
CosData AwsStorageCredentialRespData CosData AwsStorageCredentialRespData
Data map[string]interface{} `json:"data"` Data map[string]interface{} `json:"data"`
} }

View File

@ -1,6 +0,0 @@
package apistruct
type RequestPagination struct {
PageNumber int `json:"pageNumber" binding:"required"`
ShowNumber int `json:"showNumber" binding:"required"`
}

View File

@ -9,7 +9,6 @@ type GetAllConversationMessageOptReq struct {
FromUserID string `json:"fromUserID" binding:"required"` FromUserID string `json:"fromUserID" binding:"required"`
} }
type GetAllConversationMessageOptResp struct { type GetAllConversationMessageOptResp struct {
CommResp
ConversationOptResultList []*OptResult `json:"data"` ConversationOptResultList []*OptResult `json:"data"`
} }
type GetReceiveMessageOptReq struct { type GetReceiveMessageOptReq struct {
@ -18,7 +17,6 @@ type GetReceiveMessageOptReq struct {
FromUserID string `json:"fromUserID" binding:"required"` FromUserID string `json:"fromUserID" binding:"required"`
} }
type GetReceiveMessageOptResp struct { type GetReceiveMessageOptResp struct {
CommResp
ConversationOptResultList []*OptResult `json:"data"` ConversationOptResultList []*OptResult `json:"data"`
} }
type SetReceiveMessageOptReq struct { type SetReceiveMessageOptReq struct {
@ -28,7 +26,6 @@ type SetReceiveMessageOptReq struct {
ConversationIDList []string `json:"conversationIDList" binding:"required"` ConversationIDList []string `json:"conversationIDList" binding:"required"`
} }
type SetReceiveMessageOptResp struct { type SetReceiveMessageOptResp struct {
CommResp
ConversationOptResultList []*OptResult `json:"data"` ConversationOptResultList []*OptResult `json:"data"`
} }
@ -58,7 +55,6 @@ type SetConversationReq struct {
} }
type SetConversationResp struct { type SetConversationResp struct {
CommResp
} }
type ModifyConversationFieldReq struct { type ModifyConversationFieldReq struct {
Conversation Conversation
@ -67,7 +63,6 @@ type ModifyConversationFieldReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type ModifyConversationFieldResp struct { type ModifyConversationFieldResp struct {
CommResp
} }
type BatchSetConversationsReq struct { type BatchSetConversationsReq struct {
@ -78,7 +73,6 @@ type BatchSetConversationsReq struct {
} }
type BatchSetConversationsResp struct { type BatchSetConversationsResp struct {
CommResp
Data struct { Data struct {
Success []string `json:"success"` Success []string `json:"success"`
Failed []string `json:"failed"` Failed []string `json:"failed"`
@ -92,7 +86,6 @@ type GetConversationReq struct {
} }
type GetConversationResp struct { type GetConversationResp struct {
CommResp
Conversation Conversation `json:"data"` Conversation Conversation `json:"data"`
} }
@ -102,7 +95,6 @@ type GetAllConversationsReq struct {
} }
type GetAllConversationsResp struct { type GetAllConversationsResp struct {
CommResp
Conversations []Conversation `json:"data"` Conversations []Conversation `json:"data"`
} }
@ -113,7 +105,6 @@ type GetConversationsReq struct {
} }
type GetConversationsResp struct { type GetConversationsResp struct {
CommResp
Conversations []Conversation `json:"data"` Conversations []Conversation `json:"data"`
} }
@ -126,5 +117,4 @@ type SetRecvMsgOptReq struct {
} }
type SetRecvMsgOptResp struct { type SetRecvMsgOptResp struct {
CommResp
} }

View File

@ -13,7 +13,6 @@ type TencentCloudStorageCredentialRespData struct {
} }
type TencentCloudStorageCredentialResp struct { type TencentCloudStorageCredentialResp struct {
CommResp
CosData TencentCloudStorageCredentialRespData `json:"-"` CosData TencentCloudStorageCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"` Data map[string]interface{} `json:"data"`

View File

@ -10,7 +10,7 @@ package apistruct
// ParamsCommFriend // ParamsCommFriend
//} //}
//type AddBlacklistResp struct { //type AddBlacklistResp struct {
// CommResp //
//} //}
// //
//type ImportFriendReq struct { //type ImportFriendReq struct {
@ -23,7 +23,7 @@ package apistruct
// Result int32 `json:"result"` // Result int32 `json:"result"`
//} //}
//type ImportFriendResp struct { //type ImportFriendResp struct {
// CommResp //
// UserIDResultList []UserIDResult `json:"data"` // UserIDResultList []UserIDResult `json:"data"`
//} //}
// //
@ -32,7 +32,7 @@ package apistruct
// ReqMsg string `json:"reqMsg"` // ReqMsg string `json:"reqMsg"`
//} //}
//type AddFriendResp struct { //type AddFriendResp struct {
// CommResp //
//} //}
// //
//type AddFriendResponseReq struct { //type AddFriendResponseReq struct {
@ -41,14 +41,14 @@ package apistruct
// HandleMsg string `json:"handleMsg"` // HandleMsg string `json:"handleMsg"`
//} //}
//type AddFriendResponseResp struct { //type AddFriendResponseResp struct {
// CommResp //
//} //}
// //
//type DeleteFriendReq struct { //type DeleteFriendReq struct {
// ParamsCommFriend // ParamsCommFriend
//} //}
//type DeleteFriendResp struct { //type DeleteFriendResp struct {
// CommResp //
//} //}
// //
//type GetBlackListReq struct { //type GetBlackListReq struct {
@ -56,7 +56,7 @@ package apistruct
// FromUserID string `json:"fromUserID" binding:"required"` // FromUserID string `json:"fromUserID" binding:"required"`
//} //}
//type GetBlackListResp struct { //type GetBlackListResp struct {
// CommResp //
// BlackUserInfoList []*sdkws.PublicUserInfo `json:"-"` // BlackUserInfoList []*sdkws.PublicUserInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -73,14 +73,14 @@ package apistruct
// Remark string `json:"remark"` // Remark string `json:"remark"`
//} //}
//type SetFriendRemarkResp struct { //type SetFriendRemarkResp struct {
// CommResp //
//} //}
// //
//type RemoveBlacklistReq struct { //type RemoveBlacklistReq struct {
// ParamsCommFriend // ParamsCommFriend
//} //}
//type RemoveBlacklistResp struct { //type RemoveBlacklistResp struct {
// CommResp //
//} //}
// //
//type IsFriendReq struct { //type IsFriendReq struct {
@ -90,7 +90,7 @@ package apistruct
// Friend bool `json:"isFriend"` // Friend bool `json:"isFriend"`
//} //}
//type IsFriendResp struct { //type IsFriendResp struct {
// CommResp //
// Response Response `json:"data"` // Response Response `json:"data"`
//} //}
// //
@ -98,7 +98,7 @@ package apistruct
// ParamsCommFriend // ParamsCommFriend
//} //}
//type GetFriendsInfoResp struct { //type GetFriendsInfoResp struct {
// CommResp //
// FriendInfoList []*sdkws.FriendInfo `json:"-"` // FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -108,7 +108,7 @@ package apistruct
// FromUserID string `json:"fromUserID" binding:"required"` // FromUserID string `json:"fromUserID" binding:"required"`
//} //}
//type GetFriendListResp struct { //type GetFriendListResp struct {
// CommResp //
// FriendInfoList []*sdkws.FriendInfo `json:"-"` // FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -118,7 +118,7 @@ package apistruct
// FromUserID string `json:"fromUserID" binding:"required"` // FromUserID string `json:"fromUserID" binding:"required"`
//} //}
//type GetFriendApplyListResp struct { //type GetFriendApplyListResp struct {
// CommResp //
// FriendRequestList []*sdkws.FriendRequest `json:"-"` // FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -128,7 +128,7 @@ package apistruct
// FromUserID string `json:"fromUserID" binding:"required"` // FromUserID string `json:"fromUserID" binding:"required"`
//} //}
//type GetSelfApplyListResp struct { //type GetSelfApplyListResp struct {
// CommResp //
// FriendRequestList []*sdkws.FriendRequest `json:"-"` // FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -180,7 +180,7 @@ type ImportFriendReq struct {
} }
type ImportFriendResp struct { type ImportFriendResp struct {
//CommResp //
} }
type AddFriendReq struct { type AddFriendReq struct {
@ -189,7 +189,7 @@ type AddFriendReq struct {
ReqMsg string `json:"reqMsg"` ReqMsg string `json:"reqMsg"`
} }
type AddFriendResp struct { type AddFriendResp struct {
//CommResp //
} }
type AddFriendResponseReq struct { type AddFriendResponseReq struct {

View File

@ -4,16 +4,6 @@ import (
sdkws "OpenIM/pkg/proto/sdkws" sdkws "OpenIM/pkg/proto/sdkws"
) )
type CommResp struct {
ErrCode int32 `json:"errCode"`
ErrMsg string `json:"errMsg"`
}
type CommDataResp struct {
CommResp
Data []map[string]interface{} `json:"data"`
}
type KickGroupMemberReq struct { type KickGroupMemberReq struct {
GroupID string `json:"groupID" binding:"required"` GroupID string `json:"groupID" binding:"required"`
KickedUserIDList []string `json:"kickedUserIDList" binding:"required"` KickedUserIDList []string `json:"kickedUserIDList" binding:"required"`
@ -21,7 +11,7 @@ type KickGroupMemberReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type KickGroupMemberResp struct { type KickGroupMemberResp struct {
CommResp
//UserIDResultList []*UserIDResult `json:"data"` //UserIDResultList []*UserIDResult `json:"data"`
} }
@ -31,7 +21,6 @@ type GetGroupMembersInfoReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type GetGroupMembersInfoResp struct { type GetGroupMembersInfoResp struct {
CommResp
MemberList []*sdkws.GroupMemberFullInfo `json:"-"` MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -43,7 +32,7 @@ type InviteUserToGroupReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type InviteUserToGroupResp struct { type InviteUserToGroupResp struct {
CommResp
//UserIDResultList []*UserIDResult `json:"data"` //UserIDResultList []*UserIDResult `json:"data"`
} }
@ -52,7 +41,6 @@ type GetJoinedGroupListReq struct {
FromUserID string `json:"fromUserID" binding:"required"` FromUserID string `json:"fromUserID" binding:"required"`
} }
type GetJoinedGroupListResp struct { type GetJoinedGroupListResp struct {
CommResp
GroupInfoList []*sdkws.GroupInfo `json:"-"` GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -64,7 +52,6 @@ type GetGroupMemberListReq struct {
OperationID string `json:"operationID"` OperationID string `json:"operationID"`
} }
type GetGroupMemberListResp struct { type GetGroupMemberListResp struct {
CommResp
NextSeq int32 `json:"nextSeq"` NextSeq int32 `json:"nextSeq"`
MemberList []*sdkws.GroupMemberFullInfo `json:"-"` MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
@ -77,7 +64,6 @@ type GetGroupAllMemberReq struct {
Count int32 `json:"count"` Count int32 `json:"count"`
} }
type GetGroupAllMemberResp struct { type GetGroupAllMemberResp struct {
CommResp
MemberList []*sdkws.GroupMemberFullInfo `json:"-"` MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -90,7 +76,7 @@ type GetGroupAllMemberResp struct {
// Count int32 `json:"count" binding:"required"` // Count int32 `json:"count" binding:"required"`
//} //}
//type GetGroupAllMemberListBySplitResp struct { //type GetGroupAllMemberListBySplitResp struct {
// CommResp //
// MemberList []*sdkws.GroupMemberFullInfo `json:"-"` // MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"` // Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//} //}
@ -108,7 +94,6 @@ type CreateGroupReq struct {
GroupID string `json:"groupID"` GroupID string `json:"groupID"`
} }
type CreateGroupResp struct { type CreateGroupResp struct {
CommResp
GroupInfo sdkws.GroupInfo `json:"-"` GroupInfo sdkws.GroupInfo `json:"-"`
Data map[string]interface{} `json:"data" swaggerignore:"true"` Data map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -118,7 +103,6 @@ type GetGroupApplicationListReq struct {
FromUserID string `json:"fromUserID" binding:"required"` //作为管理员或群主收到的 进群申请 FromUserID string `json:"fromUserID" binding:"required"` //作为管理员或群主收到的 进群申请
} }
type GetGroupApplicationListResp struct { type GetGroupApplicationListResp struct {
CommResp
GroupRequestList []*sdkws.GroupRequest `json:"-"` GroupRequestList []*sdkws.GroupRequest `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -137,7 +121,6 @@ type GetGroupInfoReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type GetGroupInfoResp struct { type GetGroupInfoResp struct {
CommResp
GroupInfoList []*sdkws.GroupInfo `json:"-"` GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"` Data []map[string]interface{} `json:"data" swaggerignore:"true"`
} }
@ -171,7 +154,6 @@ type ApplicationGroupResponseReq struct {
HandleResult int32 `json:"handleResult" binding:"required,oneof=-1 1"` HandleResult int32 `json:"handleResult" binding:"required,oneof=-1 1"`
} }
type ApplicationGroupResponseResp struct { type ApplicationGroupResponseResp struct {
CommResp
} }
type JoinGroupReq struct { type JoinGroupReq struct {
@ -183,7 +165,6 @@ type JoinGroupReq struct {
} }
type JoinGroupResp struct { type JoinGroupResp struct {
CommResp
} }
type QuitGroupReq struct { type QuitGroupReq struct {
@ -191,7 +172,6 @@ type QuitGroupReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type QuitGroupResp struct { type QuitGroupResp struct {
CommResp
} }
type SetGroupInfoReq struct { type SetGroupInfoReq struct {
@ -208,7 +188,6 @@ type SetGroupInfoReq struct {
} }
type SetGroupInfoResp struct { type SetGroupInfoResp struct {
CommResp
} }
type TransferGroupOwnerReq struct { type TransferGroupOwnerReq struct {
@ -218,7 +197,6 @@ type TransferGroupOwnerReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type TransferGroupOwnerResp struct { type TransferGroupOwnerResp struct {
CommResp
} }
type DismissGroupReq struct { type DismissGroupReq struct {
@ -226,7 +204,6 @@ type DismissGroupReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type DismissGroupResp struct { type DismissGroupResp struct {
CommResp
} }
type MuteGroupMemberReq struct { type MuteGroupMemberReq struct {
@ -236,7 +213,6 @@ type MuteGroupMemberReq struct {
MutedSeconds uint32 `json:"mutedSeconds" binding:"required"` MutedSeconds uint32 `json:"mutedSeconds" binding:"required"`
} }
type MuteGroupMemberResp struct { type MuteGroupMemberResp struct {
CommResp
} }
type CancelMuteGroupMemberReq struct { type CancelMuteGroupMemberReq struct {
@ -245,7 +221,6 @@ type CancelMuteGroupMemberReq struct {
UserID string `json:"userID" binding:"required"` UserID string `json:"userID" binding:"required"`
} }
type CancelMuteGroupMemberResp struct { type CancelMuteGroupMemberResp struct {
CommResp
} }
type MuteGroupReq struct { type MuteGroupReq struct {
@ -253,7 +228,6 @@ type MuteGroupReq struct {
GroupID string `json:"groupID" binding:"required"` GroupID string `json:"groupID" binding:"required"`
} }
type MuteGroupResp struct { type MuteGroupResp struct {
CommResp
} }
type CancelMuteGroupReq struct { type CancelMuteGroupReq struct {
@ -261,7 +235,6 @@ type CancelMuteGroupReq struct {
GroupID string `json:"groupID" binding:"required"` GroupID string `json:"groupID" binding:"required"`
} }
type CancelMuteGroupResp struct { type CancelMuteGroupResp struct {
CommResp
} }
type SetGroupMemberNicknameReq struct { type SetGroupMemberNicknameReq struct {
@ -272,7 +245,6 @@ type SetGroupMemberNicknameReq struct {
} }
type SetGroupMemberNicknameResp struct { type SetGroupMemberNicknameResp struct {
CommResp
} }
type SetGroupMemberInfoReq struct { type SetGroupMemberInfoReq struct {
@ -286,7 +258,6 @@ type SetGroupMemberInfoReq struct {
} }
type SetGroupMemberInfoResp struct { type SetGroupMemberInfoResp struct {
CommResp
} }
type GetGroupAbstractInfoReq struct { type GetGroupAbstractInfoReq struct {
@ -295,7 +266,6 @@ type GetGroupAbstractInfoReq struct {
} }
type GetGroupAbstractInfoResp struct { type GetGroupAbstractInfoResp struct {
CommResp
GroupMemberNumber int32 `json:"groupMemberNumber"` GroupMemberNumber int32 `json:"groupMemberNumber"`
GroupMemberListHash uint64 `json:"groupMemberListHash"` GroupMemberListHash uint64 `json:"groupMemberListHash"`
} }

View File

@ -9,14 +9,12 @@ type DeleteUsersReq struct {
DeleteUserIDList []string `json:"deleteUserIDList" binding:"required"` DeleteUserIDList []string `json:"deleteUserIDList" binding:"required"`
} }
type DeleteUsersResp struct { type DeleteUsersResp struct {
CommResp
FailedUserIDList []string `json:"data"` FailedUserIDList []string `json:"data"`
} }
type GetAllUsersUidReq struct { type GetAllUsersUidReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
} }
type GetAllUsersUidResp struct { type GetAllUsersUidResp struct {
CommResp
UserIDList []string `json:"data"` UserIDList []string `json:"data"`
} }
type GetUsersOnlineStatusReq struct { type GetUsersOnlineStatusReq struct {
@ -24,7 +22,7 @@ type GetUsersOnlineStatusReq struct {
UserIDList []string `json:"userIDList" binding:"required,lte=200"` UserIDList []string `json:"userIDList" binding:"required,lte=200"`
} }
type GetUsersOnlineStatusResp struct { type GetUsersOnlineStatusResp struct {
CommResp
//SuccessResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult `json:"data"` //SuccessResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult `json:"data"`
} }
type AccountCheckReq struct { type AccountCheckReq struct {
@ -32,7 +30,7 @@ type AccountCheckReq struct {
CheckUserIDList []string `json:"checkUserIDList" binding:"required,lte=100"` CheckUserIDList []string `json:"checkUserIDList" binding:"required,lte=100"`
} }
type AccountCheckResp struct { type AccountCheckResp struct {
CommResp
//ResultList []*pbUser.AccountCheckResp_SingleUserStatus `json:"data"` //ResultList []*pbUser.AccountCheckResp_SingleUserStatus `json:"data"`
} }
@ -69,7 +67,6 @@ type ManagementBatchSendMsgReq struct {
} }
type ManagementBatchSendMsgResp struct { type ManagementBatchSendMsgResp struct {
CommResp
Data struct { Data struct {
ResultList []*SingleReturnResult `json:"resultList"` ResultList []*SingleReturnResult `json:"resultList"`
FailedIDList []string FailedIDList []string
@ -87,7 +84,6 @@ type CheckMsgIsSendSuccessReq struct {
} }
type CheckMsgIsSendSuccessResp struct { type CheckMsgIsSendSuccessResp struct {
CommResp
Status int32 `json:"status"` Status int32 `json:"status"`
} }
@ -119,7 +115,6 @@ type CMSUser struct {
} }
type GetUsersResp struct { type GetUsersResp struct {
CommResp
Data struct { Data struct {
UserList []*CMSUser `json:"userList"` UserList []*CMSUser `json:"userList"`
TotalNum int32 `json:"totalNum"` TotalNum int32 `json:"totalNum"`

View File

@ -12,7 +12,6 @@ type DelMsgReq struct {
} }
type DelMsgResp struct { type DelMsgResp struct {
CommResp
} }
type CleanUpMsgReq struct { type CleanUpMsgReq struct {
@ -21,7 +20,6 @@ type CleanUpMsgReq struct {
} }
type CleanUpMsgResp struct { type CleanUpMsgResp struct {
CommResp
} }
type DelSuperGroupMsgReq struct { type DelSuperGroupMsgReq struct {
@ -33,7 +31,6 @@ type DelSuperGroupMsgReq struct {
} }
type DelSuperGroupMsgResp struct { type DelSuperGroupMsgResp struct {
CommResp
} }
type MsgDeleteNotificationElem struct { type MsgDeleteNotificationElem struct {
@ -50,7 +47,6 @@ type SetMsgMinSeqReq struct {
} }
type SetMsgMinSeqResp struct { type SetMsgMinSeqResp struct {
CommResp
} }
type ModifyMessageReactionExtensionsReq struct { type ModifyMessageReactionExtensionsReq struct {
@ -67,7 +63,6 @@ type ModifyMessageReactionExtensionsReq struct {
} }
type ModifyMessageReactionExtensionsResp struct { type ModifyMessageReactionExtensionsResp struct {
CommResp
Data struct { Data struct {
ResultKeyValue []*msg.KeyValueResp `json:"result"` ResultKeyValue []*msg.KeyValueResp `json:"result"`
MsgFirstModifyTime int64 `json:"msgFirstModifyTime"` MsgFirstModifyTime int64 `json:"msgFirstModifyTime"`
@ -83,7 +78,6 @@ type ModifyMessageReactionExtensionsResp struct {
//} //}
type OperateMessageListReactionExtensionsResp struct { type OperateMessageListReactionExtensionsResp struct {
CommResp
Data struct { Data struct {
SuccessList []*msg.ExtendMsgResp `json:"successList"` SuccessList []*msg.ExtendMsgResp `json:"successList"`
FailedList []*msg.ExtendMsgResp `json:"failedList"` FailedList []*msg.ExtendMsgResp `json:"failedList"`
@ -97,7 +91,6 @@ type SetMessageReactionExtensionsCallbackResp ModifyMessageReactionExtensionsRes
//type GetMessageListReactionExtensionsReq OperateMessageListReactionExtensionsReq //type GetMessageListReactionExtensionsReq OperateMessageListReactionExtensionsReq
type GetMessageListReactionExtensionsResp struct { type GetMessageListReactionExtensionsResp struct {
CommResp
Data []*msg.SingleMessageExtensionResult `json:"data"` Data []*msg.SingleMessageExtensionResult `json:"data"`
} }
@ -116,7 +109,6 @@ type DeleteMessageReactionExtensionsReq struct {
} }
type DeleteMessageReactionExtensionsResp struct { type DeleteMessageReactionExtensionsResp struct {
CommResp
Data []*msg.KeyValueResp Data []*msg.KeyValueResp
} }

View File

@ -16,7 +16,6 @@ type OSSCredentialRespData struct {
} }
type OSSCredentialResp struct { type OSSCredentialResp struct {
CommResp
OssData OSSCredentialRespData `json:"-"` OssData OSSCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"` Data map[string]interface{} `json:"data"`
} }

View File

@ -29,7 +29,6 @@ type MinioUploadFile struct {
} }
type MinioUploadFileResp struct { type MinioUploadFileResp struct {
CommResp
Data struct { Data struct {
MinioUploadFile MinioUploadFile
} `json:"data"` } `json:"data"`
@ -46,7 +45,6 @@ type UploadUpdateAppReq struct {
} }
type UploadUpdateAppResp struct { type UploadUpdateAppResp struct {
CommResp
} }
type GetDownloadURLReq struct { type GetDownloadURLReq struct {
@ -56,7 +54,6 @@ type GetDownloadURLReq struct {
} }
type GetDownloadURLResp struct { type GetDownloadURLResp struct {
CommResp
Data struct { Data struct {
HasNewVersion bool `json:"hasNewVersion"` HasNewVersion bool `json:"hasNewVersion"`
ForceUpdate bool `json:"forceUpdate"` ForceUpdate bool `json:"forceUpdate"`
@ -73,7 +70,6 @@ type GetRTCInvitationInfoReq struct {
} }
type GetRTCInvitationInfoResp struct { type GetRTCInvitationInfoResp struct {
CommResp
Data struct { Data struct {
OpUserID string `json:"opUserID"` OpUserID string `json:"opUserID"`
Invitation struct { Invitation struct {
@ -110,7 +106,6 @@ type FcmUpdateTokenReq struct {
} }
type FcmUpdateTokenResp struct { type FcmUpdateTokenResp struct {
CommResp
} }
type SetAppBadgeReq struct { type SetAppBadgeReq struct {
OperationID string `json:"operationID" binding:"required"` OperationID string `json:"operationID" binding:"required"`
@ -119,5 +114,4 @@ type SetAppBadgeReq struct {
} }
type SetAppBadgeResp struct { type SetAppBadgeResp struct {
CommResp
} }

View File

@ -2,6 +2,7 @@ package cmd
import ( import (
"OpenIM/internal/msggateway" "OpenIM/internal/msggateway"
//"OpenIM/internal/msggateway"
"OpenIM/pkg/common/constant" "OpenIM/pkg/common/constant"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -23,14 +24,13 @@ func (m *MsgGatewayCmd) getWsPortFlag(cmd *cobra.Command) int {
return port return port
} }
func (m *MsgGatewayCmd) addRun() { func (m *MsgGatewayCmd) addRunE() {
m.Command.Run = func(cmd *cobra.Command, args []string) { m.Command.RunE = func(cmd *cobra.Command, args []string) error {
msggateway.Init(m.getPortFlag(cmd), m.getWsPortFlag(cmd)) return msggateway.RunWsAndServer(m.getPortFlag(cmd), m.getWsPortFlag(cmd), m.getPrometheusPortFlag(cmd))
msggateway.Run(m.getPrometheusPortFlag(cmd))
} }
} }
func (m *MsgGatewayCmd) Exec() error { func (m *MsgGatewayCmd) Exec() error {
m.addRun() m.addRunE()
return m.Execute() return m.Execute()
} }

View File

@ -8,15 +8,15 @@ import (
) )
type PushCmd struct { type PushCmd struct {
*RpcCmd *AuthCmd
} }
func NewPushCmd() *PushCmd { func NewPushCmd() *PushCmd {
return &PushCmd{NewRpcCmd(config.Config.RpcRegisterName.OpenImPushName)} return &PushCmd{NewAuthCmd()}
} }
func (r *RpcCmd) AddPush() { func (r *PushCmd) AddPush() {
r.Command.RunE = func(cmd *cobra.Command, args []string) error { r.Command.RunE = func(cmd *cobra.Command, args []string) error {
return startrpc.Start(r.getPortFlag(cmd), r.rpcRegisterName, r.getPrometheusPortFlag(cmd), push.Start) return startrpc.Start(r.getPortFlag(cmd), config.Config.RpcRegisterName.OpenImPushName, r.getPrometheusPortFlag(cmd), push.Start)
} }
} }

View File

@ -7,7 +7,9 @@ import (
) )
type RootCmd struct { type RootCmd struct {
Command cobra.Command Command cobra.Command
port int
prometheusPort int
} }
func NewRootCmd() (rootCmd *RootCmd) { func NewRootCmd() (rootCmd *RootCmd) {
@ -50,8 +52,12 @@ func (r *RootCmd) getPortFlag(cmd *cobra.Command) int {
return port return port
} }
func (r *RootCmd) GetPortFlag() int {
return r.port
}
func (r *RootCmd) AddPrometheusPortFlag() { func (r *RootCmd) AddPrometheusPortFlag() {
r.Command.Flags().StringP(constant.FlagPrometheusPort, "pp", "", "server prometheus listen port") r.Command.Flags().String(constant.FlagPrometheusPort, "", "server prometheus listen port")
} }
func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int { func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
@ -59,6 +65,10 @@ func (r *RootCmd) getPrometheusPortFlag(cmd *cobra.Command) int {
return port return port
} }
func (r *RootCmd) GetPrometheusPortFlag() int {
return r.prometheusPort
}
func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error { func (r *RootCmd) getConfFromCmdAndInit(cmdLines *cobra.Command) error {
configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf) configFolderPath, _ := cmdLines.Flags().GetString(constant.FlagConf)
return config.InitConfig(configFolderPath) return config.InitConfig(configFolderPath)

View File

@ -7,22 +7,23 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
) )
type RpcCmd struct { type AuthCmd struct {
*RootCmd *RootCmd
rpcRegisterName string
} }
func NewRpcCmd(rpcRegisterName string) *RpcCmd { func NewAuthCmd() *AuthCmd {
return &RpcCmd{NewRootCmd(), rpcRegisterName} authCmd := &AuthCmd{NewRootCmd()}
return authCmd
} }
func (r *RpcCmd) AddRpc(rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) { func (a *AuthCmd) Exec() error {
r.Command.RunE = func(cmd *cobra.Command, args []string) error { a.Command.Run = func(cmd *cobra.Command, args []string) {
return startrpc.Start(r.getPortFlag(cmd), r.rpcRegisterName, r.getPrometheusPortFlag(cmd), rpcFn) a.port = a.getPortFlag(cmd)
a.prometheusPort = a.getPrometheusPortFlag(cmd)
} }
return a.Execute()
} }
func (r *RpcCmd) Exec(rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error { func (a *AuthCmd) StartSvr(name string, rpcFn func(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error) error {
r.AddRpc(rpcFn) return startrpc.Start(a.GetPortFlag(), name, a.GetPrometheusPortFlag(), rpcFn)
return r.Execute()
} }

View File

@ -176,7 +176,7 @@ type config struct {
ZkAddr []string `yaml:"zkAddr"` ZkAddr []string `yaml:"zkAddr"`
UserName string `yaml:"userName"` UserName string `yaml:"userName"`
Password string `yaml:"password"` Password string `yaml:"password"`
} } `yaml:"zookeeper"`
Log struct { Log struct {
StorageLocation string `yaml:"storageLocation"` StorageLocation string `yaml:"storageLocation"`
RotationTime int `yaml:"rotationTime"` RotationTime int `yaml:"rotationTime"`
@ -515,9 +515,10 @@ func (c *config) initConfig(config interface{}, configName, configFolderPath str
return err return err
} }
configPath = filepath.Join(Root, "config", configName) configPath = filepath.Join(Root, "config", configName)
fmt.Println(configPath, "not exist, use", configPath) fmt.Println("use", configPath)
} else {
Root = filepath.Dir(configPath)
} }
Root = filepath.Dir(configPath)
return c.unmarshalConfig(config, configPath) return c.unmarshalConfig(config, configPath)
} }

View File

@ -1,16 +1,6 @@
package constant package constant
const ( const (
//Websocket Protocol
WSGetNewestSeq = 1001
WSPullMsgBySeqList = 1002
WSSendMsg = 1003
WSSendSignalMsg = 1004
WSPushMsg = 2001
WSKickOnlineMsg = 2002
WsLogoutMsg = 2003
WsSetBackgroundStatus = 2004
WSDataError = 3001
///ContentType ///ContentType
//UserRelated //UserRelated

View File

@ -5,6 +5,7 @@ import (
"context" "context"
) )
// for mongoDB
type ExtendMsgDatabase interface { type ExtendMsgDatabase interface {
CreateExtendMsgSet(ctx context.Context, set *unRelationTb.ExtendMsgSetModel) error CreateExtendMsgSet(ctx context.Context, set *unRelationTb.ExtendMsgSetModel) error
GetAllExtendMsgSet(ctx context.Context, ID string, opts *unRelationTb.GetAllExtendMsgSetOpts) (sets []*unRelationTb.ExtendMsgSetModel, err error) GetAllExtendMsgSet(ctx context.Context, ID string, opts *unRelationTb.GetAllExtendMsgSetOpts) (sets []*unRelationTb.ExtendMsgSetModel, err error)

View File

@ -76,6 +76,9 @@ func NewGroupDatabase(
} }
func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database) GroupDatabase { func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.Database) GroupDatabase {
rcOptions := rockscache.NewDefaultOptions()
rcOptions.StrongConsistency = true
rcOptions.RandomExpireAdjustment = 0.2
return NewGroupDatabase( return NewGroupDatabase(
relation.NewGroupDB(db), relation.NewGroupDB(db),
relation.NewGroupMemberDB(db), relation.NewGroupMemberDB(db),
@ -83,10 +86,7 @@ func InitGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, database *mongo.D
tx.NewGorm(db), tx.NewGorm(db),
tx.NewMongo(database.Client()), tx.NewMongo(database.Client()),
unrelation.NewSuperGroupMongoDriver(database), unrelation.NewSuperGroupMongoDriver(database),
cache.NewGroupCacheRedis(rdb, relation.NewGroupDB(db), relation.NewGroupMemberDB(db), relation.NewGroupRequest(db), unrelation.NewSuperGroupMongoDriver(database), rockscache.Options{ cache.NewGroupCacheRedis(rdb, relation.NewGroupDB(db), relation.NewGroupMemberDB(db), relation.NewGroupRequest(db), unrelation.NewSuperGroupMongoDriver(database), rcOptions),
StrongConsistency: true,
RandomExpireAdjustment: 2.0,
}),
) )
} }

View File

@ -1,10 +1,12 @@
package controller package controller
import ( import (
"OpenIM/pkg/common/config"
"OpenIM/pkg/common/constant" "OpenIM/pkg/common/constant"
"OpenIM/pkg/common/db/cache" "OpenIM/pkg/common/db/cache"
unRelationTb "OpenIM/pkg/common/db/table/unrelation" unRelationTb "OpenIM/pkg/common/db/table/unrelation"
"OpenIM/pkg/common/db/unrelation" "OpenIM/pkg/common/db/unrelation"
"OpenIM/pkg/common/kafka"
"OpenIM/pkg/common/log" "OpenIM/pkg/common/log"
"OpenIM/pkg/common/prome" "OpenIM/pkg/common/prome"
"OpenIM/pkg/common/tracelog" "OpenIM/pkg/common/tracelog"
@ -68,7 +70,7 @@ type MsgDatabase interface {
DeleteReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*sdkws.KeyValue) error DeleteReactionExtendMsgSet(ctx context.Context, sourceID string, sessionType int32, clientMsgID string, msgFirstModifyTime int64, reactionExtensionList map[string]*sdkws.KeyValue) error
SetSendMsgStatus(ctx context.Context, id string, status int32) error SetSendMsgStatus(ctx context.Context, id string, status int32) error
GetSendMsgStatus(ctx context.Context, id string) (int32, error) GetSendMsgStatus(ctx context.Context, id string) (int32, error)
MsgToMQ(ctx context.Context, key string, mq *pbMsg.MsgDataToMQ) error MsgToMQ(ctx context.Context, key string, msg2mq *pbMsg.MsgDataToMQ) error
GetUserMaxSeq(ctx context.Context, userID string) (int64, error) GetUserMaxSeq(ctx context.Context, userID string) (int64, error)
GetUserMinSeq(ctx context.Context, userID string) (int64, error) GetUserMinSeq(ctx context.Context, userID string) (int64, error)
GetGroupMaxSeq(ctx context.Context, groupID string) (int64, error) GetGroupMaxSeq(ctx context.Context, groupID string) (int64, error)
@ -79,6 +81,7 @@ func NewMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel ca
return &msgDatabase{ return &msgDatabase{
msgDocDatabase: msgDocModel, msgDocDatabase: msgDocModel,
cache: cacheModel, cache: cacheModel,
producer: kafka.NewKafkaProducer(config.Config.Kafka.Ws2mschat.Addr, config.Config.Kafka.Ws2mschat.Topic),
} }
} }
@ -93,6 +96,8 @@ type msgDatabase struct {
msgDocDatabase unRelationTb.MsgDocModelInterface msgDocDatabase unRelationTb.MsgDocModelInterface
extendMsgDatabase unRelationTb.ExtendMsgSetModelInterface extendMsgDatabase unRelationTb.ExtendMsgSetModelInterface
cache cache.Model cache cache.Model
producer *kafka.Producer
// model
msg unRelationTb.MsgDocModel msg unRelationTb.MsgDocModel
extendMsgSetModel unRelationTb.ExtendMsgSetModel extendMsgSetModel unRelationTb.ExtendMsgSetModel
} }
@ -165,9 +170,9 @@ func (db *msgDatabase) GetSendMsgStatus(ctx context.Context, id string) (int32,
return db.cache.GetSendMsgStatus(ctx, id) return db.cache.GetSendMsgStatus(ctx, id)
} }
func (db *msgDatabase) MsgToMQ(ctx context.Context, key string, mq *pbMsg.MsgDataToMQ) error { func (db *msgDatabase) MsgToMQ(ctx context.Context, key string, msg2mq *pbMsg.MsgDataToMQ) error {
//TODO implement me _, _, err := db.producer.SendMessage(ctx, key, msg2mq)
panic("implement me") return err
} }
func (db *msgDatabase) GetUserMaxSeq(ctx context.Context, userID string) (int64, error) { func (db *msgDatabase) GetUserMaxSeq(ctx context.Context, userID string) (int64, error) {

View File

@ -10,7 +10,7 @@ import (
const ( const (
singleGocMsgNum = 5000 singleGocMsgNum = 5000
CChat = "msg" Msg = "msg"
OldestList = 0 OldestList = 0
NewestList = -1 NewestList = -1
) )
@ -38,7 +38,7 @@ type MsgDocModelInterface interface {
} }
func (MsgDocModel) TableName() string { func (MsgDocModel) TableName() string {
return CChat return Msg
} }
func (MsgDocModel) GetSingleGocMsgNum() int64 { func (MsgDocModel) GetSingleGocMsgNum() int64 {

View File

@ -61,7 +61,7 @@ func (m *Mongo) GetDatabase() *mongo.Database {
} }
func (m *Mongo) CreateMsgIndex() error { func (m *Mongo) CreateMsgIndex() error {
return m.createMongoIndex(unrelation.CChat, false, "uid") return m.createMongoIndex(unrelation.Msg, false, "uid")
} }
func (m *Mongo) CreateSuperGroupIndex() error { func (m *Mongo) CreateSuperGroupIndex() error {

View File

@ -46,7 +46,7 @@ func NewKafkaProducer(addr []string, topic string) *Producer {
return &p return &p
} }
func (p *Producer) SendMessage(ctx context.Context, m proto.Message, key string) (int32, int64, error) { func (p *Producer) SendMessage(ctx context.Context, key string, m proto.Message) (int32, int64, error) {
operationID := tracelog.GetOperationID(ctx) operationID := tracelog.GetOperationID(ctx)
log.Info(operationID, "SendMessage", "key ", key, m.String(), p.producer) log.Info(operationID, "SendMessage", "key ", key, m.String(), p.producer)
kMsg := &sarama.ProducerMessage{} kMsg := &sarama.ProducerMessage{}

View File

@ -90,3 +90,6 @@ func ParseRedisInterfaceToken(redisToken interface{}) (*Claims, error) {
func IsManagerUserID(opUserID string) bool { func IsManagerUserID(opUserID string) bool {
return utils.IsContain(opUserID, config.Config.Manager.AppManagerUid) return utils.IsContain(opUserID, config.Config.Manager.AppManagerUid)
} }
func WsVerifyToken(token, userID, platformID string) error {
return nil
}

View File

@ -9,6 +9,7 @@ type SvcDiscoveryRegistry interface {
UnRegister() error UnRegister() error
GetConns(serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error) GetConns(serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error)
GetConn(serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error) GetConn(serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
AddOption(opts ...grpc.DialOption)
RegisterConf2Registry(key string, conf []byte) error RegisterConf2Registry(key string, conf []byte) error
GetConfFromRegistry(key string) ([]byte, error) GetConfFromRegistry(key string) ([]byte, error)

View File

@ -22,22 +22,19 @@ func CopyStructFields(a interface{}, b interface{}, fields ...string) (err error
} }
func Wrap1(err error) error { func Wrap1(err error) error {
if err != nil { return errors.Wrap(err, "==> " + printCallerNameAndLine())
return Wrap(err, "")
}
return nil
} }
func Wrap2[T any](a T, err error) (T, error) { func Wrap2[T any](a T, err error) (T, error) {
if err != nil { if err != nil {
return a, Wrap(err, "") return a, errors.Wrap(err, "==> " + printCallerNameAndLine())
} }
return a, nil return a, nil
} }
func Wrap3[T any, V any](a T, b V, err error) (T, V, error) { func Wrap3[T any, V any](a T, b V, err error) (T, V, error) {
if err != nil { if err != nil {
return a, b, Wrap(err, "") return a, b, errors.Wrap(err, "==> " + printCallerNameAndLine())
} }
return a, b, nil return a, b, nil
} }

View File

@ -10,7 +10,7 @@ service_port_name=(
openImUserPort openImUserPort
openImFriendPort openImFriendPort
openImMessagePort openImMessagePort
# openImMessageGatewayPort openImMessageGatewayPort
openImGroupPort openImGroupPort
openImAuthPort openImAuthPort
openImPushPort openImPushPort

View File

@ -31,7 +31,7 @@ fi
sleep 1 sleep 1
cd ${msg_gateway_binary_root} cd ${msg_gateway_binary_root}
for ((i = 0; i < ${#ws_ports[@]}; i++)); do for ((i = 0; i < ${#ws_ports[@]}; i++)); do
nohup ./${msg_gateway_name} -port ${rpc_ports[$i]} -ws_port ${ws_ports[$i]} -prometheus_port ${prome_ports[$i]} >>../logs/openIM.log 2>&1 & nohup ./${msg_gateway_name} --port ${rpc_ports[$i]} --ws_port ${ws_ports[$i]} --prometheus_port ${prome_ports[$i]} >>../logs/openIM.log 2>&1 &
done done
#Check launched service process #Check launched service process

View File

@ -25,7 +25,7 @@ for ((i = 0; i < ${msg_transfer_service_num}; i++)); do
prome_port=${prome_ports[$i]} prome_port=${prome_ports[$i]}
cmd="nohup ./${msg_transfer_name}" cmd="nohup ./${msg_transfer_name}"
if [ $prome_port != "" ]; then if [ $prome_port != "" ]; then
cmd="$cmd -prometheus_port $prome_port" cmd="$cmd --prometheus_port $prome_port"
fi fi
$cmd >>../logs/openIM.log 2>&1 & $cmd >>../logs/openIM.log 2>&1 &
done done

View File

@ -49,7 +49,7 @@ service_source_root=(
../cmd/rpc/third/ ../cmd/rpc/third/
../cmd/crontask ../cmd/crontask
../cmd/cmdutils ../cmd/cmdutils
# ${msg_gateway_source_root} ${msg_gateway_source_root}
${msg_transfer_source_root/} ${msg_transfer_source_root/}
${msg_source_root} ${msg_source_root}
${push_source_root} ${push_source_root}
@ -68,7 +68,7 @@ service_names=(
open_im_third open_im_third
open_im_cron_task open_im_cron_task
open_im_cmd_utils open_im_cmd_utils
# ${msg_gateway_name} ${msg_gateway_name}
${msg_transfer_name} ${msg_transfer_name}
${msg_name} ${msg_name}
${push_name} ${push_name}

View File

@ -25,7 +25,7 @@ sleep 1
cd ${push_binary_root} cd ${push_binary_root}
for ((i = 0; i < ${#rpc_ports[@]}; i++)); do for ((i = 0; i < ${#rpc_ports[@]}; i++)); do
nohup ./${push_name} -port ${rpc_ports[$i]} -prometheus_port ${prome_ports[$i]} >>../logs/openIM.log 2>&1 & nohup ./${push_name} --port ${rpc_ports[$i]} --prometheus_port ${prome_ports[$i]} >>../logs/openIM.log 2>&1 &
done done
sleep 3 sleep 3

View File

@ -8,7 +8,7 @@ need_to_start_server_shell=(
push_start.sh push_start.sh
msg_transfer_start.sh msg_transfer_start.sh
sdk_svr_start.sh sdk_svr_start.sh
# msg_gateway_start.sh msg_gateway_start.sh
start_cron.sh start_cron.sh
) )
time=`date +"%Y-%m-%d %H:%M:%S"` time=`date +"%Y-%m-%d %H:%M:%S"`

View File

@ -70,9 +70,13 @@ for ((i = 0; i < ${#service_filename[*]}; i++)); do
#Start related rpc services based on the number of ports #Start related rpc services based on the number of ports
for ((j = 0; j < ${#service_ports[*]}; j++)); do for ((j = 0; j < ${#service_ports[*]}; j++)); do
#Start the service in the background #Start the service in the background
cmd="./${service_filename[$i]} -port ${service_ports[$j]} -prometheus_port ${prome_ports[$j]}" if [ -z "${prome_ports[$j]}" ]; then
cmd="./${service_filename[$i]} --port ${service_ports[$j]}"
else
cmd="./${service_filename[$i]} --port ${service_ports[$j]} --prometheus_port ${prome_ports[$j]}"
fi
if [ $i -eq 0 -o $i -eq 1 ]; then if [ $i -eq 0 -o $i -eq 1 ]; then
cmd="./${service_filename[$i]} -port ${service_ports[$j]}" cmd="./${service_filename[$i]} --port ${service_ports[$j]}"
fi fi
echo $cmd echo $cmd
nohup $cmd >>../logs/openIM.log 2>&1 & nohup $cmd >>../logs/openIM.log 2>&1 &