Merge branch 'main' into fix/v3-error2

pull/562/head
Alan 2 years ago committed by GitHub
commit 3e58bbe6af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -28,46 +28,46 @@ jobs:
- name: Start Docker Compose
run: |
docker compose stop
sleep 30
docker compose up -d
sleep 60
sudo docker compose stop
sudo sleep 30
sudo docker compose up -d
sudo sleep 60
continue-on-error: true
- name: Stop all services
run: |
chmod +x ./scripts/stop_all.sh
./scripts/stop_all.sh
cat logs/openIM.log 2>/dev/null
sudo chmod +x ./scripts/stop_all.sh
sudo ./scripts/stop_all.sh
sudo cat logs/openIM.log 2>/dev/null
shell: bash
continue-on-error: true
- name: Build all services
run: |
chmod +x ./scripts/build_all_service.sh
./scripts/build_all_service.sh
cat logs/openIM.log 2>/dev/null
sudo chmod +x ./scripts/build_all_service.sh
sudo ./scripts/build_all_service.sh
sudo cat logs/openIM.log 2>/dev/null
shell: bash
continue-on-error: true
- name: Start all services
run: |
chmod +x ./scripts/start_all.sh
./scripts/start_all.sh
cat logs/openIM.log 2>/dev/null
sudo chmod +x ./scripts/start_all.sh
sudo ./scripts/start_all.sh
sudo cat logs/openIM.log 2>/dev/null
continue-on-error: true
shell: bash
- name: Check all services
run: |
chmod +x ./scripts/check_all.sh
./scripts/check_all.sh
cat logs/openIM.log 2>/dev/null
sudo chmod +x ./scripts/check_all.sh
sudo ./scripts/check_all.sh
sudo cat logs/openIM.log 2>/dev/null
shell: bash
- name: Print openIM.log
run: |
cat logs/* 2>/dev/null
cat logs/* 2>/dev/null >> "$GITHUB_OUTPUT"
sudo cat logs/* 2>/dev/null
sudo cat logs/* 2>/dev/null >> "$GITHUB_OUTPUT"
shell: bash
continue-on-error: true

@ -1,5 +1,9 @@
# Build Stage
FROM golang as build
FROM golang:1.20 AS builder
LABEL org.opencontainers.image.source=https://github.com/OpenIMSDK/Open-IM-Server
LABEL org.opencontainers.image.description="OpenIM Server image"
LABEL org.opencontainers.image.licenses="Apache 2.0"
# Set go mod installation source and proxy
ARG GO111MODULE=on
@ -24,9 +28,9 @@ RUN apk --no-cache add tzdata
VOLUME ["/Open-IM-Server/logs", "/Open-IM-Server/config", "/Open-IM-Server/scripts", "/Open-IM-Server/db/sdk"]
# Copy scripts and binary files to the production image
COPY --from=build /Open-IM-Server/scripts /Open-IM-Server/scripts
COPY --from=build /Open-IM-Server/_output/bin/platforms/linux/arm64 /Open-IM-Server/_output/bin/platforms/linux/arm64
COPY --from=builder /Open-IM-Server/scripts /Open-IM-Server/scripts
COPY --from=builder /Open-IM-Server/_output/bin/platforms/linux/amd64 /Open-IM-Server/_output/bin/platforms/linux/amd64
WORKDIR /Open-IM-Server/scripts
CMD ["./docker_start_all.sh"]
CMD ["docker_start_all.sh"]

@ -18,12 +18,12 @@ import (
"context"
"fmt"
"net"
"net/http"
"os"
"runtime"
"strconv"
"time"
"net/http"
_ "net/http/pprof"
"github.com/OpenIMSDK/Open-IM-Server/internal/api"

@ -100,7 +100,7 @@ services:
openim_server:
image: ghcr.io/openimsdk/openim-server:v3.0.0-rc.2
image: ghcr.io/openimsdk/openim-server:v3.0.1
container_name: openim-server
volumes:
- ./logs:/Open-IM-Server/logs

@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/auth"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
type AuthApi rpcclient.Auth
func NewAuthApi(discov discoveryregistry.SvcDiscoveryRegistry) AuthApi {
return AuthApi(*rpcclient.NewAuth(discov))
func NewAuthApi(client rpcclient.Auth) AuthApi {
return AuthApi(client)
}
func (o *AuthApi) UserToken(c *gin.Context) {

@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
type ConversationApi rpcclient.Conversation
func NewConversationApi(discov discoveryregistry.SvcDiscoveryRegistry) ConversationApi {
return ConversationApi(*rpcclient.NewConversation(discov))
func NewConversationApi(client rpcclient.Conversation) ConversationApi {
return ConversationApi(client)
}
func (o *ConversationApi) GetAllConversations(c *gin.Context) {

@ -16,7 +16,6 @@ package api
import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/friend"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
@ -25,8 +24,8 @@ import (
type FriendApi rpcclient.Friend
func NewFriendApi(discov discoveryregistry.SvcDiscoveryRegistry) FriendApi {
return FriendApi(*rpcclient.NewFriend(discov))
func NewFriendApi(client rpcclient.Friend) FriendApi {
return FriendApi(client)
}
func (o *FriendApi) ApplyToAddFriend(c *gin.Context) {

@ -16,7 +16,6 @@ package api
import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
@ -25,8 +24,8 @@ import (
type GroupApi rpcclient.Group
func NewGroupApi(discov discoveryregistry.SvcDiscoveryRegistry) GroupApi {
return GroupApi(*rpcclient.NewGroup(discov))
func NewGroupApi(client rpcclient.Group) GroupApi {
return GroupApi(client)
}
func (o *GroupApi) CreateGroup(c *gin.Context) {
@ -132,6 +131,7 @@ func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) {
func (o *GroupApi) GroupCreateCount(c *gin.Context) {
a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c)
}
func (o *GroupApi) GetGroups(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroups, o.Client, c)
}

@ -26,7 +26,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
@ -35,12 +34,13 @@ import (
)
type MessageApi struct {
rpcclient.Message
*rpcclient.Message
validate *validator.Validate
userRpcClient *rpcclient.UserRpcClient
}
func NewMessageApi(discov discoveryregistry.SvcDiscoveryRegistry) MessageApi {
return MessageApi{Message: *rpcclient.NewMessage(discov), validate: validator.New()}
func NewMessageApi(msgRpcClient *rpcclient.Message, userRpcClient *rpcclient.User) MessageApi {
return MessageApi{Message: msgRpcClient, validate: validator.New(), userRpcClient: rpcclient.NewUserRpcClientByUser(userRpcClient)}
}
func (MessageApi) SetOptions(options map[string]bool, value bool) {
@ -50,9 +50,10 @@ func (MessageApi) SetOptions(options map[string]bool, value bool) {
utils.SetSwitchFromOptions(options, constant.IsConversationUpdate, value)
}
func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.ManagementSendMsgReq) *msg.SendMsgReq {
func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.SendMsg) *msg.SendMsgReq {
var newContent string
var err error
options := make(map[string]bool, 5)
switch params.ContentType {
case constant.Text:
newContent = params.Content["text"].(string)
@ -70,11 +71,9 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.Manageme
fallthrough
case constant.CustomOnlineOnly:
fallthrough
case constant.Revoke:
newContent = params.Content["revokeMsgClientID"].(string)
default:
newContent = utils.StructToJsonString(params.Content)
}
options := make(map[string]bool, 5)
if params.IsOnlineOnly {
m.SetOptions(options, false)
}
@ -98,7 +97,6 @@ func (m MessageApi) newUserSendMsgReq(c *gin.Context, params *apistruct.Manageme
MsgFrom: constant.SysMsgType,
ContentType: params.ContentType,
Content: []byte(newContent),
RecvID: params.RecvID,
CreateTime: utils.GetCurrentTimestampByMill(),
Options: options,
OfflinePushInfo: params.OfflinePushInfo,
@ -163,19 +161,9 @@ func (m *MessageApi) DeleteMsgPhysical(c *gin.Context) {
a2r.Call(msg.MsgClient.DeleteMsgPhysical, m.Client, c)
}
func (m *MessageApi) SendMessage(c *gin.Context) {
params := apistruct.ManagementSendMsgReq{}
if err := c.BindJSON(&params); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
if !tokenverify.IsAppManagerUid(c) {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
func (m *MessageApi) getSendMsgReq(c *gin.Context, req apistruct.SendMsg) (sendMsgReq *msg.SendMsgReq, err error) {
var data interface{}
switch params.ContentType {
switch req.ContentType {
case constant.Text:
data = apistruct.TextElem{}
case constant.Picture:
@ -192,25 +180,44 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
data = apistruct.RevokeElem{}
case constant.OANotification:
data = apistruct.OANotificationElem{}
params.SessionType = constant.NotificationChatType
req.SessionType = constant.NotificationChatType
case constant.CustomNotTriggerConversation:
data = apistruct.CustomElem{}
case constant.CustomOnlineOnly:
data = apistruct.CustomElem{}
default:
apiresp.GinError(c, errs.ErrArgs.WithDetail("not support err contentType").Wrap())
return
return nil, errs.ErrArgs.WithDetail("not support err contentType")
}
if err := mapstructure.WeakDecode(req.Content, &data); err != nil {
return nil, err
}
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
log.ZDebug(c, "getSendMsgReq", "data", data)
if err := m.validate.Struct(data); err != nil {
return nil, err
}
return m.newUserSendMsgReq(c, &req), nil
}
func (m *MessageApi) SendMessage(c *gin.Context) {
req := apistruct.SendMsgReq{}
if err := c.BindJSON(&req); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
} else if err := m.validate.Struct(params); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
}
log.ZInfo(c, "SendMessage", "req", req)
if !tokenverify.IsAppManagerUid(c) {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
pbReq := m.newUserSendMsgReq(c, &params)
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
if err != nil {
log.ZError(c, "decodeData failed", err)
apiresp.GinError(c, err)
}
sendMsgReq.MsgData.RecvID = req.RecvID
var status int
respPb, err := m.Client.SendMsg(c, pbReq)
respPb, err := m.Client.SendMsg(c, sendMsgReq)
if err != nil {
status = constant.MsgSendFailed
apiresp.GinError(c, err)
@ -226,122 +233,62 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
apiresp.GinSuccess(c, respPb)
}
func (m *MessageApi) ManagementBatchSendMsg(c *gin.Context) {
params := apistruct.ManagementBatchSendMsgReq{}
resp := apistruct.ManagementBatchSendMsgResp{}
var msgSendFailedFlag bool
if err := c.BindJSON(&params); err != nil {
func (m *MessageApi) BatchSendMsg(c *gin.Context) {
var (
req apistruct.BatchSendMsgReq
resp apistruct.BatchSendMsgResp
)
if err := c.BindJSON(&req); err != nil {
log.ZError(c, "BatchSendMsg BindJSON failed", err)
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
if !tokenverify.IsAppManagerUid(c) {
log.ZInfo(c, "BatchSendMsg", "req", req)
if err := tokenverify.CheckAdmin(c); err != nil {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
var data interface{}
switch params.ContentType {
case constant.Text:
data = apistruct.TextElem{}
case constant.Picture:
data = apistruct.PictureElem{}
case constant.Voice:
data = apistruct.SoundElem{}
case constant.Video:
data = apistruct.VideoElem{}
case constant.File:
data = apistruct.FileElem{}
case constant.Custom:
data = apistruct.CustomElem{}
case constant.Revoke:
data = apistruct.RevokeElem{}
case constant.OANotification:
data = apistruct.OANotificationElem{}
params.SessionType = constant.NotificationChatType
case constant.CustomNotTriggerConversation:
data = apistruct.CustomElem{}
case constant.CustomOnlineOnly:
data = apistruct.CustomElem{}
default:
apiresp.GinError(c, errs.ErrArgs.WithDetail("not support err contentType").Wrap())
return
var recvIDs []string
var err error
if req.IsSendAll {
pageNumber := 1
showNumber := 500
for {
recvIDsPart, err := m.userRpcClient.GetAllUserIDs(c, int32(pageNumber), int32(showNumber))
if err != nil {
log.ZError(c, "GetAllUserIDs failed", err)
apiresp.GinError(c, err)
}
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
} else if err := m.validate.Struct(params); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
if len(recvIDsPart) < showNumber {
recvIDs = append(recvIDs, recvIDsPart...)
break
}
t := &apistruct.ManagementSendMsgReq{
SendID: params.SendID,
GroupID: params.GroupID,
SenderNickname: params.SenderNickname,
SenderFaceURL: params.SenderFaceURL,
SenderPlatformID: params.SenderPlatformID,
Content: params.Content,
ContentType: params.ContentType,
SessionType: params.SessionType,
IsOnlineOnly: params.IsOnlineOnly,
NotOfflinePush: params.NotOfflinePush,
OfflinePushInfo: params.OfflinePushInfo,
pageNumber++
}
pbReq := m.newUserSendMsgReq(c, t)
// l := len(params.RecvIDList)
// for i := 0; i < l; {
// recvList := []string{}
// if i+constant.BatchNum < l {
// recvList = params.RecvIDList[i : i+constant.BatchNum]
// } else {
// recvList = params.RecvIDList[i:]
// }
// for _, recvID := range recvList {
// pbReq.MsgData.RecvID = recvID
// rpcResp, err := m.Client.SendMsg(c, pbReq)
// if err != nil {
// resp.Data.FailedIDList = append(resp.Data.FailedIDList, recvID)
// msgSendFailedFlag = true
// continue
// }
// resp.Data.ResultList = append(resp.Data.ResultList, &apistruct.SingleReturnResult{
// ServerMsgID: rpcResp.ServerMsgID,
// ClientMsgID: rpcResp.ClientMsgID,
// SendTime: rpcResp.SendTime,
// RecvID: recvID,
// })
var recvList []string
if params.IsSendAll {
// req2 := &user.GetAllUserIDReq{}
// resp2, err := m.Message.GetAllUserID(c, req2)
// if err != nil {
// apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
// return
// }
// recvList = resp2.UserIDs
} else {
recvList = params.RecvIDList
recvIDs = req.RecvIDs
}
for _, recvID := range recvList {
pbReq.MsgData.RecvID = recvID
_, err := m.Client.SendMsg(c, pbReq)
log.ZDebug(c, "BatchSendMsg nums", "nums ", len(recvIDs))
sendMsgReq, err := m.getSendMsgReq(c, req.SendMsg)
if err != nil {
resp.Data.FailedIDList = append(resp.Data.FailedIDList, recvID)
msgSendFailedFlag = true
continue
}
}
var status int32
if msgSendFailedFlag {
status = constant.MsgSendFailed
} else {
status = constant.MsgSendSuccessed
log.ZError(c, "decodeData failed", err)
apiresp.GinError(c, err)
}
_, err := m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{Status: status})
for _, recvID := range recvIDs {
sendMsgReq.MsgData.RecvID = recvID
rpcResp, err := m.Client.SendMsg(c, sendMsgReq)
if err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
resp.FailedIDs = append(resp.FailedIDs, recvID)
continue
}
resp.Results = append(resp.Results, &apistruct.SingleReturnResult{
ServerMsgID: rpcResp.ServerMsgID,
ClientMsgID: rpcResp.ClientMsgID,
SendTime: rpcResp.SendTime,
RecvID: recvID,
})
}
apiresp.GinSuccess(c, resp)
}

@ -29,6 +29,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine {
@ -40,8 +41,17 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
}
log.ZInfo(context.Background(), "load config", "config", config.Config)
r.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
u := NewUserApi(discov)
m := NewMessageApi(discov)
// init rpc client here
userRpc := rpcclient.NewUser(discov)
groupRpc := rpcclient.NewGroup(discov)
friendRpc := rpcclient.NewFriend(discov)
messageRpc := rpcclient.NewMessage(discov)
conversationRpc := rpcclient.NewConversation(discov)
authRpc := rpcclient.NewAuth(discov)
thirdRpc := rpcclient.NewThird(discov)
u := NewUserApi(*userRpc)
m := NewMessageApi(messageRpc, userRpc)
if config.Config.Prometheus.Enable {
prome.NewApiRequestCounter()
prome.NewApiRequestFailedCounter()
@ -62,10 +72,10 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
userRouterGroup.POST("/get_users_online_status", ParseToken, u.GetUsersOnlineStatus)
userRouterGroup.POST("/get_users_online_token_detail", ParseToken, u.GetUsersOnlineTokenDetail)
}
//friend routing group
// friend routing group
friendRouterGroup := r.Group("/friend", ParseToken)
{
f := NewFriendApi(discov)
f := NewFriendApi(*friendRpc)
friendRouterGroup.POST("/delete_friend", f.DeleteFriend)
friendRouterGroup.POST("/get_friend_apply_list", f.GetFriendApplyList)
friendRouterGroup.POST("/get_self_friend_apply_list", f.GetSelfApplyList)
@ -79,7 +89,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
friendRouterGroup.POST("/import_friend", f.ImportFriends)
friendRouterGroup.POST("/is_friend", f.IsFriend)
}
g := NewGroupApi(discov)
g := NewGroupApi(*groupRpc)
groupRouterGroup := r.Group("/group", ParseToken)
{
groupRouterGroup.POST("/create_group", g.CreateGroup)
@ -110,18 +120,18 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
superGroupRouterGroup.POST("/get_joined_group_list", g.GetJoinedSuperGroupList)
superGroupRouterGroup.POST("/get_groups_info", g.GetSuperGroupsInfo)
}
//certificate
// certificate
authRouterGroup := r.Group("/auth")
{
a := NewAuthApi(discov)
a := NewAuthApi(*authRpc)
authRouterGroup.POST("/user_token", a.UserToken)
authRouterGroup.POST("/parse_token", a.ParseToken)
authRouterGroup.POST("/force_logout", ParseToken, a.ForceLogout)
}
//Third service
// Third service
thirdGroup := r.Group("/third", ParseToken)
{
t := NewThirdApi(discov)
t := NewThirdApi(*thirdRpc)
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
thirdGroup.POST("/set_app_badge", t.SetAppBadge)
@ -135,7 +145,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
objectGroup.POST("/access_url", t.AccessURL)
objectGroup.GET("/*name", t.ObjectRedirect)
}
//Message
// Message
msgGroup := r.Group("/msg", ParseToken)
{
msgGroup.POST("/newest_seq", m.GetSeq)
@ -154,13 +164,13 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
msgGroup.POST("/delete_msg_phsical_by_seq", m.DeleteMsgPhysicalBySeq)
msgGroup.POST("/delete_msg_physical", m.DeleteMsgPhysical)
msgGroup.POST("/batch_send_msg", m.ManagementBatchSendMsg)
msgGroup.POST("/batch_send_msg", m.BatchSendMsg)
msgGroup.POST("/check_msg_is_send_success", m.CheckMsgIsSendSuccess)
}
//Conversation
// Conversation
conversationGroup := r.Group("/conversation", ParseToken)
{
c := NewConversationApi(discov)
c := NewConversationApi(*conversationRpc)
conversationGroup.POST("/get_all_conversations", c.GetAllConversations)
conversationGroup.POST("/get_conversation", c.GetConversation)
conversationGroup.POST("/get_conversations", c.GetConversations)

@ -18,15 +18,14 @@ import (
"github.com/gin-gonic/gin"
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
type StatisticsApi rpcclient.User
func NewStatisticsApi(discov discoveryregistry.SvcDiscoveryRegistry) StatisticsApi {
return StatisticsApi(*rpcclient.NewUser(discov))
func NewStatisticsApi(client rpcclient.User) StatisticsApi {
return StatisticsApi(client)
}
func (s *StatisticsApi) UserRegister(c *gin.Context) {

@ -23,7 +23,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/a2r"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
@ -31,8 +30,8 @@ import (
type ThirdApi rpcclient.Third
func NewThirdApi(discov discoveryregistry.SvcDiscoveryRegistry) ThirdApi {
return ThirdApi(*rpcclient.NewThird(discov))
func NewThirdApi(client rpcclient.Third) ThirdApi {
return ThirdApi(client)
}
func (o *ThirdApi) FcmUpdateToken(c *gin.Context) {

@ -22,7 +22,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msggateway"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
@ -31,8 +30,8 @@ import (
type UserApi rpcclient.User
func NewUserApi(discov discoveryregistry.SvcDiscoveryRegistry) UserApi {
return UserApi(*rpcclient.NewUser(discov))
func NewUserApi(client rpcclient.User) UserApi {
return UserApi(client)
}
func (u *UserApi) UserRegister(c *gin.Context) {
@ -79,7 +78,7 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) {
var respResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult
flag := false
//Online push message
// Online push message
for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.GetUsersOnlineStatus(c, &req)
@ -132,7 +131,7 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
apiresp.GinError(c, err)
return
}
//Online push message
// Online push message
for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.GetUsersOnlineStatus(c, &req)
@ -161,7 +160,6 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
}
}
}
}
for p, tokens := range m {
t := new(msggateway.SinglePlatformToken)
@ -177,5 +175,4 @@ func (u *UserApi) GetUsersOnlineTokenDetail(c *gin.Context) {
}
apiresp.GinSuccess(c, respResult)
}

@ -31,10 +31,12 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
)
var ErrConnClosed = errors.New("conn has closed")
var ErrNotSupportMessageProtocol = errors.New("not support message protocol")
var ErrClientClosed = errors.New("client actively close the connection")
var ErrPanic = errors.New("panic error")
var (
ErrConnClosed = errors.New("conn has closed")
ErrNotSupportMessageProtocol = errors.New("not support message protocol")
ErrClientClosed = errors.New("client actively close the connection")
ErrPanic = errors.New("panic error")
)
const (
// MessageText is for UTF-8 encoded text messages like JSON.
@ -102,10 +104,12 @@ func (c *Client) ResetClient(
c.closedErr = nil
c.token = token
}
func (c *Client) pongHandler(_ string) error {
c.conn.SetReadDeadline(pongWait)
return nil
}
func (c *Client) readMessage() {
defer func() {
if r := recover(); r != nil {
@ -124,7 +128,7 @@ func (c *Client) readMessage() {
return
}
log.ZDebug(c.ctx, "readMessage", "messageType", messageType)
if c.closed == true { //连接刚置位已经关闭,但是协程还没退出的场景
if c.closed == true { // 连接刚置位已经关闭,但是协程还没退出的场景
c.closedErr = ErrConnClosed
return
}
@ -148,8 +152,8 @@ func (c *Client) readMessage() {
default:
}
}
}
func (c *Client) handleMessage(message []byte) error {
if c.IsCompress {
var decompressErr error
@ -198,26 +202,26 @@ func (c *Client) handleMessage(message []byte) error {
}
c.replyMessage(ctx, &binaryReq, messageErr, resp)
return nil
}
func (c *Client) setAppBackgroundStatus(ctx context.Context, req Req) ([]byte, error) {
resp, isBackground, messageErr := c.longConnServer.SetUserDeviceBackground(ctx, req)
if messageErr != nil {
return nil, messageErr
}
c.IsBackground = isBackground
//todo callback
// todo callback
return resp, nil
}
func (c *Client) close() {
c.w.Lock()
defer c.w.Unlock()
c.closed = true
c.conn.Close()
c.longConnServer.UnRegister(c)
}
func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, resp []byte) {
errResp := apiresp.ParseError(err)
mReply := Resp{
@ -234,6 +238,7 @@ func (c *Client) replyMessage(ctx context.Context, binaryReq *Req, err error, re
log.ZWarn(ctx, "wireBinaryMsg replyMessage", err, "resp", mReply.String())
}
}
func (c *Client) PushMessage(ctx context.Context, msgData *sdkws.MsgData) error {
var msg sdkws.PushMessages
conversationID := utils.GetConversationIDByMsg(msgData)
@ -296,5 +301,4 @@ func (c *Client) writePongMsg() error {
}
_ = c.conn.SetWriteDeadline(writeWait)
return c.conn.WriteMessage(PongMessage, nil)
}

@ -33,6 +33,7 @@ type GzipCompressor struct {
func NewGzipCompressor() *GzipCompressor {
return &GzipCompressor{compressProtocol: "gzip"}
}
func (g *GzipCompressor) Compress(rawData []byte) ([]byte, error) {
gzipBuffer := bytes.Buffer{}
gz := gzip.NewWriter(&gzipBuffer)

@ -27,11 +27,13 @@ const (
GzipCompressionProtocol = "gzip"
BackgroundStatus = "isBackground"
)
const (
WebSocket = iota + 1
)
const (
//Websocket Protocol
// Websocket Protocol.
WSGetNewestSeq = 1001
WSPullMsgBySeqList = 1002
WSSendMsg = 1003

@ -71,9 +71,11 @@ func newContext(respWriter http.ResponseWriter, req *http.Request) *UserConnCont
ConnID: utils.Md5(req.RemoteAddr + "_" + strconv.Itoa(int(utils.GetCurrentTimestampByMill()))),
}
}
func (c *UserConnContext) GetRemoteAddr() string {
return c.RemoteAddr
}
func (c *UserConnContext) Query(key string) (string, bool) {
var value string
if value = c.Req.URL.Query().Get(key); value == "" {
@ -81,6 +83,7 @@ func (c *UserConnContext) Query(key string) (string, bool) {
}
return value, true
}
func (c *UserConnContext) GetHeader(key string) (string, bool) {
var value string
if value = c.Req.Header.Get(key); value == "" {
@ -88,27 +91,35 @@ func (c *UserConnContext) GetHeader(key string) (string, bool) {
}
return value, true
}
func (c *UserConnContext) SetHeader(key, value string) {
c.RespWriter.Header().Set(key, value)
}
func (c *UserConnContext) ErrReturn(error string, code int) {
http.Error(c.RespWriter, error, code)
}
func (c *UserConnContext) GetConnID() string {
return c.ConnID
}
func (c *UserConnContext) GetUserID() string {
return c.Req.URL.Query().Get(WsUserID)
}
func (c *UserConnContext) GetPlatformID() string {
return c.Req.URL.Query().Get(PlatformID)
}
func (c *UserConnContext) GetOperationID() string {
return c.Req.URL.Query().Get(OperationID)
}
func (c *UserConnContext) GetToken() string {
return c.Req.URL.Query().Get(Token)
}
func (c *UserConnContext) GetBackground() bool {
b, err := strconv.ParseBool(c.Req.URL.Query().Get(BackgroundStatus))
if err != nil {

@ -26,12 +26,12 @@ type Encoder interface {
Decode(encodeData []byte, decodeData interface{}) error
}
type GobEncoder struct {
}
type GobEncoder struct{}
func NewGobEncoder() *GobEncoder {
return &GobEncoder{}
}
func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
buff := bytes.Buffer{}
enc := gob.NewEncoder(&buff)
@ -41,6 +41,7 @@ func (g *GobEncoder) Encode(data interface{}) ([]byte, error) {
}
return buff.Bytes(), nil
}
func (g *GobEncoder) Decode(encodeData []byte, decodeData interface{}) error {
buff := bytes.NewBuffer(encodeData)
dec := gob.NewDecoder(buff)

@ -197,6 +197,6 @@ func (s *Server) MultiTerminalLoginCheck(
ctx context.Context,
req *msggateway.MultiTerminalLoginCheckReq,
) (*msggateway.MultiTerminalLoginCheckResp, error) {
//TODO implement me
// TODO implement me
panic("implement me")
}

@ -22,14 +22,14 @@ import (
)
type LongConn interface {
//Close this connection
// Close this connection
Close() error
// WriteMessage Write message to connection,messageType means data type,can be set binary(2) and text(1).
WriteMessage(messageType int, message []byte) error
// ReadMessage Read message from connection.
ReadMessage() (int, []byte, error)
// SetReadDeadline sets the read deadline on the underlying network connection,
//after a read has timed out, will return an error.
// after a read has timed out, will return an error.
SetReadDeadline(timeout time.Duration) error
// SetWriteDeadline sets to write deadline when send message,when read has timed out,will return error.
SetWriteDeadline(timeout time.Duration) error
@ -58,6 +58,7 @@ func newGWebSocket(protocolType int, handshakeTimeout time.Duration) *GWebSocket
func (d *GWebSocket) Close() error {
return d.conn.Close()
}
func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) error {
upgrader := &websocket.Upgrader{
HandshakeTimeout: d.handshakeTimeout,
@ -69,10 +70,10 @@ func (d *GWebSocket) GenerateLongConn(w http.ResponseWriter, r *http.Request) er
}
d.conn = conn
return nil
}
func (d *GWebSocket) WriteMessage(messageType int, message []byte) error {
//d.setSendConn(d.conn)
// d.setSendConn(d.conn)
return d.conn.WriteMessage(messageType, message)
}
@ -83,6 +84,7 @@ func (d *GWebSocket) WriteMessage(messageType int, message []byte) error {
func (d *GWebSocket) ReadMessage() (int, []byte, error) {
return d.conn.ReadMessage()
}
func (d *GWebSocket) SetReadDeadline(timeout time.Duration) error {
return d.conn.SetReadDeadline(time.Now().Add(timeout))
}
@ -97,7 +99,6 @@ func (d *GWebSocket) Dial(urlStr string, requestHeader http.Header) (*http.Respo
d.conn = conn
}
return httpResp, err
}
func (d *GWebSocket) IsNil() bool {
@ -110,9 +111,11 @@ func (d *GWebSocket) IsNil() bool {
func (d *GWebSocket) SetConnNil() {
d.conn = nil
}
func (d *GWebSocket) SetReadLimit(limit int64) {
d.conn.SetReadLimit(limit)
}
func (d *GWebSocket) SetPongHandler(handler PongHandler) {
d.conn.SetPongHandler(handler)
}

@ -75,8 +75,10 @@ type GrpcHandler struct {
func NewGrpcHandler(validate *validator.Validate, client discoveryregistry.SvcDiscoveryRegistry) *GrpcHandler {
msgRpcClient := rpcclient.NewMessageRpcClient(client)
pushRpcClient := rpcclient.NewPushRpcClient(client)
return &GrpcHandler{msgRpcClient: &msgRpcClient,
pushClient: &pushRpcClient, validate: validate}
return &GrpcHandler{
msgRpcClient: &msgRpcClient,
pushClient: &pushRpcClient, validate: validate,
}
}
func (g GrpcHandler) GetSeq(context context.Context, data Req) ([]byte, error) {
@ -164,6 +166,7 @@ func (g GrpcHandler) UserLogout(context context.Context, data Req) ([]byte, erro
}
return c, nil
}
func (g GrpcHandler) SetUserDeviceBackground(_ context.Context, data Req) ([]byte, bool, error) {
req := sdkws.SetAppBackgroundStatusReq{}
if err := proto.Unmarshal(data.Data, &req); err != nil {

@ -86,6 +86,7 @@ type kickHandler struct {
func (ws *WsServer) SetDiscoveryRegistry(client discoveryregistry.SvcDiscoveryRegistry) {
ws.MessageHandler = NewGrpcHandler(ws.validate, client)
}
func (ws *WsServer) SetCacheHandler(cache cache.MsgModel) {
ws.cache = cache
}
@ -113,7 +114,6 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
}
if config.port < 1024 {
return nil, errors.New("port not allow to listen")
}
v := validator.New()
return &WsServer{
@ -134,6 +134,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
Encoder: NewGobEncoder(),
}, nil
}
func (ws *WsServer) Run() error {
var client *Client
go func() {
@ -150,7 +151,7 @@ func (ws *WsServer) Run() error {
}()
http.HandleFunc("/", ws.wsHandler)
// http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {})
return http.ListenAndServe(":"+utils.IntToString(ws.port), nil) //Start listening
return http.ListenAndServe(":"+utils.IntToString(ws.port), nil) // Start listening
}
func (ws *WsServer) registerClient(client *Client) {
@ -165,7 +166,6 @@ func (ws *WsServer) registerClient(client *Client) {
log.ZDebug(client.ctx, "user not exist", "userID", client.UserID, "platformID", client.PlatformID)
atomic.AddInt64(&ws.onlineUserNum, 1)
atomic.AddInt64(&ws.onlineUserConnNum, 1)
} else {
i := &kickHandler{
clientOK: clientOK,
@ -176,7 +176,7 @@ func (ws *WsServer) registerClient(client *Client) {
log.ZDebug(client.ctx, "user exist", "userID", client.UserID, "platformID", client.PlatformID)
if clientOK {
ws.clients.Set(client.UserID, client)
//已经有同平台的连接存在
// 已经有同平台的连接存在
log.ZInfo(client.ctx, "repeat login", "userID", client.UserID, "platformID", client.PlatformID, "old remote addr", getRemoteAdders(oldClients))
atomic.AddInt64(&ws.onlineUserConnNum, 1)
} else {
@ -194,6 +194,7 @@ func (ws *WsServer) registerClient(client *Client) {
ws.onlineUserConnNum,
)
}
func getRemoteAdders(client []*Client) string {
var ret string
for i, c := range client {
@ -284,8 +285,8 @@ func (ws *WsServer) multiTerminalLoginChecker(info *kickHandler) {
}
}
}
}
func (ws *WsServer) unregisterClient(client *Client) {
defer ws.clientPool.Put(client)
isDeleteUser := ws.clients.delete(client.UserID, client.ctx.GetRemoteAddr())

@ -16,33 +16,38 @@ package msggateway
import "time"
type Option func(opt *configs)
type configs struct {
//长连接监听端口
type (
Option func(opt *configs)
configs struct {
// 长连接监听端口
port int
//长连接允许最大链接数
// 长连接允许最大链接数
maxConnNum int64
//连接握手超时时间
// 连接握手超时时间
handshakeTimeout time.Duration
//允许消息最大长度
// 允许消息最大长度
messageMaxMsgLength int
}
}
)
func WithPort(port int) Option {
return func(opt *configs) {
opt.port = port
}
}
func WithMaxConnNum(num int64) Option {
return func(opt *configs) {
opt.maxConnNum = num
}
}
func WithHandshakeTimeout(t time.Duration) Option {
return func(opt *configs) {
opt.handshakeTimeout = t
}
}
func WithMessageMaxMsgLength(length int) Option {
return func(opt *configs) {
opt.messageMaxMsgLength = length

@ -29,6 +29,7 @@ type UserMap struct {
func newUserMap() *UserMap {
return &UserMap{}
}
func (u *UserMap) GetAll(key string) ([]*Client, bool) {
allClients, ok := u.m.Load(key)
if ok {
@ -36,6 +37,7 @@ func (u *UserMap) GetAll(key string) ([]*Client, bool) {
}
return nil, ok
}
func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
allClients, userExisted := u.m.Load(key)
if userExisted {
@ -47,12 +49,12 @@ func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
}
if len(clients) > 0 {
return clients, userExisted, true
}
return clients, userExisted, false
}
return nil, userExisted, false
}
func (u *UserMap) Set(key string, v *Client) {
allClients, existed := u.m.Load(key)
if existed {
@ -67,6 +69,7 @@ func (u *UserMap) Set(key string, v *Client) {
u.m.Store(key, clients)
}
}
func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) {
allClients, existed := u.m.Load(key)
if existed {
@ -87,6 +90,7 @@ func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool)
}
return existed
}
func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser bool) {
m := utils.SliceToMapAny(clients, func(c *Client) (string, struct{}) {
return c.ctx.GetRemoteAddr(), struct{}{}
@ -110,6 +114,7 @@ func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser boo
}
return existed
}
func (u *UserMap) DeleteAll(key string) {
u.m.Delete(key)
}

@ -19,6 +19,9 @@ import (
"sync"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@ -30,8 +33,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
openKeeper "github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry/zookeeper"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
type MsgTransfer struct {
@ -84,9 +85,12 @@ func StartTransfer(prometheusPort int) error {
func NewMsgTransfer(chatLogDatabase controller.ChatLogDatabase,
msgDatabase controller.CommonMsgDatabase,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient) *MsgTransfer {
return &MsgTransfer{persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase)}
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient,
) *MsgTransfer {
return &MsgTransfer{
persistentCH: NewPersistentConsumerHandler(chatLogDatabase), historyCH: NewOnlineHistoryRedisConsumerHandler(msgDatabase, conversationRpcClient, groupRpcClient),
historyMongoCH: NewOnlineHistoryMongoConsumerHandler(msgDatabase),
}
}
func (m *MsgTransfer) initPrometheus() {

@ -38,10 +38,12 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
)
const ConsumerMsgs = 3
const SourceMessages = 4
const MongoMessages = 5
const ChannelNum = 100
const (
ConsumerMsgs = 3
SourceMessages = 4
MongoMessages = 5
ChannelNum = 100
)
type MsgChannelValue struct {
uniqueKey string
@ -85,7 +87,7 @@ func NewOnlineHistoryRedisConsumerHandler(
) *OnlineHistoryRedisConsumerHandler {
var och OnlineHistoryRedisConsumerHandler
och.msgDatabase = database
och.msgDistributionCh = make(chan Cmd2Value) //no buffer channel
och.msgDistributionCh = make(chan Cmd2Value) // no buffer channel
go och.MessagesDistributionHandle()
for i := 0; i < ChannelNum; i++ {
och.chArrays[i] = make(chan Cmd2Value, 50)
@ -93,8 +95,10 @@ func NewOnlineHistoryRedisConsumerHandler(
}
och.conversationRpcClient = conversationRpcClient
och.groupRpcClient = groupRpcClient
och.historyConsumerGroup = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
och.historyConsumerGroup = kafka.NewMConsumerGroup(&kafka.MConsumerGroupConfig{
KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToRedis)
// statistics.NewStatistics(&och.singleMsgSuccessCount, config.Config.ModuleName.MsgTransferName, fmt.Sprintf("%d
// second singleMsgCount insert to mongo", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
@ -163,7 +167,7 @@ func (och *OnlineHistoryRedisConsumerHandler) Run(channelID int) {
}
}
// 获取消息/通知 存储的消息列表, 不存储并且推送的消息列表,
// 获取消息/通知 存储的消息列表, 不存储并且推送的消息列表,.
func (och *OnlineHistoryRedisConsumerHandler) getPushStorageMsgList(
totalMsgs []*ContextMsg,
) (storageMsgList, notStorageMsgList, storageNotificatoinList, notStorageNotificationList, modifyMsgList []*sdkws.MsgData) {
@ -312,7 +316,7 @@ func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
triggerChannelValue := cmd.Value.(TriggerChannelValue)
ctx := triggerChannelValue.ctx
consumerMessages := triggerChannelValue.cMsgList
//Aggregation map[userid]message list
// Aggregation map[userid]message list
log.ZDebug(ctx, "batch messages come to distribution center", "length", len(consumerMessages))
for i := 0; i < len(consumerMessages); i++ {
ctxMsg := &ContextMsg{}
@ -378,13 +382,13 @@ func (och *OnlineHistoryRedisConsumerHandler) MessagesDistributionHandle() {
}
}
}
func withAggregationCtx(ctx context.Context, values []*ContextMsg) context.Context {
var allMessageOperationID string
for i, v := range values {
if opid := mcontext.GetOperationID(v.ctx); opid != "" {
if i == 0 {
allMessageOperationID += opid
} else {
allMessageOperationID += "$" + opid
}
@ -431,13 +435,15 @@ func (och *OnlineHistoryRedisConsumerHandler) ConsumeClaim(
ctx := mcontext.WithTriggerIDContext(context.Background(), utils.OperationIDGenerator())
log.ZDebug(ctx, "timer trigger msg consumer start", "length", len(ccMsg))
for i := 0; i < len(ccMsg)/split; i++ {
//log.Debug()
// log.Debug()
och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{
ctx: ctx, cMsgList: ccMsg[i*split : (i+1)*split]}}
ctx: ctx, cMsgList: ccMsg[i*split : (i+1)*split],
}}
}
if (len(ccMsg) % split) > 0 {
och.msgDistributionCh <- Cmd2Value{Cmd: ConsumerMsgs, Value: TriggerChannelValue{
ctx: ctx, cMsgList: ccMsg[split*(len(ccMsg)/split):]}}
ctx: ctx, cMsgList: ccMsg[split*(len(ccMsg)/split):],
}}
}
log.ZDebug(ctx, "timer trigger msg consumer end", "length", len(ccMsg))
}

@ -34,8 +34,10 @@ type OnlineHistoryMongoConsumerHandler struct {
func NewOnlineHistoryMongoConsumerHandler(database controller.CommonMsgDatabase) *OnlineHistoryMongoConsumerHandler {
mc := &OnlineHistoryMongoConsumerHandler{
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToMongo.Topic},
historyConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.MsgToMongo.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMongo),
msgDatabase: database,
}

@ -36,8 +36,10 @@ type PersistentConsumerHandler struct {
func NewPersistentConsumerHandler(database controller.ChatLogDatabase) *PersistentConsumerHandler {
return &PersistentConsumerHandler{
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
persistentConsumerGroup: kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.LatestMsgToRedis.Topic},
config.Config.Kafka.Addr, config.Config.Kafka.ConsumerGroupID.MsgToMySql),
chatLogDatabase: database,
}
@ -59,9 +61,9 @@ func (pc *PersistentConsumerHandler) handleChatWs2Mysql(
}
return
log.ZDebug(ctx, "handleChatWs2Mysql", "msg", msgFromMQ.MsgData)
//Control whether to store history messages (mysql)
// Control whether to store history messages (mysql)
isPersist := utils.GetSwitchFromOptions(msgFromMQ.MsgData.Options, constant.IsPersistent)
//Only process receiver data
// Only process receiver data
if isPersist {
switch msgFromMQ.MsgData.SessionType {
case constant.SingleChatType, constant.NotificationChatType:

@ -95,7 +95,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
if err == nil {
apns.Payload.Aps.Badge = &unreadCountSum
} else {
//log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
// log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
Fail++
continue
}
@ -107,7 +107,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
zero := 1
apns.Payload.Aps.Badge = &zero
} else {
//log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
// log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
Fail++
continue
}
@ -127,7 +127,7 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
response, err := f.fcmMsgCli.SendAll(ctx, messages)
if err != nil {
Fail = Fail + messageCount
//log.Info(operationID, "some token push err", err.Error(), messageCount)
// log.Info(operationID, "some token push err", err.Error(), messageCount)
} else {
Success = Success + response.SuccessCount
Fail = Fail + response.FailureCount

@ -145,7 +145,7 @@ func newPushReq(title, content string) PushReq {
}
func newBatchPushReq(userIDs []string, taskID string) PushReq {
var IsAsync = true
IsAsync := true
return PushReq{Audience: &Audience{Alias: userIDs}, IsAsync: &IsAsync, TaskID: &taskID}
}

@ -15,17 +15,16 @@
package getui
import (
"sync"
"github.com/go-redis/redis"
"context"
"crypto/sha256"
"encoding/hex"
"errors"
"strconv"
"sync"
"time"
"github.com/go-redis/redis"
"github.com/OpenIMSDK/Open-IM-Server/internal/push/offlinepush"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@ -49,7 +48,7 @@ const (
taskURL = "/push/list/message"
batchPushURL = "/push/list/alias"
// codes
// codes.
tokenExpireCode = 10001
tokenExpireTime = 60 * 60 * 23
taskIDTTL = 1000 * 60 * 60 * 24
@ -142,7 +141,7 @@ func (g *Client) GetTaskID(ctx context.Context, token string, pushReq PushReq) (
return respTask.TaskID, nil
}
// max num is 999
// max num is 999.
func (g *Client) batchPush(ctx context.Context, token string, userIDs []string, pushReq PushReq) error {
taskID, err := g.GetTaskID(ctx, token, pushReq)
if err != nil {

@ -66,6 +66,7 @@ func (p *Platform) Set(os string) error {
return nil
}
func (p *Platform) SetPlatform(platform string) error {
switch platform {
case constant.AndroidPlatformStr:
@ -75,8 +76,8 @@ func (p *Platform) SetPlatform(platform string) error {
default:
return errors.New("platform err")
}
}
func (p *Platform) SetIOS() error {
return p.Set(IOS)
}

@ -37,6 +37,7 @@ func (p *PushObj) SetNotification(no *Notification) {
func (p *PushObj) SetMessage(m *Message) {
p.Message = m
}
func (p *PushObj) SetOptions(o *Options) {
p.Options = o
}

@ -37,8 +37,10 @@ type ConsumerHandler struct {
func NewConsumerHandler(pusher *Pusher) *ConsumerHandler {
var consumerHandler ConsumerHandler
consumerHandler.pusher = pusher
consumerHandler.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
consumerHandler.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{
KafkaVersion: sarama.V2_0_0_0,
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false,
}, []string{config.Config.Kafka.MsgToPush.Topic}, config.Config.Kafka.Addr,
config.Config.Kafka.ConsumerGroupID.MsgToPush)
return &consumerHandler
}
@ -76,7 +78,8 @@ func (c *ConsumerHandler) handleMs2PsChat(ctx context.Context, msg []byte) {
func (ConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
func (ConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
claim sarama.ConsumerGroupClaim) error {
claim sarama.ConsumerGroupClaim,
) error {
for msg := range claim.Messages() {
ctx := c.pushConsumerGroup.GetContextFromMsg(msg)
c.handleMs2PsChat(ctx, msg.Value)

@ -54,7 +54,8 @@ var errNoOfflinePusher = errors.New("no offlinePusher is configured")
func NewPusher(discov discoveryregistry.SvcDiscoveryRegistry, offlinePusher offlinepush.OfflinePusher, database controller.PushDatabase,
groupLocalCache *localcache.GroupLocalCache, conversationLocalCache *localcache.ConversationLocalCache,
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient) *Pusher {
conversationRpcClient *rpcclient.ConversationRpcClient, groupRpcClient *rpcclient.GroupRpcClient, msgRpcClient *rpcclient.MessageRpcClient,
) *Pusher {
return &Pusher{
discov: discov,
database: database,
@ -223,7 +224,7 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws
}
needOfflinePushUserIDs = utils.DifferenceString(notNotificationUserIDs, needOfflinePushUserIDs)
}
//Use offline push messaging
// Use offline push messaging
if len(needOfflinePushUserIDs) > 0 {
var offlinePushUserIDs []string
err = callbackOfflinePush(ctx, needOfflinePushUserIDs, msg, &offlinePushUserIDs)
@ -254,7 +255,7 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
if err != nil {
return nil, err
}
//Online push message
// Online push message
for _, v := range conns {
msgClient := msggateway.NewMsgGatewayClient(v)
reply, err := msgClient.SuperGroupOnlineBatchPushOneMsg(ctx, &msggateway.OnlineBatchPushOneMsgReq{MsgData: msg, PushToUserIDs: pushToUserIDs})
@ -265,7 +266,6 @@ func (p *Pusher) GetConnsAndOnlinePush(ctx context.Context, msg *sdkws.MsgData,
if reply != nil && reply.SinglePushResult != nil {
wsResults = append(wsResults, reply.SinglePushResult...)
}
}
return wsResults, nil
}

@ -17,6 +17,8 @@ package conversation
import (
"context"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@ -31,7 +33,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
)
type conversationServer struct {
@ -184,7 +185,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbConver
return &pbConversation.SetConversationsResp{}, nil
}
// 获取超级大群开启免打扰的用户ID
// 获取超级大群开启免打扰的用户ID.
func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbConversation.GetRecvMsgNotNotifyUserIDsReq) (*pbConversation.GetRecvMsgNotNotifyUserIDsResp, error) {
userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID)
if err != nil {
@ -193,7 +194,7 @@ func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req
return &pbConversation.GetRecvMsgNotNotifyUserIDsResp{UserIDs: userIDs}, nil
}
// create conversation without notification for msg redis transfer
// create conversation without notification for msg redis transfer.
func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, req *pbConversation.CreateSingleChatConversationsReq) (*pbConversation.CreateSingleChatConversationsResp, error) {
var conversation tableRelation.ConversationModel
conversation.ConversationID = utils.GetConversationIDBySessionType(constant.SingleChatType, req.RecvID, req.SendID)
@ -247,7 +248,10 @@ func (c *conversationServer) GetUserConversationIDsHash(ctx context.Context, req
return &pbConversation.GetUserConversationIDsHashResp{Hash: hash}, nil
}
func (c *conversationServer) GetConversationsByConversationID(ctx context.Context, req *pbConversation.GetConversationsByConversationIDReq) (*pbConversation.GetConversationsByConversationIDResp, error) {
func (c *conversationServer) GetConversationsByConversationID(
ctx context.Context,
req *pbConversation.GetConversationsByConversationIDReq,
) (*pbConversation.GetConversationsByConversationIDResp, error) {
conversations, err := c.conversationDatabase.GetConversationsByConversationID(ctx, req.ConversationIDs)
if err != nil {
return nil, err

@ -83,7 +83,7 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error {
return nil
}
// ok
// ok.
func (s *friendServer) ApplyToAddFriend(
ctx context.Context,
req *pbfriend.ApplyToAddFriendReq,
@ -116,7 +116,7 @@ func (s *friendServer) ApplyToAddFriend(
return resp, nil
}
// ok
// ok.
func (s *friendServer) ImportFriends(
ctx context.Context,
req *pbfriend.ImportFriendReq,
@ -142,7 +142,7 @@ func (s *friendServer) ImportFriends(
return &pbfriend.ImportFriendResp{}, nil
}
// ok
// ok.
func (s *friendServer) RespondFriendApply(
ctx context.Context,
req *pbfriend.RespondFriendApplyReq,
@ -178,7 +178,7 @@ func (s *friendServer) RespondFriendApply(
return nil, errs.ErrArgs.Wrap("req.HandleResult != -1/1")
}
// ok
// ok.
func (s *friendServer) DeleteFriend(
ctx context.Context,
req *pbfriend.DeleteFriendReq,
@ -199,7 +199,7 @@ func (s *friendServer) DeleteFriend(
return resp, nil
}
// ok
// ok.
func (s *friendServer) SetFriendRemark(
ctx context.Context,
req *pbfriend.SetFriendRemarkReq,
@ -220,7 +220,7 @@ func (s *friendServer) SetFriendRemark(
return resp, nil
}
// ok
// ok.
func (s *friendServer) GetDesignatedFriends(
ctx context.Context,
req *pbfriend.GetDesignatedFriendsReq,
@ -240,7 +240,7 @@ func (s *friendServer) GetDesignatedFriends(
return resp, nil
}
// ok 获取接收到的好友申请(即别人主动申请的)
// ok 获取接收到的好友申请(即别人主动申请的).
func (s *friendServer) GetPaginationFriendsApplyTo(
ctx context.Context,
req *pbfriend.GetPaginationFriendsApplyToReq,
@ -263,7 +263,7 @@ func (s *friendServer) GetPaginationFriendsApplyTo(
return resp, nil
}
// ok 获取主动发出去的好友申请列表
// ok 获取主动发出去的好友申请列表.
func (s *friendServer) GetPaginationFriendsApplyFrom(
ctx context.Context,
req *pbfriend.GetPaginationFriendsApplyFromReq,
@ -286,7 +286,7 @@ func (s *friendServer) GetPaginationFriendsApplyFrom(
return resp, nil
}
// ok
// ok.
func (s *friendServer) IsFriend(
ctx context.Context,
req *pbfriend.IsFriendReq,
@ -300,7 +300,7 @@ func (s *friendServer) IsFriend(
return resp, nil
}
// ok
// ok.
func (s *friendServer) GetPaginationFriends(
ctx context.Context,
req *pbfriend.GetPaginationFriendsReq,

@ -17,20 +17,23 @@ package group
import (
"context"
"fmt"
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
"math/big"
"math/rand"
"strconv"
"strings"
"time"
pbConversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mw/specialerror"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@ -45,7 +48,6 @@ import (
pbGroup "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
)
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {
@ -229,7 +231,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
}
}()
} else {
//s.Notification.GroupCreatedNotification(ctx, group, groupMembers, userMap)
// s.Notification.GroupCreatedNotification(ctx, group, groupMembers, userMap)
tips := &sdkws.GroupCreatedTips{
Group: resp.GroupInfo,
OperationTime: group.CreateTime.UnixMilli(),
@ -258,7 +260,7 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo
pageNumber = req.Pagination.PageNumber
showNumber = req.Pagination.ShowNumber
}
//total, members, err := s.GroupDatabase.PageGroupMember(ctx, nil, []string{req.FromUserID}, nil, pageNumber, showNumber)
// total, members, err := s.GroupDatabase.PageGroupMember(ctx, nil, []string{req.FromUserID}, nil, pageNumber, showNumber)
total, members, err := s.GroupDatabase.PageGetJoinGroup(ctx, req.FromUserID, pageNumber, showNumber)
if err != nil {
return nil, err
@ -515,7 +517,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbGroup.KickGrou
Notification: group.Notification,
Introduction: group.Introduction,
FaceURL: group.FaceURL,
//OwnerUserID: owner[0].UserID,
// OwnerUserID: owner[0].UserID,
CreateTime: group.CreateTime.UnixMilli(),
MemberCount: num,
Ex: group.Ex,
@ -900,7 +902,6 @@ func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbGroup.SetGroupInf
}()
num++
s.Notification.GroupInfoSetAnnouncementNotification(ctx, &sdkws.GroupInfoSetAnnouncementTips{Group: tips.Group, OpUser: tips.OpUser})
}
switch len(data) - num {
case 0:
@ -1104,7 +1105,7 @@ func (s *groupServer) DismissGroup(ctx context.Context, req *pbGroup.DismissGrou
if err != nil {
return nil, err
}
//s.Notification.GroupDismissedNotification(ctx, req)
// s.Notification.GroupDismissedNotification(ctx, req)
tips := &sdkws.GroupDismissedTips{
Group: s.groupDB2PB(group, owner.UserID, num),
OpUser: &sdkws.GroupMemberFullInfo{},

@ -16,9 +16,10 @@ package group
import (
"context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/group"
"time"
)
func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCreateCountReq) (*group.GroupCreateCountResp, error) {

@ -39,7 +39,7 @@ func (m *msgServer) GetConversationsHasReadAndMaxSeq(ctx context.Context, req *m
if err != nil {
return nil, err
}
var conversationMaxSeqMap = make(map[string]int64)
conversationMaxSeqMap := make(map[string]int64)
for _, conversation := range conversations {
if conversation.MaxSeq != 0 {
conversationMaxSeqMap[conversation.ConversationID] = conversation.MaxSeq

@ -36,6 +36,7 @@ type LockerMessage struct {
func NewLockerMessage(cache cache.MsgModel) *LockerMessage {
return &LockerMessage{cache: cache}
}
func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typeKey string) (err error) {
for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, typeKey)
@ -47,8 +48,8 @@ func (l *LockerMessage) LockMessageTypeKey(ctx context.Context, clientMsgID, typ
}
}
return err
}
func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID string) (err error) {
for i := 0; i < 3; i++ {
err = l.cache.LockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
@ -60,11 +61,12 @@ func (l *LockerMessage) LockGlobalMessage(ctx context.Context, clientMsgID strin
}
}
return err
}
func (l *LockerMessage) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, typeKey string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, typeKey)
}
func (l *LockerMessage) UnLockGlobalMessage(ctx context.Context, clientMsgID string) error {
return l.cache.UnLockMessageTypeKey(ctx, clientMsgID, GlOBALLOCK)
}

@ -83,6 +83,7 @@ func (m *msgServer) sendMsgSuperGroupChat(
resp.ClientMsgID = req.MsgData.ClientMsgID
return resp, nil
}
func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgData) {
log.ZDebug(nctx, "setConversationAtInfo", "msg", msg)
ctx := mcontext.NewCtx("@@@" + mcontext.GetOperationID(nctx))
@ -100,7 +101,7 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
return
}
atUserID = utils.DifferenceString([]string{constant.AtAllString}, msg.AtUserIDList)
if len(atUserID) == 0 { //just @everyone
if len(atUserID) == 0 { // just @everyone
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAll}
} else { //@Everyone and @other people
conversation.GroupAtType = &wrapperspb.Int32Value{Value: constant.AtAllAtMe}
@ -122,7 +123,6 @@ func (m *msgServer) setConversationAtInfo(nctx context.Context, msg *sdkws.MsgDa
log.ZWarn(ctx, "SetConversations", err, msg.AtUserIDList, conversation)
}
}
}
func (m *msgServer) sendMsgNotification(

@ -16,6 +16,10 @@ package msg
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
@ -30,8 +34,9 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
)
type MessageInterceptorChain []MessageInterceptorFunc
type msgServer struct {
type (
MessageInterceptorChain []MessageInterceptorFunc
msgServer struct {
RegisterCenter discoveryregistry.SvcDiscoveryRegistry
MsgDatabase controller.CommonMsgDatabase
Group *rpcclient.GroupRpcClient
@ -43,7 +48,8 @@ type msgServer struct {
MessageLocker MessageLocker
Handlers MessageInterceptorChain
notificationSender *rpcclient.NotificationSender
}
}
)
func (m *msgServer) addInterceptorHandler(interceptorFunc ...MessageInterceptorFunc) {
m.Handlers = append(m.Handlers, interceptorFunc...)

@ -16,15 +16,24 @@ package msg
import (
"context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"time"
)
func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq) (*msg.GetActiveUserResp, error) {
msgCount, userCount, users, dateCount, err := m.MsgDatabase.RangeUserSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Group, req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber)
msgCount, userCount, users, dateCount, err := m.MsgDatabase.RangeUserSendCount(
ctx,
time.UnixMilli(req.Start),
time.UnixMilli(req.End),
req.Group,
req.Ase,
req.Pagination.PageNumber,
req.Pagination.ShowNumber,
)
if err != nil {
return nil, err
}
@ -59,7 +68,14 @@ func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq
}
func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupReq) (*msg.GetActiveGroupResp, error) {
msgCount, groupCount, groups, dateCount, err := m.MsgDatabase.RangeGroupSendCount(ctx, time.UnixMilli(req.Start), time.UnixMilli(req.End), req.Ase, req.Pagination.PageNumber, req.Pagination.ShowNumber)
msgCount, groupCount, groups, dateCount, err := m.MsgDatabase.RangeGroupSendCount(
ctx,
time.UnixMilli(req.Start),
time.UnixMilli(req.End),
req.Ase,
req.Pagination.PageNumber,
req.Pagination.ShowNumber,
)
if err != nil {
return nil, err
}

@ -16,6 +16,7 @@ package msg
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"

@ -28,9 +28,7 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
)
var (
ExcludeContentType = []int{constant.HasReadReceipt}
)
var ExcludeContentType = []int{constant.HasReadReceipt}
type Validator interface {
validate(pb *msg.SendMsgReq) (bool, int32, string)
@ -126,6 +124,7 @@ func (m *msgServer) messageVerification(ctx context.Context, data *msg.SendMsgRe
return nil
}
}
func (m *msgServer) encapsulateMsgData(msg *sdkws.MsgData) {
msg.ServerMsgID = GetMsgID(msg.SendID)
msg.SendTime = utils.GetCurrentTimestampByMill()

@ -16,6 +16,8 @@ package third
import (
"context"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
@ -23,7 +25,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"time"
)
func (t *thirdServer) PartLimit(ctx context.Context, req *third.PartLimitReq) (*third.PartLimitResp, error) {

@ -17,12 +17,15 @@ package third
import (
"context"
"fmt"
"net/url"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss"
"net/url"
"time"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
@ -32,7 +35,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/discoveryregistry"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"google.golang.org/grpc"
)
func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) error {

@ -18,12 +18,13 @@ import (
"context"
"errors"
"fmt"
"strings"
"unicode/utf8"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/mcontext"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/third"
"strings"
"unicode/utf8"
)
func toPbMapArray(m map[string][]string) []*third.KeyValues {

@ -17,10 +17,11 @@ package user
import (
"context"
"errors"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"strings"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert"
@ -37,8 +38,9 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"google.golang.org/grpc"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
)
type userServer struct {
@ -233,7 +235,7 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge
}
func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) {
userIDs, err := s.UserDatabase.GetAllUserID(ctx)
userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber)
if err != nil {
return nil, err
}

@ -33,7 +33,18 @@ func (c *MsgTool) ConversationsDestructMsgs() {
}
log.ZDebug(context.Background(), "nums conversations need destruct", "nums", len(conversations))
for _, conversation := range conversations {
log.ZDebug(ctx, "UserMsgsDestruct", "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID, "msgDestructTime", conversation.MsgDestructTime, "lastMsgDestructTime", conversation.LatestMsgDestructTime)
log.ZDebug(
ctx,
"UserMsgsDestruct",
"conversationID",
conversation.ConversationID,
"ownerUserID",
conversation.OwnerUserID,
"msgDestructTime",
conversation.MsgDestructTime,
"lastMsgDestructTime",
conversation.LatestMsgDestructTime,
)
seqs, err := c.msgDatabase.UserMsgsDestruct(ctx, conversation.OwnerUserID, conversation.ConversationID, conversation.MsgDestructTime, conversation.LatestMsgDestructTime)
if err != nil {
log.ZError(ctx, "user msg destruct failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID)

@ -20,6 +20,10 @@ import (
"math"
"time"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller"
@ -34,9 +38,6 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient"
"github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/redis/go-redis/v9"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
type MsgTool struct {
@ -48,7 +49,8 @@ type MsgTool struct {
}
func NewMsgTool(msgDatabase controller.CommonMsgDatabase, userDatabase controller.UserDatabase,
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender) *MsgTool {
groupDatabase controller.GroupDatabase, conversationDatabase controller.ConversationDatabase, msgNotificationSender *notification.MsgNotificationSender,
) *MsgTool {
return &MsgTool{
msgDatabase: msgDatabase,
userDatabase: userDatabase,
@ -86,7 +88,11 @@ func InitMsgTool() (*MsgTool, error) {
tx.NewGorm(db),
)
groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase())
conversationDatabase := controller.NewConversationDatabase(relation.NewConversationGorm(db), cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)), tx.NewGorm(db))
conversationDatabase := controller.NewConversationDatabase(
relation.NewConversationGorm(db),
cache.NewConversationRedis(rdb, cache.GetDefaultOpt(), relation.NewConversationGorm(db)),
tx.NewGorm(db),
)
msgRpcClient := rpcclient.NewMessageRpcClient(discov)
msgNotificationSender := notification.NewMsgNotificationSender(rpcclient.WithRpcClient(&msgRpcClient))
msgTool := NewMsgTool(msgDatabase, userDatabase, groupDatabase, conversationDatabase, msgNotificationSender)

@ -1,68 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type UserRegisterReq struct {
Secret string `json:"secret" binding:"required,max=32"`
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
ApiUserInfo
OperationID string `json:"operationID" binding:"required"`
}
type UserTokenInfo struct {
UserID string `json:"userID"`
Token string `json:"token"`
ExpiredTime int64 `json:"expiredTime"`
}
type UserRegisterResp struct {
UserToken UserTokenInfo `json:"data"`
}
type UserTokenReq struct {
Secret string `json:"secret" binding:"required,max=32"`
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
UserID string `json:"userID" binding:"required,min=1,max=64"`
OperationID string `json:"operationID" binding:"required"`
}
type UserTokenResp struct {
UserToken UserTokenInfo `json:"data"`
}
type ForceLogoutReq struct {
Platform int32 `json:"platform" binding:"required,min=1,max=12"`
FromUserID string `json:"fromUserID" binding:"required,min=1,max=64"`
OperationID string `json:"operationID" binding:"required"`
}
type ForceLogoutResp struct{}
type ParseTokenReq struct {
OperationID string `json:"operationID" binding:"required"`
}
//type ParseTokenResp struct {
//
// ExpireTime int64 `json:"expireTime" binding:"required"`
//}
type ExpireTime struct {
ExpireTimeSeconds uint32 `json:"expireTimeSeconds"`
}
type ParseTokenResp struct {
Data map[string]interface{} `json:"data" swaggerignore:"true"`
ExpireTime ExpireTime `json:"-"`
}

@ -1,33 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type AwsStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type AwsStorageCredentialRespData struct {
AccessKeyId string `json:"accessKeyID"`
SecretAccessKey string `json:"secretAccessKey"`
SessionToken string `json:"sessionToken"`
RegionID string `json:"regionId"`
Bucket string `json:"bucket"`
FinalHost string `json:"FinalHost"`
}
type AwsStorageCredentialResp struct {
CosData AwsStorageCredentialRespData
Data map[string]interface{} `json:"data"`
}

@ -1,131 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type OptResult struct {
ConversationID string `json:"conversationID"`
Result *int32 `json:"result"`
}
type GetAllConversationMessageOptReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetAllConversationMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type GetReceiveMessageOptReq struct {
ConversationIDList []string `json:"conversationIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetReceiveMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type SetReceiveMessageOptReq struct {
FromUserID string `json:"fromUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
Opt *int32 `json:"opt" binding:"required"`
ConversationIDList []string `json:"conversationIDList" binding:"required"`
}
type SetReceiveMessageOptResp struct {
ConversationOptResultList []*OptResult `json:"data"`
}
type Conversation struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
ConversationID string `json:"conversationID" binding:"required"`
ConversationType int32 `json:"conversationType" binding:"required"`
UserID string `json:"userID"`
GroupID string `json:"groupID"`
RecvMsgOpt int32 `json:"recvMsgOpt" binding:"omitempty,oneof=0 1 2"`
UnreadCount int32 `json:"unreadCount" binding:"omitempty"`
DraftTextTime int64 `json:"draftTextTime"`
IsPinned bool `json:"isPinned" binding:"omitempty"`
IsPrivateChat bool `json:"isPrivateChat"`
BurnDuration int32 `json:"burnDuration"`
GroupAtType int32 `json:"groupAtType"`
IsNotInGroup bool `json:"isNotInGroup"`
UpdateUnreadCountTime int64 `json:"updateUnreadCountTime"`
AttachedInfo string `json:"attachedInfo"`
Ex string `json:"ex"`
}
type SetConversationReq struct {
Conversation
NotificationType int32 `json:"notificationType"`
OperationID string `json:"operationID" binding:"required"`
}
type SetConversationResp struct{}
type ModifyConversationFieldReq struct {
Conversation
FieldType int32 `json:"fieldType" binding:"required"`
UserIDList []string `json:"userIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type ModifyConversationFieldResp struct{}
type BatchSetConversationsReq struct {
Conversations []Conversation `json:"conversations" binding:"required"`
NotificationType int32 `json:"notificationType"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type BatchSetConversationsResp struct {
Data struct {
Success []string `json:"success"`
Failed []string `json:"failed"`
} `json:"data"`
}
type GetConversationReq struct {
ConversationID string `json:"conversationID" binding:"required"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetConversationResp struct {
Conversation Conversation `json:"data"`
}
type GetAllConversationsReq struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetAllConversationsResp struct {
Conversations []Conversation `json:"data"`
}
type GetConversationsReq struct {
ConversationIDs []string `json:"conversationIDs" binding:"required"`
OwnerUserID string `json:"ownerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetConversationsResp struct {
Conversations []Conversation `json:"data"`
}
type SetRecvMsgOptReq struct {
OwnerUserID string `json:"ownerUserID" binding:"required"`
ConversationID string `json:"conversationID"`
RecvMsgOpt int32 `json:"recvMsgOpt" binding:"omitempty,oneof=0 1 2"`
OperationID string `json:"operationID" binding:"required"`
NotificationType int32 `json:"notificationType"`
}
type SetRecvMsgOptResp struct{}

@ -1,33 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
import sts "github.com/tencentyun/qcloud-cos-sts-sdk/go"
type TencentCloudStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type TencentCloudStorageCredentialRespData struct {
*sts.CredentialResult
Region string `json:"region"`
Bucket string `json:"bucket"`
}
type TencentCloudStorageCredentialResp struct {
CosData TencentCloudStorageCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"`
}

@ -1,282 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
//type ParamsCommFriend struct {
// OperationID string `json:"operationID" binding:"required"`
// ToUserID string `json:"toUserID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//
//type AddBlacklistReq struct {
// ParamsCommFriend
//}
//type AddBlacklistResp struct {
//
//}
//
//type ImportFriendReq struct {
// FriendUserIDList []string `json:"friendUserIDList" binding:"required"`
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type UserIDResult struct {
// UserID string `json:"userID"`
// Result int32 `json:"result"`
//}
//type ImportFriendResp struct {
//
// UserIDResultList []UserIDResult `json:"data"`
//}
//
//type AddFriendReq struct {
// ParamsCommFriend
// ReqMsg string `json:"reqMsg"`
//}
//type AddFriendResp struct {
//
//}
//
//type AddFriendResponseReq struct {
// ParamsCommFriend
// Flag int32 `json:"flag" binding:"required,oneof=-1 0 1"`
// HandleMsg string `json:"handleMsg"`
//}
//type AddFriendResponseResp struct {
//
//}
//
//type DeleteFriendReq struct {
// ParamsCommFriend
//}
//type DeleteFriendResp struct {
//
//}
//
//type GetBlackListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetBlackListResp struct {
//
// BlackUserInfoList []*sdkws.PublicUserInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
////type PublicUserInfo struct {
//// UserID string `json:"userID"`
//// Nickname string `json:"nickname"`
//// FaceUrl string `json:"faceUrl"`
//// Gender int32 `json:"gender"`
////}
//
//type SetFriendRemarkReq struct {
// ParamsCommFriend
// Remark string `json:"remark"`
//}
//type SetFriendRemarkResp struct {
//
//}
//
//type RemoveBlacklistReq struct {
// ParamsCommFriend
//}
//type RemoveBlacklistResp struct {
//
//}
//
//type IsFriendReq struct {
// ParamsCommFriend
//}
//type Response struct {
// Friend bool `json:"isFriend"`
//}
//type IsFriendResp struct {
//
// Response Response `json:"data"`
//}
//
//type GetFriendsInfoReq struct {
// ParamsCommFriend
//}
//type GetFriendsInfoResp struct {
//
// FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetFriendListResp struct {
//
// FriendInfoList []*sdkws.FriendInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendApplyListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetFriendApplyListResp struct {
//
// FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetSelfApplyListReq struct {
// OperationID string `json:"operationID" binding:"required"`
// FromUserID string `json:"fromUserID" binding:"required"`
//}
//type GetSelfApplyListResp struct {
//
// FriendRequestList []*sdkws.FriendRequest `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type FriendInfo struct {
UserID string `json:"userID"`
Nickname string `json:"nickname"`
FaceURL string `json:"faceURL"`
Gender int32 `json:"gender"`
Ex string `json:"ex"`
}
type PublicUserInfo struct {
UserID string `json:"userID"`
Nickname string `json:"nickname"`
FaceURL string `json:"faceURL"`
Gender int32 `json:"gender"`
Ex string `json:"ex"`
}
type FriendRequest struct {
FromUserID string `json:"fromUserID"`
FromNickname string `json:"fromNickname"`
FromFaceURL string `json:"fromFaceURL"`
FromGender int32 `json:"fromGender"`
ToUserID string `json:"toUserID"`
ToNickname string `json:"toNickname"`
ToFaceURL string `json:"toFaceURL"`
ToGender int32 `json:"toGender"`
HandleResult int32 `json:"handleResult"`
ReqMsg string `json:"reqMsg"`
CreateTime uint32 `json:"createTime"`
HandlerUserID string `json:"handlerUserID"`
HandleMsg string `json:"handleMsg"`
HandleTime uint32 `json:"handleTime"`
Ex string `json:"ex"`
}
type AddBlacklistReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type AddBlacklistResp struct{}
type ImportFriendReq struct {
FriendUserIDList []string `json:"friendUserIDList" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type ImportFriendResp struct {
//
}
type AddFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
ReqMsg string `json:"reqMsg"`
}
type AddFriendResp struct {
//
}
type AddFriendResponseReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
HandleResult int32 `json:"flag" binding:"required,oneof=-1 0 1"`
HandleMsg string `json:"handleMsg"`
}
type AddFriendResponseResp struct{}
type DeleteFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type DeleteFriendResp struct{}
type GetBlackListReq struct {
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetBlackListResp struct {
BlackUserInfoList []PublicUserInfo `json:"blackUserInfoList"`
}
type SetFriendRemarkReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
Remark string `json:"remark"`
}
type SetFriendRemarkResp struct{}
type RemoveBlacklistReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type RemoveBlacklistResp struct{}
type IsFriendReq struct {
ToUserID string `json:"toUserID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type Response struct {
Friend bool `json:"isFriend"`
}
type IsFriendResp struct {
Response Response `json:"data"`
}
type GetFriendListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetFriendListResp struct {
OwnerUserID string `json:"ownerUserID"`
Remark string `json:"remark"`
CreateTime uint32 `json:"createTime"`
AddSource int32 `json:"addSource"`
OperatorUserID string `json:"operatorUserID"`
Ex string `json:"ex"`
// FriendUser *UserInfo // TODO
}
type GetFriendApplyListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetFriendApplyListResp struct {
FriendRequestList []FriendRequest `json:"friendRequestList"`
}
type GetSelfApplyListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetSelfApplyListResp struct {
FriendRequestList []FriendRequest `json:"friendRequestList"`
}

@ -1,272 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
type KickGroupMemberReq struct {
GroupID string `json:"groupID" binding:"required"`
KickedUserIDList []string `json:"kickedUserIDList" binding:"required"`
Reason string `json:"reason"`
OperationID string `json:"operationID" binding:"required"`
}
type KickGroupMemberResp struct {
// UserIDResultList []*UserIDResult `json:"data"`
}
type GetGroupMembersInfoReq struct {
GroupID string `json:"groupID" binding:"required"`
MemberList []string `json:"memberList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetGroupMembersInfoResp struct {
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type InviteUserToGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
InvitedUserIDList []string `json:"invitedUserIDList" binding:"required"`
Reason string `json:"reason"`
OperationID string `json:"operationID" binding:"required"`
}
type InviteUserToGroupResp struct {
// UserIDResultList []*UserIDResult `json:"data"`
}
type GetJoinedGroupListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
}
type GetJoinedGroupListResp struct {
GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupMemberListReq struct {
GroupID string `json:"groupID"`
Filter int32 `json:"filter"`
NextSeq int32 `json:"nextSeq"`
OperationID string `json:"operationID"`
}
type GetGroupMemberListResp struct {
NextSeq int32 `json:"nextSeq"`
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupAllMemberReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
Offset int32 `json:"offset"`
Count int32 `json:"count"`
}
type GetGroupAllMemberResp struct {
MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
//
//type GetGroupAllMemberListBySplitReq struct {
// GroupID string `json:"groupID" binding:"required"`
// OperationID string `json:"operationID" binding:"required"`
// Offset int32 `json:"offset" binding:"required"`
// Count int32 `json:"count" binding:"required"`
//}
//type GetGroupAllMemberListBySplitResp struct {
//
// MemberList []*sdkws.GroupMemberFullInfo `json:"-"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type CreateGroupReq struct {
MemberList []*GroupAddMemberInfo `json:"memberList"`
OwnerUserID string `json:"ownerUserID"`
GroupType int32 `json:"groupType"`
GroupName string `json:"groupName"`
Notification string `json:"notification"`
Introduction string `json:"introduction"`
FaceURL string `json:"faceURL"`
Ex string `json:"ex"`
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID"`
}
type CreateGroupResp struct {
GroupInfo sdkws.GroupInfo `json:"-"`
Data map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetGroupApplicationListReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"` // 作为管理员或群主收到的 进群申请
}
type GetGroupApplicationListResp struct {
GroupRequestList []*sdkws.GroupRequest `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
type GetUserReqGroupApplicationListReq struct {
OperationID string `json:"operationID" binding:"required"`
UserID string `json:"userID" binding:"required"`
}
type GetUserRespGroupApplicationResp struct {
GroupRequestList []*sdkws.GroupRequest `json:"data"`
}
type GetGroupInfoReq struct {
GroupIDList []string `json:"groupIDList" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type GetGroupInfoResp struct {
GroupInfoList []*sdkws.GroupInfo `json:"-"`
Data []map[string]interface{} `json:"data" swaggerignore:"true"`
}
//type GroupInfoAlias struct {
// sdkws.GroupInfo
// NeedVerification int32 `protobuf:"bytes,13,opt,name=needVerification" json:"needVerification,omitempty"`
//}
//type GroupInfoAlias struct {
// GroupID string `protobuf:"bytes,1,opt,name=groupID" json:"groupID,omitempty"`
// GroupName string `protobuf:"bytes,2,opt,name=groupName" json:"groupName,omitempty"`
// Notification string `protobuf:"bytes,3,opt,name=notification" json:"notification,omitempty"`
// Introduction string `protobuf:"bytes,4,opt,name=introduction" json:"introduction,omitempty"`
// FaceURL string `protobuf:"bytes,5,opt,name=faceURL" json:"faceURL,omitempty"`
// OwnerUserID string `protobuf:"bytes,6,opt,name=ownerUserID" json:"ownerUserID,omitempty"`
// CreateTime uint32 `protobuf:"varint,7,opt,name=createTime" json:"createTime,omitempty"`
// MemberCount uint32 `protobuf:"varint,8,opt,name=memberCount" json:"memberCount,omitempty"`
// Ex string `protobuf:"bytes,9,opt,name=ex" json:"ex,omitempty"`
// Status int32 `protobuf:"varint,10,opt,name=status" json:"status,omitempty"`
// CreatorUserID string `protobuf:"bytes,11,opt,name=creatorUserID" json:"creatorUserID,omitempty"`
// GroupType int32 `protobuf:"varint,12,opt,name=groupType" json:"groupType,omitempty"`
// NeedVerification int32 `protobuf:"bytes,13,opt,name=needVerification" json:"needVerification,omitempty"`
//}
type ApplicationGroupResponseReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"` // application from FromUserID
HandledMsg string `json:"handledMsg"`
HandleResult int32 `json:"handleResult" binding:"required,oneof=-1 1"`
}
type ApplicationGroupResponseResp struct{}
type JoinGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
ReqMessage string `json:"reqMessage"`
OperationID string `json:"operationID" binding:"required"`
JoinSource int32 `json:"joinSource"`
InviterUserID string `json:"inviterUserID"`
}
type JoinGroupResp struct{}
type QuitGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type QuitGroupResp struct{}
type SetGroupInfoReq struct {
GroupID string `json:"groupID" binding:"required"`
GroupName string `json:"groupName"`
Notification string `json:"notification"`
Introduction string `json:"introduction"`
FaceURL string `json:"faceURL"`
Ex string `json:"ex"`
OperationID string `json:"operationID" binding:"required"`
NeedVerification *int32 `json:"needVerification"`
LookMemberInfo *int32 `json:"lookMemberInfo"`
ApplyMemberFriend *int32 `json:"applyMemberFriend"`
}
type SetGroupInfoResp struct{}
type TransferGroupOwnerReq struct {
GroupID string `json:"groupID" binding:"required"`
OldOwnerUserID string `json:"oldOwnerUserID" binding:"required"`
NewOwnerUserID string `json:"newOwnerUserID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type TransferGroupOwnerResp struct{}
type DismissGroupReq struct {
GroupID string `json:"groupID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type DismissGroupResp struct{}
type MuteGroupMemberReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
MutedSeconds uint32 `json:"mutedSeconds" binding:"required"`
}
type MuteGroupMemberResp struct{}
type CancelMuteGroupMemberReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
}
type CancelMuteGroupMemberResp struct{}
type MuteGroupReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
}
type MuteGroupResp struct{}
type CancelMuteGroupReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
}
type CancelMuteGroupResp struct{}
type SetGroupMemberNicknameReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
Nickname string `json:"nickname"`
}
type SetGroupMemberNicknameResp struct{}
type SetGroupMemberInfoReq struct {
OperationID string `json:"operationID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
UserID string `json:"userID" binding:"required"`
Nickname *string `json:"nickname"`
FaceURL *string `json:"userGroupFaceUrl"`
RoleLevel *int32 `json:"roleLevel" validate:"gte=1,lte=3"`
Ex *string `json:"ex"`
}
type SetGroupMemberInfoResp struct{}
type GetGroupAbstractInfoReq struct {
OperationID string `json:"operationID"`
GroupID string `json:"groupID"`
}
type GetGroupAbstractInfoResp struct {
GroupMemberNumber int32 `json:"groupMemberNumber"`
GroupMemberListHash uint64 `json:"groupMemberListHash"`
}

@ -18,34 +18,7 @@ import (
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
)
type DeleteUsersReq struct {
OperationID string `json:"operationID" binding:"required"`
DeleteUserIDList []string `json:"deleteUserIDList" binding:"required"`
}
type DeleteUsersResp struct {
FailedUserIDList []string `json:"data"`
}
type GetAllUsersUidReq struct {
OperationID string `json:"operationID" binding:"required"`
}
type GetAllUsersUidResp struct {
UserIDList []string `json:"data"`
}
type GetUsersOnlineStatusReq struct {
OperationID string `json:"operationID" binding:"required"`
UserIDList []string `json:"userIDList" binding:"required,lte=200"`
}
type GetUsersOnlineStatusResp struct {
// SuccessResult []*msggateway.GetUsersOnlineStatusResp_SuccessResult `json:"data"`
}
type AccountCheckReq struct {
OperationID string `json:"operationID" binding:"required"`
CheckUserIDList []string `json:"checkUserIDList" binding:"required,lte=100"`
}
type AccountCheckResp struct{}
type ManagementSendMsg struct {
type SendMsg struct {
SendID string `json:"sendID" binding:"required"`
GroupID string `json:"groupID" binding:"required_if=SessionType 2|required_if=SessionType 3"`
SenderNickname string `json:"senderNickname"`
@ -59,48 +32,25 @@ type ManagementSendMsg struct {
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
}
type ManagementSendMsgReq struct {
SendID string `json:"sendID" binding:"required"`
type SendMsgReq struct {
RecvID string `json:"recvID" binding:"required_if" message:"recvID is required if sessionType is SingleChatType or NotificationChatType"`
GroupID string `json:"groupID" binding:"required_if" message:"groupID is required if sessionType is GroupChatType or SuperGroupChatType"`
SenderNickname string `json:"senderNickname"`
SenderFaceURL string `json:"senderFaceURL"`
SenderPlatformID int32 `json:"senderPlatformID"`
Content map[string]interface{} `json:"content" binding:"required" swaggerignore:"true"`
ContentType int32 `json:"contentType" binding:"required"`
SessionType int32 `json:"sessionType" binding:"required"`
IsOnlineOnly bool `json:"isOnlineOnly"`
NotOfflinePush bool `json:"notOfflinePush"`
OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"`
SendMsg
}
type ManagementSendMsgResp struct {
ResultList sdkws.UserSendMsgResp `json:"data"`
}
type ManagementBatchSendMsgReq struct {
ManagementSendMsg
type BatchSendMsgReq struct {
SendMsg
IsSendAll bool `json:"isSendAll"`
RecvIDList []string `json:"recvIDList"`
RecvIDs []string `json:"recvIDs"`
}
type ManagementBatchSendMsgResp struct {
Data struct {
ResultList []*SingleReturnResult `json:"resultList"`
FailedIDList []string
} `json:"data"`
type BatchSendMsgResp struct {
Results []*SingleReturnResult `json:"results"`
FailedIDs []string `json:"failedUserIDs"`
}
type SingleReturnResult struct {
ServerMsgID string `json:"serverMsgID"`
ClientMsgID string `json:"clientMsgID"`
SendTime int64 `json:"sendTime"`
RecvID string `json:"recvID"`
}
type CheckMsgIsSendSuccessReq struct {
OperationID string `json:"operationID"`
}
type CheckMsgIsSendSuccessResp struct {
Status int32 `json:"status"`
}

@ -14,46 +14,6 @@
package apistruct
type DelMsgReq struct {
UserID string `json:"userID,omitempty" binding:"required"`
SeqList []uint32 `json:"seqList,omitempty" binding:"required"`
OperationID string `json:"operationID,omitempty" binding:"required"`
}
type DelMsgResp struct{}
type CleanUpMsgReq struct {
UserID string `json:"userID" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type CleanUpMsgResp struct{}
type DelSuperGroupMsgReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID" binding:"required"`
SeqList []uint32 `json:"seqList,omitempty"`
IsAllDelete bool `json:"isAllDelete"`
OperationID string `json:"operationID" binding:"required"`
}
type DelSuperGroupMsgResp struct{}
type MsgDeleteNotificationElem struct {
GroupID string `json:"groupID"`
IsAllDelete bool `json:"isAllDelete"`
SeqList []uint32 `json:"seqList"`
}
type SetMsgMinSeqReq struct {
UserID string `json:"userID" binding:"required"`
GroupID string `json:"groupID"`
MinSeq uint32 `json:"minSeq" binding:"required"`
OperationID string `json:"operationID" binding:"required"`
}
type SetMsgMinSeqResp struct{}
type PictureBaseInfo struct {
UUID string `mapstructure:"uuid"`
Type string `mapstructure:"type"`
@ -113,7 +73,7 @@ type CustomElem struct {
Extension string `mapstructure:"extension"`
}
type TextElem struct {
Content string `mapstructure:"content" validate:"required"`
Text string `mapstructure:"text" validate:"required"`
}
type RevokeElem struct {

@ -1,35 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type OSSCredentialReq struct {
OperationID string `json:"operationID"`
Filename string `json:"filename"`
FileType string `json:"file_type"`
}
type OSSCredentialRespData struct {
Endpoint string `json:"endpoint"`
AccessKeyId string `json:"access_key_id"`
AccessKeySecret string `json:"access_key_secret"`
Token string `json:"token"`
Bucket string `json:"bucket"`
FinalHost string `json:"final_host"`
}
type OSSCredentialResp struct {
OssData OSSCredentialRespData `json:"-"`
Data map[string]interface{} `json:"data"`
}

@ -1,20 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type Pagination struct {
PageNumber int32 `json:"pageNumber" binding:"required"`
ShowNumber int32 `json:"showNumber" binding:"required"`
}

@ -14,18 +14,6 @@
package apistruct
type ApiUserInfo struct {
UserID string `json:"userID" binding:"required,min=1,max=64" swaggo:"true,用户ID,"`
Nickname string `json:"nickname" binding:"omitempty,min=1,max=64" swaggo:"true,my id,19"`
FaceURL string `json:"faceURL" binding:"omitempty,max=1024"`
Gender int32 `json:"gender" binding:"omitempty,oneof=0 1 2"`
PhoneNumber string `json:"phoneNumber" binding:"omitempty,max=32"`
Birth int64 `json:"birth" binding:"omitempty"`
Email string `json:"email" binding:"omitempty,max=64"`
CreateTime int64 `json:"createTime"`
Ex string `json:"ex" binding:"omitempty,max=1024"`
}
type GroupAddMemberInfo struct {
UserID string `json:"userID" binding:"required"`
RoleLevel int32 `json:"roleLevel" binding:"required,oneof= 1 3"`

@ -1,31 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
type GetJoinedSuperGroupListReq struct {
GetJoinedGroupListReq
}
type GetJoinedSuperGroupListResp struct {
GetJoinedGroupListResp
}
type GetSuperGroupsInfoReq struct {
GetGroupInfoReq
}
type GetSuperGroupsInfoResp struct {
GetGroupInfoResp
}

@ -1,128 +0,0 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package apistruct
import "mime/multipart"
type MinioStorageCredentialReq struct {
OperationID string `json:"operationID"`
}
type MiniostorageCredentialResp struct {
SecretAccessKey string `json:"secretAccessKey"`
AccessKeyID string `json:"accessKeyID"`
SessionToken string `json:"sessionToken"`
BucketName string `json:"bucketName"`
StsEndpointURL string `json:"stsEndpointURL"`
StorageTime int `json:"storageTime"`
IsDistributedMod bool `json:"isDistributedMod"`
}
type MinioUploadFileReq struct {
OperationID string `form:"operationID" binding:"required"`
FileType int `form:"fileType" binding:"required"`
}
type MinioUploadFile struct {
URL string `json:"URL"`
NewName string `json:"newName"`
SnapshotURL string `json:"snapshotURL,omitempty"`
SnapshotNewName string `json:"snapshotName,omitempty"`
}
type MinioUploadFileResp struct {
Data struct {
MinioUploadFile
} `json:"data"`
}
type UploadUpdateAppReq struct {
OperationID string `form:"operationID" binding:"required"`
Type int `form:"type" binding:"required"`
Version string `form:"version" binding:"required"`
File *multipart.FileHeader `form:"file" binding:"required"`
Yaml *multipart.FileHeader `form:"yaml"`
ForceUpdate bool `form:"forceUpdate"`
UpdateLog string `form:"updateLog" binding:"required"`
}
type UploadUpdateAppResp struct{}
type GetDownloadURLReq struct {
OperationID string `json:"operationID" binding:"required"`
Type int `json:"type" binding:"required"`
Version string `json:"version" binding:"required"`
}
type GetDownloadURLResp struct {
Data struct {
HasNewVersion bool `json:"hasNewVersion"`
ForceUpdate bool `json:"forceUpdate"`
FileURL string `json:"fileURL"`
YamlURL string `json:"yamlURL"`
Version string `json:"version"`
UpdateLog string `json:"update_log"`
} `json:"data"`
}
type GetRTCInvitationInfoReq struct {
OperationID string `json:"operationID" binding:"required"`
ClientMsgID string `json:"clientMsgID" binding:"required"`
}
type GetRTCInvitationInfoResp struct {
Data struct {
OpUserID string `json:"opUserID"`
Invitation struct {
InviterUserID string `json:"inviterUserID"`
InviteeUserIDList []string `json:"inviteeUserIDList"`
GroupID string `json:"groupID"`
RoomID string `json:"roomID"`
Timeout int32 `json:"timeout"`
MediaType string `json:"mediaType"`
SessionType int32 `json:"sessionType"`
InitiateTime int32 `json:"initiateTime"`
PlatformID int32 `json:"platformID"`
CustomData string `json:"customData"`
} `json:"invitation"`
OfflinePushInfo struct{} `json:"offlinePushInfo"`
} `json:"data"`
}
type GetRTCInvitationInfoStartAppReq struct {
OperationID string `json:"operationID" binding:"required"`
}
type GetRTCInvitationInfoStartAppResp struct {
GetRTCInvitationInfoResp
}
/**
* FCMToken.
*/
type FcmUpdateTokenReq struct {
OperationID string `json:"operationID" binding:"required"`
Platform int `json:"platform" binding:"required,min=1,max=2"` // only for ios + android
FcmToken string `json:"fcmToken" binding:"required"`
}
type FcmUpdateTokenResp struct{}
type SetAppBadgeReq struct {
OperationID string `json:"operationID" binding:"required"`
FromUserID string `json:"fromUserID" binding:"required"`
AppUnreadCount int32 `json:"appUnreadCount"`
}
type SetAppBadgeResp struct{}

@ -16,7 +16,7 @@ package cmd
import (
"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
//"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway"
//"github.com/OpenIMSDK/Open-IM-Server/internal/msggateway".
"github.com/spf13/cobra"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"

@ -31,7 +31,7 @@ type CallBackConfig struct {
type NotificationConf struct {
IsSendMsg bool `yaml:"isSendMsg"`
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 presistent
ReliabilityLevel int `yaml:"reliabilityLevel"` // 1 online 2 persistent
UnreadCount bool `yaml:"unreadCount"`
OfflinePush POfflinePush `yaml:"offlinePush"`
}

@ -30,7 +30,7 @@ import (
var (
_, b, _, _ = runtime.Caller(0)
// Root folder of this project
// Root folder of this project.
Root = filepath.Join(filepath.Dir(b), "../../..")
)

@ -45,7 +45,7 @@ const (
SignalMsg = 202
CustomNotification = 203
//SysRelated.
// SysRelated.
NotificationBegin = 1000
FriendApplicationApprovedNotification = 1201 // add_friend_response
@ -113,37 +113,37 @@ const (
NotificationEnd = 5000
//status.
// status.
MsgNormal = 1
MsgDeleted = 4
//MsgFrom.
// MsgFrom.
UserMsgType = 100
SysMsgType = 200
//SessionType.
// SessionType.
SingleChatType = 1
GroupChatType = 2
SuperGroupChatType = 3
NotificationChatType = 4
//token.
// token.
NormalToken = 0
InValidToken = 1
KickedToken = 2
ExpiredToken = 3
//MultiTerminalLogin.
// MultiTerminalLogin.
DefalutNotKick = 0
//Full-end login, but the same end is mutually exclusive.
// Full-end login, but the same end is mutually exclusive.
AllLoginButSameTermKick = 1
//Only one of the endpoints can log in.
// Only one of the endpoints can log in.
SingleTerminalLogin = 2
//The web side can be online at the same time, and the other side can only log in at one end.
// The web side can be online at the same time, and the other side can only log in at one end.
WebAndOther = 3
// The PC side is mutually exclusive, and the mobile side is mutually exclusive, but the web side can be online at
// the same time.
PcMobileAndWeb = 4
//The PC terminal can be online at the same time,but other terminal only one of the endpoints can login.
// The PC terminal can be online at the same time,but other terminal only one of the endpoints can login.
PCAndOther = 5
OnlineStatus = "online"
@ -151,12 +151,12 @@ const (
Registered = "registered"
UnRegistered = "unregistered"
//MsgReceiveOpt.
// MsgReceiveOpt.
ReceiveMessage = 0
NotReceiveMessage = 1
ReceiveNotNotifyMessage = 2
//OptionsKey.
// OptionsKey.
IsHistory = "history"
IsPersistent = "persistent"
IsOfflinePush = "offlinePush"
@ -170,13 +170,13 @@ const (
IsNotNotification = "isNotNotification"
IsSendMsg = "isSendMsg"
//GroupStatus.
// GroupStatus.
GroupOk = 0
GroupBanChat = 1
GroupStatusDismissed = 2
GroupStatusMuted = 3
//GroupType.
// GroupType.
NormalGroup = 0
SuperGroup = 1
WorkingGroup = 2
@ -184,19 +184,19 @@ const (
GroupBaned = 3
GroupBanPrivateChat = 4
//UserJoinGroupSource.
// UserJoinGroupSource.
JoinByAdmin = 1
JoinByInvitation = 2
JoinBySearch = 3
JoinByQRCode = 4
//Minio.
// Minio.
MinioDurationTimes = 3600
//Aws.
// Aws.
AwsDurationTimes = 3600
//callbackCommand.
// callbackCommand.
CallbackBeforeSendSingleMsgCommand = "callbackBeforeSendSingleMsgCommand"
CallbackAfterSendSingleMsgCommand = "callbackAfterSendSingleMsgCommand"
CallbackBeforeSendGroupMsgCommand = "callbackBeforeSendGroupMsgCommand"
@ -217,10 +217,10 @@ const (
CallbackGetMessageListReactionExtensionsCommand = "callbackGetMessageListReactionExtensionsCommand"
CallbackAddMessageListReactionExtensionsCommand = "callbackAddMessageListReactionExtensionsCommand"
//callback actionCode.
// callback actionCode.
ActionAllow = 0
ActionForbidden = 1
//callback callbackHandleCode.
// callback callbackHandleCode.
CallbackHandleSuccess = 0
CallbackHandleFailed = 1

@ -15,9 +15,9 @@
package constant
// fixme 1<--->IOS 2<--->Android 3<--->Windows
// fixme 4<--->OSX 5<--->Web 6<--->MiniWeb 7<--->Linux
// fixme 4<--->OSX 5<--->Web 6<--->MiniWeb 7<--->Linux.
const (
//Platform ID.
// Platform ID.
IOSPlatformID = 1
AndroidPlatformID = 2
WindowsPlatformID = 3
@ -29,7 +29,7 @@ const (
IPadPlatformID = 9
AdminPlatformID = 10
//Platform string match to Platform ID.
// Platform string match to Platform ID.
IOSPlatformStr = "IOS"
AndroidPlatformStr = "Android"
WindowsPlatformStr = "Windows"
@ -41,7 +41,7 @@ const (
IPadPlatformStr = "IPad"
AdminPlatformStr = "Admin"
//terminal types.
// terminal types.
TerminalPC = "PC"
TerminalMobile = "Mobile"
)

@ -76,7 +76,7 @@ func Db2PbGroupMember(m *relation.GroupMemberModel) *sdkws.GroupMemberFullInfo {
JoinTime: m.JoinTime.UnixMilli(),
Nickname: m.Nickname,
FaceURL: m.FaceURL,
//AppMangerLevel: m.AppMangerLevel,
// AppMangerLevel: m.AppMangerLevel,
JoinSource: m.JoinSource,
OperatorUserID: m.OperatorUserID,
Ex: m.Ex,

@ -54,7 +54,6 @@ func MsgPb2DB(msg *sdkws.MsgData) *unrelation.MsgDataModel {
msgDataModel.AttachedInfo = msg.AttachedInfo
msgDataModel.Ex = msg.Ex
return &msgDataModel
}
func MsgDB2Pb(msgModel *unrelation.MsgDataModel) *sdkws.MsgData {

@ -29,13 +29,13 @@ const (
blackExpireTime = time.Second * 60 * 60 * 12
)
// args fn will exec when no data in msgCache
// args fn will exec when no data in msgCache.
type BlackCache interface {
//get blackIDs from msgCache
// get blackIDs from msgCache
metaCache
NewCache() BlackCache
GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error)
//del user's blackIDs msgCache, exec when a user's black list changed
// del user's blackIDs msgCache, exec when a user's black list changed
DelBlackIDs(ctx context.Context, userID string) BlackCache
}

@ -41,7 +41,7 @@ const (
conversationExpireTime = time.Second * 60 * 60 * 12
)
// arg fn will exec when no data in msgCache
// arg fn will exec when no data in msgCache.
type ConversationCache interface {
metaCache
NewCache() ConversationCache

@ -32,7 +32,7 @@ const (
friendKey = "FRIEND_INFO:"
)
// args fn will exec when no data in msgCache
// args fn will exec when no data in msgCache.
type FriendCache interface {
metaCache
NewCache() FriendCache
@ -109,7 +109,7 @@ func (f *FriendCacheRedis) DelFriendIDs(ownerUserID ...string) FriendCache {
return new
}
// todo
// todo.
func (f *FriendCacheRedis) GetTwoWayFriendIDs(
ctx context.Context,
ownerUserID string,

@ -106,7 +106,8 @@ func NewGroupCacheRedis(
opts rockscache.Options,
) GroupCache {
rcClient := rockscache.NewClient(rdb, opts)
return &GroupCacheRedis{rcClient: rcClient, expireTime: groupExpireTime,
return &GroupCacheRedis{
rcClient: rcClient, expireTime: groupExpireTime,
groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB,
mongoDB: mongoClient, metaCache: NewMetaCacheRedis(rcClient),
}
@ -176,7 +177,7 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationTb.GroupMembe
return 0, errIndex
}
// / groupInfo
// / groupInfo.
func (g *GroupCacheRedis) GetGroupsInfo(
ctx context.Context,
groupIDs []string,
@ -265,7 +266,7 @@ func (g *GroupCacheRedis) GetSuperGroupMemberIDs(
)
}
// userJoinSuperGroup
// userJoinSuperGroup.
func (g *GroupCacheRedis) DelJoinedSuperGroupIDs(userIDs ...string) GroupCache {
new := g.NewCache()
var keys []string
@ -286,7 +287,7 @@ func (g *GroupCacheRedis) DelSuperGroupMemberIDs(groupIDs ...string) GroupCache
return new
}
// groupMembersHash
// groupMembersHash.
func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) {
return getCache(
ctx,
@ -331,7 +332,7 @@ func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache {
return cache
}
// groupMemberIDs
// groupMemberIDs.
func (g *GroupCacheRedis) GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) {
return getCache(
ctx,

@ -28,10 +28,10 @@ import (
)
const (
maxRetry = 10 //number of retries
maxRetry = 10 // number of retries
)
// NewRedis Initialize redis connection
// NewRedis Initialize redis connection.
func NewRedis() (redis.UniversalClient, error) {
if len(config.Config.Redis.Address) == 0 {
return nil, errors.New("redis address is empty")

@ -16,11 +16,12 @@ package cache
import (
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"testing"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
)
//TestNewRedis Test redis connection
// TestNewRedis Test redis connection
func TestNewRedis(t *testing.T) {
err := config.InitConfig("config_folder_path")
if err != nil {

@ -212,6 +212,7 @@ func (c *msgCache) GetMaxSeqs(ctx context.Context, conversationIDs []string) (m
func (c *msgCache) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) {
return c.getSeq(ctx, conversationID, c.getMaxSeqKey)
}
func (c *msgCache) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error {
return c.setSeq(ctx, conversationID, minSeq, c.getMinSeqKey)
}
@ -235,6 +236,7 @@ func (c *msgCache) SetMinSeqs(ctx context.Context, seqs map[string]int64) error
func (c *msgCache) GetMinSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) {
return c.getSeqs(ctx, conversationIDs, c.getMinSeqKey)
}
func (c *msgCache) GetMinSeq(ctx context.Context, conversationID string) (int64, error) {
return c.getSeq(ctx, conversationID, c.getMinSeqKey)
}
@ -359,7 +361,7 @@ func (c *msgCache) GetMessagesBySeq(
) (seqMsgs []*sdkws.MsgData, failedSeqs []int64, err error) {
pipe := c.rdb.Pipeline()
for _, v := range seqs {
//MESSAGE_CACHE:169.254.225.224_reliability1653387820_0_1
// MESSAGE_CACHE:169.254.225.224_reliability1653387820_0_1
key := c.getMessageCacheKey(conversationID, v)
if err := pipe.Get(ctx, key).Err(); err != nil && err != redis.Nil {
return nil, nil, err

@ -26,9 +26,9 @@ import (
)
type AuthDatabase interface {
//结果为空 不返回错误
// 结果为空 不返回错误
GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error)
//创建token
// 创建token
CreateToken(ctx context.Context, userID string, platformID int) (string, error)
}
@ -43,7 +43,7 @@ func NewAuthDatabase(cache cache.MsgModel, accessSecret string, accessExpire int
return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire}
}
// 结果为空 不返回错误
// 结果为空 不返回错误.
func (a *authDatabase) GetTokensWithoutError(
ctx context.Context,
userID string,
@ -52,7 +52,7 @@ func (a *authDatabase) GetTokensWithoutError(
return a.cache.GetTokensWithoutError(ctx, userID, platformID)
}
// 创建token
// 创建token.
func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformID int) (string, error) {
tokens, err := a.cache.GetTokensWithoutError(ctx, userID, platformID)
if err != nil {

@ -48,7 +48,7 @@ func NewBlackDatabase(black relation.BlackModelInterface, cache cache.BlackCache
return &blackDatabase{black, cache}
}
// Create 增加黑名单
// Create 增加黑名单.
func (b *blackDatabase) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) {
if err := b.black.Create(ctx, blacks); err != nil {
return err
@ -56,7 +56,7 @@ func (b *blackDatabase) Create(ctx context.Context, blacks []*relation.BlackMode
return b.deleteBlackIDsCache(ctx, blacks)
}
// Delete 删除黑名单
// Delete 删除黑名单.
func (b *blackDatabase) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) {
if err := b.black.Delete(ctx, blacks); err != nil {
return err
@ -72,7 +72,7 @@ func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*relat
return cache.ExecDel(ctx)
}
// FindOwnerBlacks 获取黑名单列表
// FindOwnerBlacks 获取黑名单列表.
func (b *blackDatabase) FindOwnerBlacks(
ctx context.Context,
ownerUserID string,
@ -81,7 +81,7 @@ func (b *blackDatabase) FindOwnerBlacks(
return b.black.FindOwnerBlacks(ctx, ownerUserID, pageNumber, showNumber)
}
// CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true)
// CheckIn 检查user2是否在user1的黑名单列表中(inUser1Blacks==true) 检查user1是否在user2的黑名单列表中(inUser2Blacks==true).
func (b *blackDatabase) CheckIn(
ctx context.Context,
userID1, userID2 string,

@ -27,21 +27,21 @@ import (
)
type ConversationDatabase interface {
//UpdateUserConversationFiled 更新用户该会话的属性信息
// UpdateUserConversationFiled 更新用户该会话的属性信息
UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) error
//CreateConversation 创建一批新的会话
// CreateConversation 创建一批新的会话
CreateConversation(ctx context.Context, conversations []*relationTb.ConversationModel) error
//SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作
// SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作
SyncPeerUserPrivateConversationTx(ctx context.Context, conversation []*relationTb.ConversationModel) error
//FindConversations 根据会话ID获取某个用户的多个会话
// FindConversations 根据会话ID获取某个用户的多个会话
FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationTb.ConversationModel, error)
//FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID
// FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID
FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
//GetUserAllConversation 获取一个用户在服务器上所有的会话
// GetUserAllConversation 获取一个用户在服务器上所有的会话
GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationTb.ConversationModel, error)
//SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性
// SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性
SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationTb.ConversationModel) error
//SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作
// SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作
SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationTb.ConversationModel, filedMap map[string]interface{}) error
CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error
GetConversationIDs(ctx context.Context, userID string) ([]string, error)
@ -98,7 +98,6 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context,
temp.OwnerUserID = v
temp.CreateTime = now
conversations = append(conversations, temp)
}
if len(conversations) > 0 {
err = conversationTx.Create(ctx, conversations)

@ -93,7 +93,7 @@ func NewFriendDatabase(
return &friendDatabase{friend: friend, friendRequest: friendRequest, cache: cache, tx: tx}
}
// ok 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true)
// ok 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true).
func (f *friendDatabase) CheckIn(
ctx context.Context,
userID1, userID2 string,
@ -109,7 +109,7 @@ func (f *friendDatabase) CheckIn(
return utils.IsContain(userID2, userID1FriendIDs), utils.IsContain(userID1, userID2FriendIDs), nil
}
// 增加或者更新好友申请 如果之前有记录则更新,没有记录则新增
// 增加或者更新好友申请 如果之前有记录则更新,没有记录则新增.
func (f *friendDatabase) AddFriendRequest(
ctx context.Context,
fromUserID, toUserID string,
@ -118,11 +118,11 @@ func (f *friendDatabase) AddFriendRequest(
) (err error) {
return f.tx.Transaction(func(tx any) error {
_, err := f.friendRequest.NewTx(tx).Take(ctx, fromUserID, toUserID)
//有db错误
// 有db错误
if err != nil && errs.Unwrap(err) != gorm.ErrRecordNotFound {
return err
}
//无错误 则更新
// 无错误 则更新
if err == nil {
m := make(map[string]interface{}, 1)
m["handle_result"] = 0
@ -135,7 +135,7 @@ func (f *friendDatabase) AddFriendRequest(
}
return nil
}
//gorm.ErrRecordNotFound 错误,则新增
// gorm.ErrRecordNotFound 错误,则新增
if err := f.friendRequest.NewTx(tx).Create(ctx, []*relation.FriendRequestModel{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}); err != nil {
return err
}
@ -143,7 +143,7 @@ func (f *friendDatabase) AddFriendRequest(
})
}
// (1)先判断是否在好友表 (在不在都不返回错误) (2)对于不在好友列表的 插入即可
// (1)先判断是否在好友表 (在不在都不返回错误) (2)对于不在好友列表的 插入即可.
func (f *friendDatabase) BecomeFriends(
ctx context.Context,
ownerUserID string,
@ -152,7 +152,7 @@ func (f *friendDatabase) BecomeFriends(
) (err error) {
cache := f.cache.NewCache()
if err := f.tx.Transaction(func(tx any) error {
//先find 找出重复的 去掉重复的
// 先find 找出重复的 去掉重复的
fs1, err := f.friend.NewTx(tx).FindFriends(ctx, ownerUserID, friendUserIDs)
if err != nil {
return err
@ -194,7 +194,7 @@ func (f *friendDatabase) BecomeFriends(
return cache.ExecDel(ctx)
}
// 拒绝好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)修改申请记录 已拒绝
// 拒绝好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)修改申请记录 已拒绝.
func (f *friendDatabase) RefuseFriendRequest(
ctx context.Context,
friendRequest *relation.FriendRequestModel,
@ -215,7 +215,7 @@ func (f *friendDatabase) RefuseFriendRequest(
return nil
}
// AgreeFriendRequest 同意好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)检查是否好友(不返回错误) (3) 建立双向好友关系(存在的忽略)
// AgreeFriendRequest 同意好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)检查是否好友(不返回错误) (3) 建立双向好友关系(存在的忽略).
func (f *friendDatabase) AgreeFriendRequest(
ctx context.Context,
friendRequest *relation.FriendRequestModel,
@ -289,7 +289,7 @@ func (f *friendDatabase) AgreeFriendRequest(
})
}
// 删除好友 外部判断是否好友关系
// 删除好友 外部判断是否好友关系.
func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) {
if err := f.friend.Delete(ctx, ownerUserID, friendUserIDs); err != nil {
return err
@ -297,7 +297,7 @@ func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendU
return f.cache.DelFriendIDs(append(friendUserIDs, ownerUserID)...).ExecDel(ctx)
}
// 更新好友备注 零值也支持
// 更新好友备注 零值也支持.
func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) {
if err := f.friend.UpdateRemark(ctx, ownerUserID, friendUserID, remark); err != nil {
return err
@ -305,7 +305,7 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs
return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx)
}
// 获取ownerUserID的好友列表 无结果不返回错误
// 获取ownerUserID的好友列表 无结果不返回错误.
func (f *friendDatabase) PageOwnerFriends(
ctx context.Context,
ownerUserID string,
@ -314,7 +314,7 @@ func (f *friendDatabase) PageOwnerFriends(
return f.friend.FindOwnerFriends(ctx, ownerUserID, pageNumber, showNumber)
}
// friendUserID在哪些人的好友列表中
// friendUserID在哪些人的好友列表中.
func (f *friendDatabase) PageInWhoseFriends(
ctx context.Context,
friendUserID string,
@ -323,7 +323,7 @@ func (f *friendDatabase) PageInWhoseFriends(
return f.friend.FindInWhoseFriends(ctx, friendUserID, pageNumber, showNumber)
}
// 获取我发出去的好友申请 无结果不返回错误
// 获取我发出去的好友申请 无结果不返回错误.
func (f *friendDatabase) PageFriendRequestFromMe(
ctx context.Context,
userID string,
@ -332,7 +332,7 @@ func (f *friendDatabase) PageFriendRequestFromMe(
return f.friendRequest.FindFromUserID(ctx, userID, pageNumber, showNumber)
}
// 获取我收到的的好友申请 无结果不返回错误
// 获取我收到的的好友申请 无结果不返回错误.
func (f *friendDatabase) PageFriendRequestToMe(
ctx context.Context,
userID string,
@ -341,7 +341,7 @@ func (f *friendDatabase) PageFriendRequestToMe(
return f.friendRequest.FindToUserID(ctx, userID, pageNumber, showNumber)
}
// 获取某人指定好友的信息 如果有好友不存在,也返回错误
// 获取某人指定好友的信息 如果有好友不存在,也返回错误.
func (f *friendDatabase) FindFriendsWithError(
ctx context.Context,
ownerUserID string,

@ -203,7 +203,7 @@ func (g *groupDatabase) CreateGroup(
groups []*relationTb.GroupModel,
groupMembers []*relationTb.GroupMemberModel,
) error {
var cache = g.cache.NewCache()
cache := g.cache.NewCache()
if err := g.tx.Transaction(func(tx any) error {
if len(groups) > 0 {
if err := g.groupDB.NewTx(tx).Create(ctx, groups); err != nil {
@ -473,7 +473,7 @@ func (g *groupDatabase) UpdateGroupMember(
}
func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationTb.BatchUpdateGroupMember) error {
var cache = g.cache.NewCache()
cache := g.cache.NewCache()
if err := g.tx.Transaction(func(tx any) error {
for _, item := range data {
if err := g.groupMemberDB.NewTx(tx).Update(ctx, item.GroupID, item.UserID, item.Map); err != nil {

@ -15,8 +15,16 @@
package controller
import (
"context"
"errors"
"time"
"gorm.io/gorm"
relation2 "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"github.com/redis/go-redis/v9"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
@ -29,13 +37,11 @@ import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"context"
"errors"
"go.mongodb.org/mongo-driver/mongo"
pbMsg "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"go.mongodb.org/mongo-driver/mongo"
)
const (
@ -100,8 +106,23 @@ type CommonMsgDatabase interface {
MsgToPushMQ(ctx context.Context, key, conversarionID string, msg2mq *sdkws.MsgData) (int32, int64, error)
MsgToMongoMQ(ctx context.Context, key, conversarionID string, msgs []*sdkws.MsgData, lastSeq int64) error
RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*unRelationTb.UserCount, dateCount map[string]int64, err error)
RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error)
RangeUserSendCount(
ctx context.Context,
start time.Time,
end time.Time,
group bool,
ase bool,
pageNumber int32,
showNumber int32,
) (msgCount int64, userCount int64, users []*unRelationTb.UserCount, dateCount map[string]int64, err error)
RangeGroupSendCount(
ctx context.Context,
start time.Time,
end time.Time,
ase bool,
pageNumber int32,
showNumber int32,
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error)
}
func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel cache.MsgModel) CommonMsgDatabase {
@ -166,7 +187,7 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI
return nil
}
num := db.msg.GetSingleGocMsgNum()
//num = 100
// num = 100
for i, field := range fields { // 检查类型
var ok bool
switch key {
@ -384,7 +405,7 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa
func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversationID string, seqs []int64) (totalMsgs []*sdkws.MsgData, err error) {
for docID, seqs := range db.msg.GetDocIDSeqsMap(conversationID, seqs) {
//log.ZDebug(ctx, "getMsgBySeqs", "docID", docID, "seqs", seqs)
// log.ZDebug(ctx, "getMsgBySeqs", "docID", docID, "seqs", seqs)
msgs, err := db.findMsgInfoBySeq(ctx, userID, docID, seqs)
if err != nil {
return nil, err
@ -569,7 +590,22 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co
log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID)
}
}
log.ZInfo(ctx, "db.cache.GetMessagesBySeq", "userID", userID, "conversationID", conversationID, "seqs", seqs, "successMsgs", len(successMsgs), "failedSeqs", failedSeqs, "conversationID", conversationID)
log.ZInfo(
ctx,
"db.cache.GetMessagesBySeq",
"userID",
userID,
"conversationID",
conversationID,
"seqs",
seqs,
"successMsgs",
len(successMsgs),
"failedSeqs",
failedSeqs,
"conversationID",
conversationID,
)
prome.Add(prome.MsgPullFromRedisSuccessCounter, len(successMsgs))
if len(failedSeqs) > 0 {
mongoMsgs, err := db.getMsgBySeqs(ctx, userID, conversationID, failedSeqs)
@ -631,7 +667,6 @@ func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID string
log.ZDebug(ctx, "deleteMsgRecursion finished", "conversationID", conversationID, "userID", userID, "index", index)
break
}
}
}
}
@ -646,7 +681,7 @@ func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID string
return seqs, nil
}
// this is struct for recursion
// this is struct for recursion.
type delMsgRecursionStruct struct {
minSeq int64
delDocIDs []string
@ -659,7 +694,7 @@ func (d *delMsgRecursionStruct) getSetMinSeq() int64 {
// index 0....19(del) 20...69
// seq 70
// set minSeq 21
// recursion 删除list并且返回设置的最小seq
// recursion 删除list并且返回设置的最小seq.
func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversationID string, index int64, delStruct *delMsgRecursionStruct, remainTime int64) (int64, error) {
// find from oldest list
msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1)
@ -785,15 +820,19 @@ func (db *commonMsgDatabase) CleanUpUserConversationsMsgs(ctx context.Context, u
func (db *commonMsgDatabase) SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error {
return db.cache.SetMaxSeq(ctx, conversationID, maxSeq)
}
func (db *commonMsgDatabase) GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) {
return db.cache.GetMaxSeqs(ctx, conversationIDs)
}
func (db *commonMsgDatabase) GetMaxSeq(ctx context.Context, conversationID string) (int64, error) {
return db.cache.GetMaxSeq(ctx, conversationID)
}
func (db *commonMsgDatabase) SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error {
return db.cache.SetMinSeq(ctx, conversationID, minSeq)
}
func (db *commonMsgDatabase) SetMinSeqs(ctx context.Context, seqs map[string]int64) error {
return db.cache.SetMinSeqs(ctx, seqs)
}
@ -801,18 +840,23 @@ func (db *commonMsgDatabase) SetMinSeqs(ctx context.Context, seqs map[string]int
func (db *commonMsgDatabase) GetMinSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) {
return db.cache.GetMinSeqs(ctx, conversationIDs)
}
func (db *commonMsgDatabase) GetMinSeq(ctx context.Context, conversationID string) (int64, error) {
return db.cache.GetMinSeq(ctx, conversationID)
}
func (db *commonMsgDatabase) GetConversationUserMinSeq(ctx context.Context, conversationID string, userID string) (int64, error) {
return db.cache.GetConversationUserMinSeq(ctx, conversationID, userID)
}
func (db *commonMsgDatabase) GetConversationUserMinSeqs(ctx context.Context, conversationID string, userIDs []string) (map[string]int64, error) {
return db.cache.GetConversationUserMinSeqs(ctx, conversationID, userIDs)
}
func (db *commonMsgDatabase) SetConversationUserMinSeq(ctx context.Context, conversationID string, userID string, minSeq int64) error {
return db.cache.SetConversationUserMinSeq(ctx, conversationID, userID, minSeq)
}
func (db *commonMsgDatabase) SetConversationUserMinSeqs(ctx context.Context, conversationID string, seqs map[string]int64) (err error) {
return db.cache.SetConversationUserMinSeqs(ctx, conversationID, seqs)
}
@ -828,6 +872,7 @@ func (db *commonMsgDatabase) UserSetHasReadSeqs(ctx context.Context, userID stri
func (db *commonMsgDatabase) SetHasReadSeq(ctx context.Context, userID string, conversationID string, hasReadSeq int64) error {
return db.cache.SetHasReadSeq(ctx, userID, conversationID, hasReadSeq)
}
func (db *commonMsgDatabase) GetHasReadSeqs(ctx context.Context, userID string, conversationIDs []string) (map[string]int64, error) {
return db.cache.GetHasReadSeqs(ctx, userID, conversationIDs)
}
@ -878,11 +923,26 @@ func (db *commonMsgDatabase) GetMinMaxSeqMongo(ctx context.Context, conversation
return
}
func (db *commonMsgDatabase) RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*unRelationTb.UserCount, dateCount map[string]int64, err error) {
func (db *commonMsgDatabase) RangeUserSendCount(
ctx context.Context,
start time.Time,
end time.Time,
group bool,
ase bool,
pageNumber int32,
showNumber int32,
) (msgCount int64, userCount int64, users []*unRelationTb.UserCount, dateCount map[string]int64, err error) {
return db.msgDocDatabase.RangeUserSendCount(ctx, start, end, group, ase, pageNumber, showNumber)
}
func (db *commonMsgDatabase) RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error) {
func (db *commonMsgDatabase) RangeGroupSendCount(
ctx context.Context,
start time.Time,
end time.Time,
ase bool,
pageNumber int32,
showNumber int32,
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error) {
return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber)
}

@ -16,11 +16,12 @@ package controller
import (
"context"
"path/filepath"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"path/filepath"
"time"
)
type S3Database interface {

@ -26,22 +26,22 @@ import (
)
type UserDatabase interface {
//获取指定用户的信息 如有userID未找到 也返回错误
// 获取指定用户的信息 如有userID未找到 也返回错误
FindWithError(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error)
//获取指定用户的信息 如有userID未找到 不返回错误
// 获取指定用户的信息 如有userID未找到 不返回错误
Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error)
//插入多条 外部保证userID 不重复 且在db中不存在
// 插入多条 外部保证userID 不重复 且在db中不存在
Create(ctx context.Context, users []*relation.UserModel) (err error)
//更新(非零值) 外部保证userID存在
// 更新(非零值) 外部保证userID存在
Update(ctx context.Context, user *relation.UserModel) (err error)
//更新(零值) 外部保证userID存在
// 更新(零值) 外部保证userID存在
UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error)
//如果没找到,不返回错误
// 如果没找到,不返回错误
Page(ctx context.Context, pageNumber, showNumber int32) (users []*relation.UserModel, count int64, err error)
//只要有一个存在就为true
// 只要有一个存在就为true
IsExist(ctx context.Context, userIDs []string) (exist bool, err error)
//获取所有用户ID
GetAllUserID(ctx context.Context) ([]string, error)
GetAllUserID(ctx context.Context, pageNumber, showNumber int32) ([]string, error)
//函数内部先查询db中是否存在存在则什么都不做不存在则插入
InitOnce(ctx context.Context, users []*relation.UserModel) (err error)
// 获取用户总数
@ -75,7 +75,7 @@ func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel
return nil
}
// 获取指定用户的信息 如有userID未找到 也返回错误
// 获取指定用户的信息 如有userID未找到 也返回错误.
func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
users, err = u.cache.GetUsersInfo(ctx, userIDs)
if err != nil {
@ -87,13 +87,13 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use
return
}
// 获取指定用户的信息 如有userID未找到 不返回错误
// 获取指定用户的信息 如有userID未找到 不返回错误.
func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
users, err = u.cache.GetUsersInfo(ctx, userIDs)
return
}
// 插入多条 外部保证userID 不重复 且在db中不存在
// 插入多条 外部保证userID 不重复 且在db中不存在.
func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) {
if err := u.tx.Transaction(func(tx any) error {
err = u.userDB.Create(ctx, users)
@ -111,7 +111,7 @@ func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel)
return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx)
}
// 更新(非零值) 外部保证userID存在
// 更新(非零值) 外部保证userID存在.
func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) {
if err := u.userDB.Update(ctx, user); err != nil {
return err
@ -119,7 +119,7 @@ func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (er
return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx)
}
// 更新(零值) 外部保证userID存在
// 更新(零值) 外部保证userID存在.
func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) {
if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil {
return err
@ -127,7 +127,7 @@ func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[
return u.cache.DelUsersInfo(userID).ExecDel(ctx)
}
// 获取,如果没找到,不返回错误
// 获取,如果没找到,不返回错误.
func (u *userDatabase) Page(
ctx context.Context,
pageNumber, showNumber int32,
@ -135,7 +135,7 @@ func (u *userDatabase) Page(
return u.userDB.Page(ctx, pageNumber, showNumber)
}
// userIDs是否存在 只要有一个存在就为true
// userIDs是否存在 只要有一个存在就为true.
func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) {
users, err := u.userDB.Find(ctx, userIDs)
if err != nil {
@ -147,8 +147,8 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo
return false, nil
}
func (u *userDatabase) GetAllUserID(ctx context.Context) (userIDs []string, err error) {
return u.userDB.GetAllUserID(ctx)
func (u *userDatabase) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
return u.userDB.GetAllUserID(ctx, pageNumber, showNumber)
}
func (u *userDatabase) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) {

@ -76,5 +76,4 @@ func (g *ConversationLocalCache) GetConversationIDs(ctx context.Context, userID
return conversationIDsResp.ConversationIDs, nil
}
return hash.ids, nil
}

@ -35,12 +35,12 @@ func (f *FriendGorm) NewTx(tx any) relation.FriendModelInterface {
return &FriendGorm{NewMetaDB(tx.(*gorm.DB), &relation.FriendModel{})}
}
// 插入多条记录
// 插入多条记录.
func (f *FriendGorm) Create(ctx context.Context, friends []*relation.FriendModel) (err error) {
return utils.Wrap(f.db(ctx).Create(&friends).Error, "")
}
// 删除ownerUserID指定的好友
// 删除ownerUserID指定的好友.
func (f *FriendGorm) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) {
err = utils.Wrap(
f.db(ctx).
@ -52,7 +52,7 @@ func (f *FriendGorm) Delete(ctx context.Context, ownerUserID string, friendUserI
return err
}
// 更新ownerUserID单个好友信息 更新零值
// 更新ownerUserID单个好友信息 更新零值.
func (f *FriendGorm) UpdateByMap(
ctx context.Context,
ownerUserID string,
@ -65,12 +65,12 @@ func (f *FriendGorm) UpdateByMap(
)
}
// 更新好友信息的非零值
// 更新好友信息的非零值.
func (f *FriendGorm) Update(ctx context.Context, friends []*relation.FriendModel) (err error) {
return utils.Wrap(f.db(ctx).Updates(&friends).Error, "")
}
// 更新好友备注(也支持零值
// 更新好友备注(也支持零值 .
func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) {
if remark != "" {
return utils.Wrap(
@ -86,7 +86,7 @@ func (f *FriendGorm) UpdateRemark(ctx context.Context, ownerUserID, friendUserID
return utils.Wrap(f.db(ctx).Where("owner_user_id = ?", ownerUserID).Updates(m).Error, "")
}
// 获取单个好友信息,如没找到 返回错误
// 获取单个好友信息,如没找到 返回错误.
func (f *FriendGorm) Take(
ctx context.Context,
ownerUserID, friendUserID string,
@ -98,7 +98,7 @@ func (f *FriendGorm) Take(
)
}
// 查找好友关系,如果是双向关系,则都返回
// 查找好友关系,如果是双向关系,则都返回.
func (f *FriendGorm) FindUserState(
ctx context.Context,
userID1, userID2 string,
@ -112,7 +112,7 @@ func (f *FriendGorm) FindUserState(
)
}
// 获取 owner指定的好友列表 如果有friendUserIDs不存在也不返回错误
// 获取 owner指定的好友列表 如果有friendUserIDs不存在也不返回错误.
func (f *FriendGorm) FindFriends(
ctx context.Context,
ownerUserID string,
@ -124,7 +124,7 @@ func (f *FriendGorm) FindFriends(
)
}
// 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在也不返回错误
// 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在也不返回错误.
func (f *FriendGorm) FindReversalFriends(
ctx context.Context,
friendUserID string,
@ -136,7 +136,7 @@ func (f *FriendGorm) FindReversalFriends(
)
}
// 获取ownerUserID好友列表 支持翻页
// 获取ownerUserID好友列表 支持翻页.
func (f *FriendGorm) FindOwnerFriends(
ctx context.Context,
ownerUserID string,
@ -158,7 +158,7 @@ func (f *FriendGorm) FindOwnerFriends(
return
}
// 获取哪些人添加了friendUserID 支持翻页
// 获取哪些人添加了friendUserID 支持翻页.
func (f *FriendGorm) FindInWhoseFriends(
ctx context.Context,
friendUserID string,

@ -35,12 +35,12 @@ func (f *FriendRequestGorm) NewTx(tx any) relation.FriendRequestModelInterface {
return &FriendRequestGorm{NewMetaDB(tx.(*gorm.DB), &relation.FriendRequestModel{})}
}
// 插入多条记录
// 插入多条记录.
func (f *FriendRequestGorm) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) (err error) {
return utils.Wrap(f.db(ctx).Create(&friendRequests).Error, "")
}
// 删除记录
// 删除记录.
func (f *FriendRequestGorm) Delete(ctx context.Context, fromUserID, toUserID string) (err error) {
return utils.Wrap(
f.db(ctx).
@ -51,7 +51,7 @@ func (f *FriendRequestGorm) Delete(ctx context.Context, fromUserID, toUserID str
)
}
// 更新零值
// 更新零值.
func (f *FriendRequestGorm) UpdateByMap(
ctx context.Context,
fromUserID string,
@ -68,7 +68,7 @@ func (f *FriendRequestGorm) UpdateByMap(
)
}
// 更新记录 (非零值)
// 更新记录 (非零值).
func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) {
return utils.Wrap(
f.db(ctx).
@ -79,7 +79,7 @@ func (f *FriendRequestGorm) Update(ctx context.Context, friendRequest *relation.
)
}
// 获取来指定用户的好友申请 未找到 不返回错误
// 获取来指定用户的好友申请 未找到 不返回错误.
func (f *FriendRequestGorm) Find(
ctx context.Context,
fromUserID, toUserID string,
@ -104,7 +104,7 @@ func (f *FriendRequestGorm) Take(
return friendRequest, err
}
// 获取toUserID收到的好友申请列表
// 获取toUserID收到的好友申请列表.
func (f *FriendRequestGorm) FindToUserID(
ctx context.Context,
toUserID string,
@ -126,7 +126,7 @@ func (f *FriendRequestGorm) FindToUserID(
return
}
// 获取fromUserID发出去的好友申请列表
// 获取fromUserID发出去的好友申请列表.
func (f *FriendRequestGorm) FindFromUserID(
ctx context.Context,
fromUserID string,

@ -16,9 +16,10 @@ package relation
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"gorm.io/gorm"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/ormutil"
@ -67,6 +68,7 @@ func (g *GroupGorm) Search(ctx context.Context, keyword string, pageNumber, show
db = db.WithContext(ctx).Where("status!=?", constant.GroupStatusDismissed)
return ormutil.GormSearch[relation.GroupModel](db, []string{"name"}, keyword, pageNumber, showNumber)
}
func (g *GroupGorm) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) {
return groupIDs, utils.Wrap(g.DB.Model(&relation.GroupModel{}).Where("group_type = ? ", groupType).Pluck("group_id", &groupIDs).Error, "")
}

@ -31,10 +31,10 @@ import (
)
const (
maxRetry = 100 //number of retries
maxRetry = 100 // number of retries
)
// newMysqlGormDB Initialize the database connection
// newMysqlGormDB Initialize the database connection.
func newMysqlGormDB() (*gorm.DB, error) {
dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=true&loc=Local",
config.Config.Mysql.Username, config.Config.Mysql.Password, config.Config.Mysql.Address[0], "mysql")
@ -84,7 +84,7 @@ func newMysqlGormDB() (*gorm.DB, error) {
return db, nil
}
// connectToDatabase Connection retry for mysql
// connectToDatabase Connection retry for mysql.
func connectToDatabase(dsn string, maxRetry int) (*gorm.DB, error) {
var db *gorm.DB
var err error
@ -101,7 +101,7 @@ func connectToDatabase(dsn string, maxRetry int) (*gorm.DB, error) {
return nil, err
}
// NewGormDB gorm mysql
// NewGormDB gorm mysql.
func NewGormDB() (*gorm.DB, error) {
specialerror.AddReplace(gorm.ErrRecordNotFound, errs.ErrRecordNotFound)
specialerror.AddErrHandler(replaceDuplicateKey)

@ -34,35 +34,35 @@ func NewUserGorm(db *gorm.DB) relation.UserModelInterface {
return &UserGorm{NewMetaDB(db, &relation.UserModel{})}
}
// 插入多条
// 插入多条.
func (u *UserGorm) Create(ctx context.Context, users []*relation.UserModel) (err error) {
return utils.Wrap(u.db(ctx).Create(&users).Error, "")
}
// 更新用户信息 零值
// 更新用户信息 零值.
func (u *UserGorm) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) {
return utils.Wrap(u.db(ctx).Model(&relation.UserModel{}).Where("user_id = ?", userID).Updates(args).Error, "")
}
// 更新多个用户信息 非零值
// 更新多个用户信息 非零值.
func (u *UserGorm) Update(ctx context.Context, user *relation.UserModel) (err error) {
return utils.Wrap(u.db(ctx).Model(user).Updates(user).Error, "")
}
// 获取指定用户信息 不存在,也不返回错误
// 获取指定用户信息 不存在,也不返回错误.
func (u *UserGorm) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) {
err = utils.Wrap(u.db(ctx).Where("user_id in (?)", userIDs).Find(&users).Error, "")
return users, err
}
// 获取某个用户信息 不存在,则返回错误
// 获取某个用户信息 不存在,则返回错误.
func (u *UserGorm) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) {
user = &relation.UserModel{}
err = utils.Wrap(u.db(ctx).Where("user_id = ?", userID).Take(&user).Error, "")
return user, err
}
// 获取用户信息 不存在,不返回错误
// 获取用户信息 不存在,不返回错误.
func (u *UserGorm) Page(
ctx context.Context,
pageNumber, showNumber int32,
@ -84,9 +84,8 @@ func (u *UserGorm) Page(
}
// 获取所有用户ID
func (u *UserGorm) GetAllUserID(ctx context.Context) (userIDs []string, err error) {
err = u.db(ctx).Pluck("user_id", &userIDs).Error
return userIDs, err
func (u *UserGorm) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) {
return userIDs, errs.Wrap(u.db(ctx).Limit(int(showNumber)).Offset(int((pageNumber-1)*showNumber)).Pluck("user_id", &userIDs).Error)
}
func (u *UserGorm) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) {

@ -20,13 +20,15 @@ import (
"encoding/hex"
"errors"
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
"github.com/google/uuid"
"path"
"strings"
"time"
"github.com/google/uuid"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/errs"
)
func New(impl s3.Interface) *Controller {

@ -16,6 +16,7 @@ package cont
import (
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
)

@ -18,14 +18,16 @@ import (
"context"
"errors"
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/tencentyun/cos-go-sdk-v5"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
)
const (

@ -18,16 +18,18 @@ import (
"context"
"errors"
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7/pkg/signer"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/minio/minio-go/v7/pkg/signer"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
)
const (

@ -18,14 +18,16 @@ import (
"context"
"errors"
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3"
)
const (
@ -146,7 +148,11 @@ func (o *OSS) AuthSign(ctx context.Context, uploadID string, name string, expire
}
request.Header.Set(oss.HTTPHeaderHost, request.Host)
request.Header.Set(oss.HTTPHeaderDate, time.Now().UTC().Format(http.TimeFormat))
authorization := fmt.Sprintf(`OSS %s:%s`, o.credentials.GetAccessKeyID(), o.getSignedStr(request, fmt.Sprintf(`/%s/%s?partNumber=%d&uploadId=%s`, o.bucket.BucketName, name, partNumber, uploadID), o.credentials.GetAccessKeySecret()))
authorization := fmt.Sprintf(
`OSS %s:%s`,
o.credentials.GetAccessKeyID(),
o.getSignedStr(request, fmt.Sprintf(`/%s/%s?partNumber=%d&uploadId=%s`, o.bucket.BucketName, name, partNumber, uploadID), o.credentials.GetAccessKeySecret()),
)
request.Header.Set(oss.HTTPHeaderAuthorization, authorization)
result.Parts[i] = s3.SignPart{
PartNumber: partNumber,

@ -19,12 +19,13 @@ import (
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"hash"
"io"
"net/http"
"sort"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func (o *OSS) getAdditionalHeaderKeys(req *http.Request) ([]string, map[string]string) {

@ -63,7 +63,7 @@ type UserModelInterface interface {
Take(ctx context.Context, userID string) (user *UserModel, err error)
// 获取用户信息 不存在,不返回错误
Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error)
GetAllUserID(ctx context.Context) (userIDs []string, err error)
GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error)
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
// 获取用户总数
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save