feat: incr sync version.

This commit is contained in:
Gordon
2024-06-24 17:48:33 +08:00
parent e8ccae6349
commit 88b8043224
308 changed files with 55952 additions and 59 deletions

View File

@@ -0,0 +1,53 @@
package open_im_sdk
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
"github.com/openimsdk/openim-sdk-core/v3/pkg/common"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"sync/atomic"
)
type apiErrCallback struct {
loginMgrCh chan common.Cmd2Value
listener open_im_sdk_callback.OnConnListener
tokenExpiredState int32
kickedOfflineState int32
tokenInvalidState int32
}
func (c *apiErrCallback) OnError(ctx context.Context, err error) {
if err == nil {
return
}
codeErr, ok := errs.Unwrap(err).(errs.CodeError)
if !ok {
log.ZError(ctx, "OnError callback not CodeError", err)
return
}
log.ZError(ctx, "OnError callback CodeError", err, "code", codeErr.Code(), "msg", codeErr.Msg(), "detail", codeErr.Detail())
switch codeErr.Code() {
case
errs.TokenExpiredError:
if atomic.CompareAndSwapInt32(&c.tokenExpiredState, 0, 1) {
log.ZError(ctx, "OnUserTokenExpired callback", err)
c.listener.OnUserTokenExpired()
_ = common.TriggerCmdLogOut(ctx, c.loginMgrCh)
}
case
errs.TokenMalformedError,
errs.TokenNotValidYetError,
errs.TokenUnknownError:
if atomic.CompareAndSwapInt32(&c.tokenInvalidState, 0, 1) {
log.ZError(ctx, "OnUserTokenInvalid callback", err)
c.listener.OnUserTokenInvalid(err.Error())
_ = common.TriggerCmdLogOut(ctx, c.loginMgrCh)
}
if atomic.CompareAndSwapInt32(&c.kickedOfflineState, 0, 1) {
log.ZError(ctx, "OnKickedOffline callback", err)
c.listener.OnKickedOffline()
_ = common.TriggerCmdLogOut(ctx, c.loginMgrCh)
}
}
}

View File

@@ -0,0 +1,484 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
"github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext"
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
"reflect"
"runtime"
"runtime/debug"
"time"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/errs"
)
func isNumeric(kind reflect.Kind) bool {
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
reflect.Float32, reflect.Float64:
return true
default:
return false
}
}
func setNumeric(in interface{}, out interface{}) {
inValue := reflect.ValueOf(in)
outValue := reflect.ValueOf(out)
outElem := outValue.Elem()
outType := outElem.Type()
inType := inValue.Type()
if outType.AssignableTo(inType) {
outElem.Set(inValue)
return
}
inKind := inValue.Kind()
outKind := outElem.Kind()
switch inKind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
switch outKind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
outElem.SetInt(inValue.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
outElem.SetUint(uint64(inValue.Int()))
case reflect.Float32, reflect.Float64:
outElem.SetFloat(float64(inValue.Int()))
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
switch outKind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
outElem.SetInt(int64(inValue.Uint()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
outElem.SetUint(inValue.Uint())
case reflect.Float32, reflect.Float64:
outElem.SetFloat(float64(inValue.Uint()))
}
case reflect.Float32, reflect.Float64:
switch outKind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
outElem.SetInt(int64(inValue.Float()))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
outElem.SetUint(uint64(inValue.Float()))
case reflect.Float32, reflect.Float64:
outElem.SetFloat(inValue.Float())
}
}
}
func call_(operationID string, fn any, args ...any) (res any, err error) {
t := time.Now()
funcPtr := reflect.ValueOf(fn).Pointer()
funcName := runtime.FuncForPC(funcPtr).Name()
if operationID == "" {
return nil, sdkerrs.ErrArgs.WrapMsg("call function operationID is empty")
}
if err := CheckResourceLoad(UserForSDK, funcName); err != nil {
return nil, sdkerrs.ErrResourceLoad.WrapMsg("not load resource")
}
ctx := ccontext.WithOperationID(UserForSDK.BaseCtx(), operationID)
defer func(start time.Time) {
if r := recover(); r != nil {
fmt.Printf("panic: %+v\n%s", r, debug.Stack())
err = fmt.Errorf("call panic: %+v", r)
} else {
elapsed := time.Since(start).Milliseconds()
if err == nil {
log.ZInfo(ctx, "fn call success", "function name", funcName, "resp", res, "cost time", fmt.Sprintf("%d ms", elapsed))
} else {
log.ZError(ctx, "fn call error", err, "function name", funcName, "cost time", fmt.Sprintf("%d ms", elapsed))
}
}
}(t)
log.ZInfo(ctx, "func call req", "function name", funcName, "args", args)
fnv := reflect.ValueOf(fn)
if fnv.Kind() != reflect.Func {
return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("call function fn is not function, is %T", fn))
}
fnt := fnv.Type()
nin := fnt.NumIn()
if len(args)+1 != nin {
return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go code error: fn in args num is not match"))
}
ins := make([]reflect.Value, 0, nin)
ins = append(ins, reflect.ValueOf(ctx))
for i := 0; i < len(args); i++ {
inFnField := fnt.In(i + 1)
arg := reflect.TypeOf(args[i])
if arg.String() == inFnField.String() || inFnField.Kind() == reflect.Interface {
ins = append(ins, reflect.ValueOf(args[i]))
continue
}
if arg.Kind() == reflect.String { // json
var ptr int
for inFnField.Kind() == reflect.Ptr {
inFnField = inFnField.Elem()
ptr++
}
switch inFnField.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map:
v := reflect.New(inFnField)
if err := json.Unmarshal([]byte(args[i].(string)), v.Interface()); err != nil {
return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go call json.Unmarshal error: %s", err))
}
if ptr == 0 {
v = v.Elem()
} else if ptr != 1 {
for i := ptr - 1; i > 0; i-- {
temp := reflect.New(v.Type())
temp.Elem().Set(v)
v = temp
}
}
ins = append(ins, v)
continue
}
}
//if isNumeric(arg.Kind()) && isNumeric(inFnField.Kind()) {
// v := reflect.Zero(inFnField).Interface()
// setNumeric(args[i], &v)
// ins = append(ins, reflect.ValueOf(v))
// continue
//}
return nil, sdkerrs.ErrSdkInternal.WrapMsg(fmt.Sprintf("go code error: fn in args type is not match"))
}
outs := fnv.Call(ins)
if len(outs) == 0 {
return "", nil
}
if fnt.Out(len(outs) - 1).Implements(reflect.ValueOf(new(error)).Elem().Type()) {
if errValueOf := outs[len(outs)-1]; !errValueOf.IsNil() {
return nil, errValueOf.Interface().(error)
}
if len(outs) == 1 {
return "", nil
}
outs = outs[:len(outs)-1]
}
for i := 0; i < len(outs); i++ {
out := outs[i]
switch out.Kind() {
case reflect.Map:
if out.IsNil() {
outs[i] = reflect.MakeMap(out.Type())
}
case reflect.Slice:
if out.IsNil() {
outs[i] = reflect.MakeSlice(out.Type(), 0, 0)
}
}
}
if len(outs) == 1 {
return outs[0].Interface(), nil
}
val := make([]any, 0, len(outs))
for i := range outs {
val = append(val, outs[i].Interface())
}
return val, nil
}
func call(callback open_im_sdk_callback.Base, operationID string, fn any, args ...any) {
if callback == nil {
log.ZWarn(context.Background(), "callback is nil", nil)
return
}
go func() {
res, err := call_(operationID, fn, args...)
if err != nil {
if code, ok := err.(errs.CodeError); ok {
callback.OnError(int32(code.Code()), code.Error())
} else {
callback.OnError(sdkerrs.UnknownCode, fmt.Sprintf("error %T not implement CodeError: %s", err, err))
}
return
}
data, err := json.Marshal(res)
if err != nil {
callback.OnError(sdkerrs.SdkInternalError, fmt.Sprintf("function res json.Marshal error: %s", err))
return
}
callback.OnSuccess(string(data))
}()
}
func syncCall(operationID string, fn any, args ...any) (res string) {
err := error(nil)
if operationID == "" {
return ""
}
fnv := reflect.ValueOf(fn)
if fnv.Kind() != reflect.Func {
err = errs.ErrRecordNotFound
return ""
}
funcPtr := reflect.ValueOf(fn).Pointer()
funcName := runtime.FuncForPC(funcPtr).Name()
if err = CheckResourceLoad(UserForSDK, funcName); err != nil {
return ""
}
fnt := fnv.Type()
numIn := fnt.NumIn()
if len(args)+1 != numIn {
err = errors.New("go code error: fn in args num is not match")
return ""
}
ins := make([]reflect.Value, 0, numIn)
ctx := ccontext.WithOperationID(UserForSDK.BaseCtx(), operationID)
t := time.Now()
defer func(start time.Time) {
if r := recover(); r != nil {
fmt.Printf("panic: %+v\n%s", r, debug.Stack())
} else {
elapsed := time.Since(start).Milliseconds()
if err == nil {
log.ZInfo(ctx, "fn call success", "function name", funcName, "resp", res, "cost time", fmt.Sprintf("%d ms", elapsed))
} else {
log.ZError(ctx, "fn call error", err, "function name", funcName, "cost time", fmt.Sprintf("%d ms", elapsed))
}
}
}(t)
log.ZInfo(ctx, "func call req", "function name", funcName, "args", args)
ins = append(ins, reflect.ValueOf(ctx))
for i := 0; i < len(args); i++ {
tag := fnt.In(i + 1)
arg := reflect.TypeOf(args[i])
if arg.String() == tag.String() || tag.Kind() == reflect.Interface {
ins = append(ins, reflect.ValueOf(args[i]))
continue
}
if arg.Kind() == reflect.String { // json
switch tag.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map, reflect.Ptr:
v := reflect.New(tag)
if args[i].(string) != "" {
if err = json.Unmarshal([]byte(args[i].(string)), v.Interface()); err != nil {
return ""
}
}
ins = append(ins, v.Elem())
continue
}
}
if isNumeric(arg.Kind()) && isNumeric(tag.Kind()) {
v := reflect.Zero(tag).Interface()
setNumeric(args[i], &v)
ins = append(ins, reflect.ValueOf(v))
continue
}
err = errors.New("err args type")
return ""
}
var lastErr bool
if numOut := fnt.NumOut(); numOut > 0 {
lastErr = fnt.Out(numOut - 1).Implements(reflect.TypeOf((*error)(nil)).Elem())
}
outs := fnv.Call(ins)
if len(outs) == 0 {
err = errors.New("err res type")
return ""
}
outVals := make([]any, 0, len(outs))
for i := 0; i < len(outs); i++ {
outVals = append(outVals, outs[i].Interface())
}
if lastErr {
if last := outVals[len(outVals)-1]; last != nil {
//callback.OnError(10000, last.(error).Error())
err = last.(error)
return ""
}
if len(outs) == 1 {
//callback.OnSuccess("") // 只有一个返回值为error且error == nil
return ""
}
outVals = outVals[:len(outVals)-1]
}
// 将map和slice的nil转换为非nil
for i := 0; i < len(outVals); i++ {
switch outs[i].Kind() {
case reflect.Map:
if outs[i].IsNil() {
outVals[i] = reflect.MakeMap(outs[i].Type()).Interface()
}
case reflect.Slice:
if outs[i].IsNil() {
outVals[i] = reflect.MakeSlice(outs[i].Type(), 0, 0).Interface()
}
}
}
var jsonVal any
if len(outVals) == 1 {
jsonVal = outVals[0]
} else {
jsonVal = outVals
}
jsonData, err := json.Marshal(jsonVal)
if err != nil {
err = errors.New("json marshal error")
return ""
}
return string(jsonData)
}
func messageCall(callback open_im_sdk_callback.SendMsgCallBack, operationID string, fn any, args ...any) {
if callback == nil {
log.ZWarn(context.Background(), "callback is nil", nil)
return
}
go messageCall_(callback, operationID, fn, args...)
}
func messageCall_(callback open_im_sdk_callback.SendMsgCallBack, operationID string, fn any, args ...any) {
defer func() {
if r := recover(); r != nil {
fmt.Println(" panic err:", r, string(debug.Stack()))
callback.OnError(sdkerrs.SdkInternalError, fmt.Sprintf("recover: %+v", r))
return
}
}()
if operationID == "" {
callback.OnError(sdkerrs.ArgsError, sdkerrs.ErrArgs.WrapMsg("operationID is empty").Error())
return
}
if err := CheckResourceLoad(UserForSDK, ""); err != nil {
callback.OnError(sdkerrs.ResourceLoadNotCompleteError, "resource load error: "+err.Error())
return
}
fnv := reflect.ValueOf(fn)
if fnv.Kind() != reflect.Func {
callback.OnError(sdkerrs.SdkInternalError, "go code error: fn is not function")
return
}
fnt := fnv.Type()
numIn := fnt.NumIn()
if len(args)+1 != numIn {
callback.OnError(sdkerrs.SdkInternalError, "go code error: fn in args num is not match")
return
}
t := time.Now()
ins := make([]reflect.Value, 0, numIn)
ctx := ccontext.WithOperationID(UserForSDK.BaseCtx(), operationID)
ctx = ccontext.WithSendMessageCallback(ctx, callback)
funcPtr := reflect.ValueOf(fn).Pointer()
funcName := runtime.FuncForPC(funcPtr).Name()
log.ZInfo(ctx, "input req", "function name", funcName, "args", args)
ins = append(ins, reflect.ValueOf(ctx))
for i := 0; i < len(args); i++ { // callback open_im_sdk_callback.Base, operationID string, ...
tag := fnt.In(i + 1) // ctx context.Context, ...
arg := reflect.TypeOf(args[i])
if arg.String() == tag.String() || tag.Kind() == reflect.Interface {
ins = append(ins, reflect.ValueOf(args[i]))
continue
}
if arg.Kind() == reflect.String { // json
switch tag.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Map, reflect.Ptr:
v := reflect.New(tag)
if err := json.Unmarshal([]byte(args[i].(string)), v.Interface()); err != nil {
callback.OnError(sdkerrs.ArgsError, err.Error())
return
}
ins = append(ins, v.Elem())
continue
}
}
if isNumeric(arg.Kind()) && isNumeric(tag.Kind()) {
v := reflect.Zero(tag).Interface()
setNumeric(args[i], &v)
ins = append(ins, reflect.ValueOf(v))
continue
}
callback.OnError(sdkerrs.ArgsError, "go code error: fn in args type is not match")
return
}
var lastErr bool
if numOut := fnt.NumOut(); numOut > 0 {
lastErr = fnt.Out(numOut - 1).Implements(reflect.ValueOf(new(error)).Elem().Type())
}
//fmt.Println("fnv:", fnv.Interface(), "ins:", ins)
outs := fnv.Call(ins)
outVals := make([]any, 0, len(outs))
for i := 0; i < len(outs); i++ {
outVals = append(outVals, outs[i].Interface())
}
if lastErr {
if last := outVals[len(outVals)-1]; last != nil {
if code, ok := last.(error).(errs.CodeError); ok {
callback.OnError(int32(code.Code()), code.Error())
} else {
callback.OnError(sdkerrs.UnknownCode, fmt.Sprintf("error %T not implement CodeError: %s", last.(error), last.(error).Error()))
}
return
}
outVals = outVals[:len(outVals)-1]
}
// 将map和slice的nil转换为非nil
for i := 0; i < len(outVals); i++ {
switch outs[i].Kind() {
case reflect.Map:
if outs[i].IsNil() {
outVals[i] = reflect.MakeMap(outs[i].Type()).Interface()
}
case reflect.Slice:
if outs[i].IsNil() {
outVals[i] = reflect.MakeSlice(outs[i].Type(), 0, 0).Interface()
}
}
}
var jsonVal any
if len(outVals) == 1 {
jsonVal = outVals[0]
} else {
jsonVal = outVals
}
jsonData, err := json.Marshal(jsonVal)
if err != nil {
callback.OnError(sdkerrs.ArgsError, err.Error())
return
}
log.ZInfo(ctx, "output resp", "function name", funcName, "resp", jsonVal, "cost time", time.Since(t))
callback.OnSuccess(string(jsonData))
}
func listenerCall(fn any, listener any) {
ctx := context.Background()
if UserForSDK == nil {
log.ZWarn(ctx, "UserForSDK is nil,set listener is invalid", nil)
return
}
fnv := reflect.ValueOf(fn)
if fnv.Kind() != reflect.Func {
log.ZWarn(ctx, "fn is error,set listener is invalid", nil)
return
}
args := reflect.ValueOf(listener)
fnv.Call([]reflect.Value{args})
}

View File

@@ -0,0 +1,251 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
)
func GetAllConversationList(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Conversation().GetAllConversationList)
}
func GetConversationListSplit(callback open_im_sdk_callback.Base, operationID string, offset int, count int) {
call(callback, operationID, UserForSDK.Conversation().GetConversationListSplit, offset, count)
}
func GetOneConversation(callback open_im_sdk_callback.Base, operationID string, sessionType int32, sourceID string) {
call(callback, operationID, UserForSDK.Conversation().GetOneConversation, sessionType, sourceID)
}
func GetMultipleConversation(callback open_im_sdk_callback.Base, operationID string, conversationIDList string) {
call(callback, operationID, UserForSDK.Conversation().GetMultipleConversation, conversationIDList)
}
func SetConversationMsgDestructTime(callback open_im_sdk_callback.Base, operationID string, conversationID string, msgDestructTime int64) {
call(callback, operationID, UserForSDK.Conversation().SetConversationMsgDestructTime, conversationID, msgDestructTime)
}
func SetConversationIsMsgDestruct(callback open_im_sdk_callback.Base, operationID string, conversationID string, isMsgDestruct bool) {
call(callback, operationID, UserForSDK.Conversation().SetConversationIsMsgDestruct, conversationID, isMsgDestruct)
}
func SetConversationEx(callback open_im_sdk_callback.Base, operationID string, conversationID string, ex string) {
call(callback, operationID, UserForSDK.Conversation().SetOneConversationEx, conversationID, ex)
}
func HideConversation(callback open_im_sdk_callback.Base, operationID string, conversationID string) {
call(callback, operationID, UserForSDK.Conversation().HideConversation, conversationID)
}
// deprecated
func GetConversationRecvMessageOpt(callback open_im_sdk_callback.Base, operationID string, conversationIDList string) {
call(callback, operationID, UserForSDK.Conversation().GetConversationRecvMessageOpt, conversationIDList)
}
func SetConversationDraft(callback open_im_sdk_callback.Base, operationID string, conversationID string, draftText string) {
call(callback, operationID, UserForSDK.Conversation().SetConversationDraft, conversationID, draftText)
}
func ResetConversationGroupAtType(callback open_im_sdk_callback.Base, operationID string, conversationID string) {
call(callback, operationID, UserForSDK.Conversation().ResetConversationGroupAtType, conversationID)
}
func PinConversation(callback open_im_sdk_callback.Base, operationID string, conversationID string, isPinned bool) {
call(callback, operationID, UserForSDK.Conversation().PinConversation, conversationID, isPinned)
}
func SetConversationPrivateChat(callback open_im_sdk_callback.Base, operationID string, conversationID string, isPrivate bool) {
call(callback, operationID, UserForSDK.Conversation().SetOneConversationPrivateChat, conversationID, isPrivate)
}
func SetConversationBurnDuration(callback open_im_sdk_callback.Base, operationID string, conversationID string, duration int32) {
call(callback, operationID, UserForSDK.Conversation().SetOneConversationBurnDuration, conversationID, duration)
}
func SetConversationRecvMessageOpt(callback open_im_sdk_callback.Base, operationID string, conversationID string, opt int) {
call(callback, operationID, UserForSDK.Conversation().SetOneConversationRecvMessageOpt, conversationID, opt)
}
func GetTotalUnreadMsgCount(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Conversation().GetTotalUnreadMsgCount)
}
func GetAtAllTag(operationID string) string {
return syncCall(operationID, UserForSDK.Conversation().GetAtAllTag)
}
func CreateAdvancedTextMessage(operationID string, text, messageEntityList string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateAdvancedTextMessage, text, messageEntityList)
}
func CreateTextAtMessage(operationID string, text, atUserList, atUsersInfo, message string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateTextAtMessage, text, atUserList, atUsersInfo, message)
}
func CreateTextMessage(operationID string, text string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateTextMessage, text)
}
func CreateLocationMessage(operationID string, description string, longitude, latitude float64) string {
return syncCall(operationID, UserForSDK.Conversation().CreateLocationMessage, description, longitude, latitude)
}
func CreateCustomMessage(operationID string, data, extension string, description string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateCustomMessage, data, extension, description)
}
func CreateQuoteMessage(operationID string, text string, message string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateQuoteMessage, text, message)
}
func CreateAdvancedQuoteMessage(operationID string, text string, message, messageEntityList string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateAdvancedQuoteMessage, text, message, messageEntityList)
}
func CreateCardMessage(operationID string, cardInfo string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateCardMessage, cardInfo)
}
func CreateVideoMessageFromFullPath(operationID string, videoFullPath string, videoType string, duration int64, snapshotFullPath string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateVideoMessageFromFullPath, videoFullPath, videoType, duration, snapshotFullPath)
}
func CreateImageMessageFromFullPath(operationID string, imageFullPath string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateImageMessageFromFullPath, imageFullPath)
}
func CreateSoundMessageFromFullPath(operationID string, soundPath string, duration int64) string {
return syncCall(operationID, UserForSDK.Conversation().CreateSoundMessageFromFullPath, soundPath, duration)
}
func CreateFileMessageFromFullPath(operationID string, fileFullPath, fileName string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateFileMessageFromFullPath, fileFullPath, fileName)
}
func CreateImageMessage(operationID string, imagePath string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateImageMessage, imagePath)
}
func CreateImageMessageByURL(operationID string, sourcePath string, sourcePicture, bigPicture, snapshotPicture string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateImageMessageByURL, sourcePath, sourcePicture, bigPicture, snapshotPicture)
}
func CreateSoundMessageByURL(operationID string, soundBaseInfo string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateSoundMessageByURL, soundBaseInfo)
}
func CreateSoundMessage(operationID string, soundPath string, duration int64) string {
return syncCall(operationID, UserForSDK.Conversation().CreateSoundMessage, soundPath, duration)
}
func CreateVideoMessageByURL(operationID string, videoBaseInfo string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateVideoMessageByURL, videoBaseInfo)
}
func CreateVideoMessage(operationID string, videoPath string, videoType string, duration int64, snapshotPath string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateVideoMessage, videoPath, videoType, duration, snapshotPath)
}
func CreateFileMessageByURL(operationID string, fileBaseInfo string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateFileMessageByURL, fileBaseInfo)
}
func CreateFileMessage(operationID string, filePath string, fileName string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateFileMessage, filePath, fileName)
}
func CreateMergerMessage(operationID string, messageList, title, summaryList string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateMergerMessage, messageList, title, summaryList)
}
func CreateFaceMessage(operationID string, index int, data string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateFaceMessage, index, data)
}
func CreateForwardMessage(operationID string, m string) string {
return syncCall(operationID, UserForSDK.Conversation().CreateForwardMessage, m)
}
func GetConversationIDBySessionType(operationID string, sourceID string, sessionType int) string {
return syncCall(operationID, UserForSDK.Conversation().GetConversationIDBySessionType, sourceID, sessionType)
}
func SendMessage(callback open_im_sdk_callback.SendMsgCallBack, operationID, message, recvID, groupID, offlinePushInfo string, isOnlineOnly bool) {
messageCall(callback, operationID, UserForSDK.Conversation().SendMessage, message, recvID, groupID, offlinePushInfo, isOnlineOnly)
}
func SendMessageNotOss(callback open_im_sdk_callback.SendMsgCallBack, operationID string, message, recvID, groupID string, offlinePushInfo string, isOnlineOnly bool) {
messageCall(callback, operationID, UserForSDK.Conversation().SendMessageNotOss, message, recvID, groupID, offlinePushInfo, isOnlineOnly)
}
func FindMessageList(callback open_im_sdk_callback.Base, operationID string, findMessageOptions string) {
call(callback, operationID, UserForSDK.Conversation().FindMessageList, findMessageOptions)
}
func GetAdvancedHistoryMessageList(callback open_im_sdk_callback.Base, operationID string, getMessageOptions string) {
call(callback, operationID, UserForSDK.Conversation().GetAdvancedHistoryMessageList, getMessageOptions)
}
func GetAdvancedHistoryMessageListReverse(callback open_im_sdk_callback.Base, operationID string, getMessageOptions string) {
call(callback, operationID, UserForSDK.Conversation().GetAdvancedHistoryMessageListReverse, getMessageOptions)
}
func RevokeMessage(callback open_im_sdk_callback.Base, operationID string, conversationID, clientMsgID string) {
call(callback, operationID, UserForSDK.Conversation().RevokeMessage, conversationID, clientMsgID)
}
func TypingStatusUpdate(callback open_im_sdk_callback.Base, operationID string, recvID string, msgTip string) {
call(callback, operationID, UserForSDK.Conversation().TypingStatusUpdate, recvID, msgTip)
}
// mark as read
func MarkConversationMessageAsRead(callback open_im_sdk_callback.Base, operationID string, conversationID string) {
call(callback, operationID, UserForSDK.Conversation().MarkConversationMessageAsRead, conversationID)
}
func MarkMessagesAsReadByMsgID(callback open_im_sdk_callback.Base, operationID string, conversationID string, clientMsgIDs string) {
call(callback, operationID, UserForSDK.Conversation().MarkMessagesAsReadByMsgID, conversationID, clientMsgIDs)
}
func DeleteMessageFromLocalStorage(callback open_im_sdk_callback.Base, operationID string, conversationID string, clientMsgID string) {
call(callback, operationID, UserForSDK.Conversation().DeleteMessageFromLocalStorage, conversationID, clientMsgID)
}
func DeleteMessage(callback open_im_sdk_callback.Base, operationID string, conversationID string, clientMsgID string) {
call(callback, operationID, UserForSDK.Conversation().DeleteMessage, conversationID, clientMsgID)
}
func HideAllConversations(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Conversation().HideAllConversations)
}
func DeleteAllMsgFromLocalAndSvr(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Conversation().DeleteAllMsgFromLocalAndSvr)
}
func DeleteAllMsgFromLocal(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Conversation().DeleteAllMessageFromLocalStorage)
}
func ClearConversationAndDeleteAllMsg(callback open_im_sdk_callback.Base, operationID string, conversationID string) {
call(callback, operationID, UserForSDK.Conversation().ClearConversationAndDeleteAllMsg, conversationID)
}
func DeleteConversationAndDeleteAllMsg(callback open_im_sdk_callback.Base, operationID string, conversationID string) {
call(callback, operationID, UserForSDK.Conversation().DeleteConversationAndDeleteAllMsg, conversationID)
}
func InsertSingleMessageToLocalStorage(callback open_im_sdk_callback.Base, operationID string, message string, recvID string, sendID string) {
call(callback, operationID, UserForSDK.Conversation().InsertSingleMessageToLocalStorage, message, recvID, sendID)
}
func InsertGroupMessageToLocalStorage(callback open_im_sdk_callback.Base, operationID string, message string, groupID string, sendID string) {
call(callback, operationID, UserForSDK.Conversation().InsertGroupMessageToLocalStorage, message, groupID, sendID)
}
func SearchLocalMessages(callback open_im_sdk_callback.Base, operationID string, searchParam string) {
call(callback, operationID, UserForSDK.Conversation().SearchLocalMessages, searchParam)
}
func SetMessageLocalEx(callback open_im_sdk_callback.Base, operationID string, conversationID, clientMsgID, localEx string) {
call(callback, operationID, UserForSDK.Conversation().SetMessageLocalEx, conversationID, clientMsgID, localEx)
}
func SearchConversation(callback open_im_sdk_callback.Base, operationID string, searchParam string) {
call(callback, operationID, UserForSDK.Conversation().SearchConversation, searchParam)
}
func ChangeInputStates(callback open_im_sdk_callback.Base, operationID string, conversationID string, focus bool) {
call(callback, operationID, UserForSDK.Conversation().ChangeInputStates, conversationID, focus)
}
func GetInputStates(callback open_im_sdk_callback.Base, operationID string, conversationID string, userID string) {
call(callback, operationID, UserForSDK.Conversation().GetInputStates, conversationID, userID)
}

View File

@@ -0,0 +1,289 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
"github.com/openimsdk/tools/log"
)
var ErrNotImplemented = errors.New("not set listener")
type emptyGroupListener struct {
ctx context.Context
}
func newEmptyGroupListener(ctx context.Context) open_im_sdk_callback.OnGroupListener {
return &emptyGroupListener{ctx}
}
func (e *emptyGroupListener) OnJoinedGroupAdded(groupInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupInfo", groupInfo)
}
func (e *emptyGroupListener) OnJoinedGroupDeleted(groupInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupInfo", groupInfo)
}
func (e *emptyGroupListener) OnGroupMemberAdded(groupMemberInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupMemberInfo", groupMemberInfo)
}
func (e *emptyGroupListener) OnGroupMemberDeleted(groupMemberInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupMemberInfo", groupMemberInfo)
}
func (e *emptyGroupListener) OnGroupApplicationAdded(groupApplication string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupApplication", groupApplication)
}
func (e *emptyGroupListener) OnGroupApplicationDeleted(groupApplication string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupApplication", groupApplication)
}
func (e *emptyGroupListener) OnGroupInfoChanged(groupInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupInfo", groupInfo)
}
func (e *emptyGroupListener) OnGroupDismissed(groupInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupInfo", groupInfo)
}
func (e *emptyGroupListener) OnGroupMemberInfoChanged(groupMemberInfo string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupMemberInfo", groupMemberInfo)
}
func (e *emptyGroupListener) OnGroupApplicationAccepted(groupApplication string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupApplication", groupApplication)
}
func (e *emptyGroupListener) OnGroupApplicationRejected(groupApplication string) {
log.ZWarn(e.ctx, "GroupListener is not implemented", nil, "groupApplication", groupApplication)
}
type emptyFriendshipListener struct {
ctx context.Context
}
func newEmptyFriendshipListener(ctx context.Context) open_im_sdk_callback.OnFriendshipListener {
return &emptyFriendshipListener{ctx}
}
func (e *emptyFriendshipListener) OnFriendApplicationAdded(friendApplication string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendApplication", friendApplication)
}
func (e *emptyFriendshipListener) OnFriendApplicationDeleted(friendApplication string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendApplication", friendApplication)
}
func (e *emptyFriendshipListener) OnFriendApplicationAccepted(friendApplication string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendApplication", friendApplication)
}
func (e *emptyFriendshipListener) OnFriendApplicationRejected(friendApplication string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendApplication", friendApplication)
}
func (e *emptyFriendshipListener) OnFriendAdded(friendInfo string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendInfo", friendInfo)
}
func (e *emptyFriendshipListener) OnFriendDeleted(friendInfo string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendInfo", friendInfo)
}
func (e *emptyFriendshipListener) OnFriendInfoChanged(friendInfo string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"friendInfo", friendInfo)
}
func (e *emptyFriendshipListener) OnBlackAdded(blackInfo string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"blackInfo", blackInfo)
}
func (e *emptyFriendshipListener) OnBlackDeleted(blackInfo string) {
log.ZWarn(e.ctx, "FriendshipListener is not implemented", nil,
"blackInfo", blackInfo)
}
type emptyConversationListener struct {
ctx context.Context
}
func newEmptyConversationListener(ctx context.Context) open_im_sdk_callback.OnConversationListener {
return &emptyConversationListener{ctx: ctx}
}
func (e *emptyConversationListener) OnSyncServerStart() {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil)
}
func (e *emptyConversationListener) OnSyncServerFinish() {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil)
}
func (e *emptyConversationListener) OnSyncServerFailed() {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil)
}
func (e *emptyConversationListener) OnNewConversation(conversationList string) {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil,
"conversationList", conversationList)
}
func (e *emptyConversationListener) OnConversationChanged(conversationList string) {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil,
"conversationList", conversationList)
}
func (e *emptyConversationListener) OnTotalUnreadMessageCountChanged(totalUnreadCount int32) {
log.ZWarn(e.ctx, "ConversationListener is not implemented", nil,
"totalUnreadCount", totalUnreadCount)
}
func (e *emptyConversationListener) OnConversationUserInputStatusChanged(change string) {
}
type emptyAdvancedMsgListener struct {
ctx context.Context
}
func newEmptyAdvancedMsgListener(ctx context.Context) open_im_sdk_callback.OnAdvancedMsgListener {
return &emptyAdvancedMsgListener{ctx}
}
func (e *emptyAdvancedMsgListener) OnRecvOnlineOnlyMessage(message string) {
}
func (e *emptyAdvancedMsgListener) OnRecvNewMessage(message string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "message", message)
}
func (e *emptyAdvancedMsgListener) OnRecvC2CReadReceipt(msgReceiptList string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil,
"msgReceiptList", msgReceiptList)
}
func (e *emptyAdvancedMsgListener) OnRecvGroupReadReceipt(groupMsgReceiptList string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil,
"groupMsgReceiptList", groupMsgReceiptList)
}
func (e *emptyAdvancedMsgListener) OnNewRecvMessageRevoked(messageRevoked string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "messageRevoked", messageRevoked)
}
func (e *emptyAdvancedMsgListener) OnRecvMessageExtensionsChanged(msgID string, reactionExtensionList string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "msgID", msgID,
"reactionExtensionList", reactionExtensionList)
}
func (e *emptyAdvancedMsgListener) OnRecvMessageExtensionsDeleted(msgID string, reactionExtensionKeyList string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "msgID", msgID,
"reactionExtensionKeyList", reactionExtensionKeyList)
}
func (e *emptyAdvancedMsgListener) OnRecvMessageExtensionsAdded(msgID string, reactionExtensionList string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "msgID", msgID,
"reactionExtensionList", reactionExtensionList)
}
func (e *emptyAdvancedMsgListener) OnRecvOfflineNewMessage(message string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "message", message)
}
func (e *emptyAdvancedMsgListener) OnMsgDeleted(message string) {
log.ZWarn(e.ctx, "AdvancedMsgListener is not implemented", nil, "message", message)
}
type emptyBatchMsgListener struct{}
func newEmptyBatchMsgListener() *emptyBatchMsgListener {
return &emptyBatchMsgListener{}
}
func (e *emptyBatchMsgListener) OnRecvNewMessages(messageList string) {
}
func (e *emptyBatchMsgListener) OnRecvOfflineNewMessages(messageList string) {
}
type emptyUserListener struct {
ctx context.Context
}
func (e *emptyUserListener) OnUserCommandAdd(userCommand string) {
log.ZWarn(e.ctx, "UserListener is not implemented", nil, "userCommand", userCommand)
}
func (e *emptyUserListener) OnUserCommandDelete(userCommand string) {
log.ZWarn(e.ctx, "UserListener is not implemented", nil, "userCommand", userCommand)
}
func (e *emptyUserListener) OnUserCommandUpdate(userCommand string) {
log.ZWarn(e.ctx, "UserListener is not implemented", nil, "userCommand", userCommand)
}
func newEmptyUserListener(ctx context.Context) open_im_sdk_callback.OnUserListener {
return &emptyUserListener{ctx: ctx}
}
func (e *emptyUserListener) OnSelfInfoUpdated(userInfo string) {
log.ZWarn(e.ctx, "UserListener is not implemented", nil, "userInfo", userInfo)
}
func (e *emptyUserListener) OnUserStatusChanged(statusMap string) {
log.ZWarn(e.ctx, "UserListener is not implemented", nil, "statusMap", statusMap)
}
type emptyCustomBusinessListener struct {
ctx context.Context
}
func newEmptyCustomBusinessListener(ctx context.Context) open_im_sdk_callback.OnCustomBusinessListener {
return &emptyCustomBusinessListener{ctx: ctx}
}
func (e *emptyCustomBusinessListener) OnRecvCustomBusinessMessage(businessMessage string) {
log.ZWarn(e.ctx, "CustomBusinessListener is not implemented", nil,
"businessMessage", businessMessage)
}

View File

@@ -0,0 +1,24 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"github.com/openimsdk/openim-sdk-core/v3/internal/file"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
)
func UploadFile(callback open_im_sdk_callback.Base, operationID string, req string, progress open_im_sdk_callback.UploadFileCallback) {
call(callback, operationID, UserForSDK.File().UploadFile, req, file.UploadFileCallback(progress))
}

View File

@@ -0,0 +1,82 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
func GetSpecifiedFriendsInfo(callback open_im_sdk_callback.Base, operationID string, userIDList string) {
call(callback, operationID, UserForSDK.Friend().GetSpecifiedFriendsInfo, userIDList)
}
func GetFriendList(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Friend().GetFriendList)
}
func GetFriendListPage(callback open_im_sdk_callback.Base, operationID string, offset int32, count int32) {
call(callback, operationID, UserForSDK.Friend().GetFriendListPage, offset, count)
}
func SearchFriends(callback open_im_sdk_callback.Base, operationID string, searchParam string) {
call(callback, operationID, UserForSDK.Friend().SearchFriends, searchParam)
}
func CheckFriend(callback open_im_sdk_callback.Base, operationID string, userIDList string) {
call(callback, operationID, UserForSDK.Friend().CheckFriend, userIDList)
}
func AddFriend(callback open_im_sdk_callback.Base, operationID string, userIDReqMsg string) {
call(callback, operationID, UserForSDK.Friend().AddFriend, userIDReqMsg)
}
func SetFriendRemark(callback open_im_sdk_callback.Base, operationID string, userIDRemark string) {
call(callback, operationID, UserForSDK.Friend().SetFriendRemark, userIDRemark)
}
func PinFriends(callback open_im_sdk_callback.Base, operationID string, pinFriendsParams string) {
call(callback, operationID, UserForSDK.Friend().PinFriends, pinFriendsParams)
}
func DeleteFriend(callback open_im_sdk_callback.Base, operationID string, friendUserID string) {
call(callback, operationID, UserForSDK.Friend().DeleteFriend, friendUserID)
}
func GetFriendApplicationListAsRecipient(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Friend().GetFriendApplicationListAsRecipient)
}
func GetFriendApplicationListAsApplicant(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Friend().GetFriendApplicationListAsApplicant)
}
func AcceptFriendApplication(callback open_im_sdk_callback.Base, operationID string, userIDHandleMsg string) {
call(callback, operationID, UserForSDK.Friend().AcceptFriendApplication, userIDHandleMsg)
}
func RefuseFriendApplication(callback open_im_sdk_callback.Base, operationID string, userIDHandleMsg string) {
call(callback, operationID, UserForSDK.Friend().RefuseFriendApplication, userIDHandleMsg)
}
func AddBlack(callback open_im_sdk_callback.Base, operationID string, blackUserID string, ex string) {
call(callback, operationID, UserForSDK.Friend().AddBlack, blackUserID, ex)
}
func GetBlackList(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Friend().GetBlackList)
}
func RemoveBlack(callback open_im_sdk_callback.Base, operationID string, removeUserID string) {
call(callback, operationID, UserForSDK.Friend().RemoveBlack, removeUserID)
}
func SetFriendsEx(callback open_im_sdk_callback.Base, operationID string, friendIDs string, ex string) {
call(callback, operationID, UserForSDK.Friend().SetFriendsEx, friendIDs, ex)
}

View File

@@ -0,0 +1,141 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import "github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
//funcation CreateGroup(callback open_im_sdk_callback.Base, operationID string, groupBaseInfo string, memberList string) {
// call(callback, operationID, UserForSDK.Group().CreateGroup, groupBaseInfo, memberList)
//}
func CreateGroup(callback open_im_sdk_callback.Base, operationID string, groupReqInfo string) {
call(callback, operationID, UserForSDK.Group().CreateGroup, groupReqInfo)
}
func JoinGroup(callback open_im_sdk_callback.Base, operationID string, groupID string, reqMsg string, joinSource int32, ex string) {
call(callback, operationID, UserForSDK.Group().JoinGroup, groupID, reqMsg, joinSource, ex)
}
func QuitGroup(callback open_im_sdk_callback.Base, operationID string, groupID string) {
call(callback, operationID, UserForSDK.Group().QuitGroup, groupID)
}
func DismissGroup(callback open_im_sdk_callback.Base, operationID string, groupID string) {
call(callback, operationID, UserForSDK.Group().DismissGroup, groupID)
}
func SetGroupVerification(callback open_im_sdk_callback.Base, operationID string, groupID string, verification int32) {
call(callback, operationID, UserForSDK.Group().SetGroupVerification, groupID, verification)
}
func SetGroupApplyMemberFriend(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) {
call(callback, operationID, UserForSDK.Group().SetGroupApplyMemberFriend, groupID, rule)
}
func SetGroupLookMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, rule int32) {
call(callback, operationID, UserForSDK.Group().SetGroupLookMemberInfo, groupID, rule)
}
func ChangeGroupMute(callback open_im_sdk_callback.Base, operationID string, groupID string, isMute bool) {
call(callback, operationID, UserForSDK.Group().ChangeGroupMute, groupID, isMute)
}
func ChangeGroupMemberMute(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, mutedSeconds int) {
call(callback, operationID, UserForSDK.Group().ChangeGroupMemberMute, groupID, userID, mutedSeconds)
}
func TransferGroupOwner(callback open_im_sdk_callback.Base, operationID string, groupID string, newOwnerUserID string) {
call(callback, operationID, UserForSDK.Group().TransferGroupOwner, groupID, newOwnerUserID)
}
func KickGroupMember(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) {
call(callback, operationID, UserForSDK.Group().KickGroupMember, groupID, reason, userIDList)
}
func SetGroupInfo(callback open_im_sdk_callback.Base, operationID string, groupInfo string) {
call(callback, operationID, UserForSDK.Group().SetGroupInfo, groupInfo)
}
func SetGroupMemberInfo(callback open_im_sdk_callback.Base, operationID string, groupMemberInfo string) {
call(callback, operationID, UserForSDK.Group().SetGroupMemberInfo, groupMemberInfo)
}
func SetGroupMemberRoleLevel(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, roleLevel int) {
call(callback, operationID, UserForSDK.Group().SetGroupMemberRoleLevel, groupID, userID, roleLevel)
}
func SetGroupMemberNickname(callback open_im_sdk_callback.Base, operationID string, groupID string, userID string, groupMemberNickname string) {
call(callback, operationID, UserForSDK.Group().SetGroupMemberNickname, groupID, userID, groupMemberNickname)
}
func GetJoinedGroupList(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Group().GetJoinedGroupList)
}
func GetJoinedGroupListPage(callback open_im_sdk_callback.Base, operationID string, offset, count int32) {
call(callback, operationID, UserForSDK.Group().GetJoinedGroupListPage, offset, count)
}
func GetSpecifiedGroupsInfo(callback open_im_sdk_callback.Base, operationID string, groupIDList string) {
call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupsInfo, groupIDList)
}
func SearchGroups(callback open_im_sdk_callback.Base, operationID string, searchParam string) {
call(callback, operationID, UserForSDK.Group().SearchGroups, searchParam)
}
func GetGroupMemberOwnerAndAdmin(callback open_im_sdk_callback.Base, operationID string, groupID string) {
call(callback, operationID, UserForSDK.Group().GetGroupMemberOwnerAndAdmin, groupID)
}
func GetGroupMemberListByJoinTimeFilter(callback open_im_sdk_callback.Base, operationID string, groupID string, offset int32, count int32, joinTimeBegin int64, joinTimeEnd int64, filterUserIDList string) {
call(callback, operationID, UserForSDK.Group().GetGroupMemberListByJoinTimeFilter, groupID, offset, count, joinTimeBegin, joinTimeEnd, filterUserIDList)
}
func GetSpecifiedGroupMembersInfo(callback open_im_sdk_callback.Base, operationID string, groupID string, userIDList string) {
call(callback, operationID, UserForSDK.Group().GetSpecifiedGroupMembersInfo, groupID, userIDList)
}
func GetGroupMemberList(callback open_im_sdk_callback.Base, operationID string, groupID string, filter int32, offset int32, count int32) {
call(callback, operationID, UserForSDK.Group().GetGroupMemberList, groupID, filter, offset, count)
}
func GetGroupApplicationListAsRecipient(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Group().GetGroupApplicationListAsRecipient)
}
func GetGroupApplicationListAsApplicant(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Group().GetGroupApplicationListAsApplicant)
}
func SearchGroupMembers(callback open_im_sdk_callback.Base, operationID string, searchParam string) {
call(callback, operationID, UserForSDK.Group().SearchGroupMembers, searchParam)
}
func IsJoinGroup(callback open_im_sdk_callback.Base, operationID string, groupID string) {
call(callback, operationID, UserForSDK.Group().IsJoinGroup, groupID)
}
func InviteUserToGroup(callback open_im_sdk_callback.Base, operationID string, groupID string, reason string, userIDList string) {
call(callback, operationID, UserForSDK.Group().InviteUserToGroup, groupID, reason, userIDList)
}
func AcceptGroupApplication(callback open_im_sdk_callback.Base, operationID string, groupID string, fromUserID string, handleMsg string) {
call(callback, operationID, UserForSDK.Group().AcceptGroupApplication, groupID, fromUserID, handleMsg)
}
func RefuseGroupApplication(callback open_im_sdk_callback.Base, operationID string, groupID string, fromUserID string, handleMsg string) {
call(callback, operationID, UserForSDK.Group().RefuseGroupApplication, groupID, fromUserID, handleMsg)
}

View File

@@ -0,0 +1,136 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"context"
"encoding/json"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
"github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
"go.etcd.io/etcd/api/v3/version"
"strings"
"github.com/openimsdk/tools/log"
"github.com/openimsdk/tools/mcontext"
)
func GetSdkVersion() string {
return constant.GetSdkVersion()
}
const (
rotateCount uint = 0
rotationTime uint = 24
)
func SetHeartbeatInterval(heartbeatInterval int) {
constant.HeartbeatInterval = heartbeatInterval
}
func InitSDK(listener open_im_sdk_callback.OnConnListener, operationID string, config string) bool {
if UserForSDK != nil {
fmt.Println(operationID, "Initialize multiple times, use the existing ", UserForSDK, " Previous configuration ", UserForSDK.ImConfig(), " now configuration: ", config)
return true
}
var configArgs sdk_struct.IMConfig
if err := json.Unmarshal([]byte(config), &configArgs); err != nil {
fmt.Println(operationID, "Unmarshal failed ", err.Error(), config)
return false
}
if configArgs.PlatformID == 0 {
return false
}
if err := log.InitFromConfig("open-im-sdk-core", "", int(configArgs.LogLevel), configArgs.IsLogStandardOutput, false, configArgs.LogFilePath, rotateCount, rotationTime, version.Version); err != nil {
fmt.Println(operationID, "log init failed ", err.Error())
}
fmt.Println("init log success")
// localLog.NewPrivateLog("", configArgs.LogLevel)
ctx := mcontext.NewCtx(operationID)
if !strings.Contains(configArgs.ApiAddr, "http") {
log.ZError(ctx, "api is http protocol, api format is invalid", nil)
return false
}
if !strings.Contains(configArgs.WsAddr, "ws") {
log.ZError(ctx, "ws is ws protocol, ws format is invalid", nil)
return false
}
log.ZInfo(ctx, "InitSDK info", "config", configArgs, "sdkVersion", GetSdkVersion())
if listener == nil || config == "" {
log.ZError(ctx, "listener or config is nil", nil)
return false
}
UserForSDK = new(LoginMgr)
return UserForSDK.InitSDK(configArgs, listener)
}
func UnInitSDK(operationID string) {
if UserForSDK == nil {
fmt.Println(operationID, "UserForSDK is nil,")
return
}
UserForSDK.UnInitSDK()
UserForSDK = nil
}
func Login(callback open_im_sdk_callback.Base, operationID string, userID, token string) {
call(callback, operationID, UserForSDK.Login, userID, token)
}
func Logout(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.Logout)
}
func SetAppBackgroundStatus(callback open_im_sdk_callback.Base, operationID string, isBackground bool) {
call(callback, operationID, UserForSDK.SetAppBackgroundStatus, isBackground)
}
func NetworkStatusChanged(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.NetworkStatusChanged)
}
func GetLoginStatus(operationID string) int {
if UserForSDK == nil {
return constant.Uninitialized
}
return UserForSDK.GetLoginStatus(ccontext.WithOperationID(context.Background(), operationID))
}
func GetLoginUserID() string {
if UserForSDK == nil {
return ""
}
return UserForSDK.GetLoginUserID()
}
func (u *LoginMgr) Login(ctx context.Context, userID, token string) error {
return u.login(ctx, userID, token)
}
func (u *LoginMgr) Logout(ctx context.Context) error {
return u.logout(ctx, false)
}
func (u *LoginMgr) SetAppBackgroundStatus(ctx context.Context, isBackground bool) error {
return u.setAppBackgroundStatus(ctx, isBackground)
}
func (u *LoginMgr) NetworkStatusChanged(ctx context.Context) {
u.longConnMgr.Close(ctx)
}
func (u *LoginMgr) GetLoginStatus(ctx context.Context) int {
return u.getLoginStatus(ctx)
}

View File

@@ -0,0 +1,52 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
)
func SetGroupListener(listener open_im_sdk_callback.OnGroupListener) {
listenerCall(UserForSDK.SetGroupListener, listener)
}
func SetConversationListener(listener open_im_sdk_callback.OnConversationListener) {
listenerCall(UserForSDK.SetConversationListener, listener)
}
func SetAdvancedMsgListener(listener open_im_sdk_callback.OnAdvancedMsgListener) {
listenerCall(UserForSDK.SetAdvancedMsgListener, listener)
}
func SetBatchMsgListener(listener open_im_sdk_callback.OnBatchMsgListener) {
listenerCall(UserForSDK.SetBatchMsgListener, listener)
}
func SetUserListener(listener open_im_sdk_callback.OnUserListener) {
listenerCall(UserForSDK.SetUserListener, listener)
}
func SetFriendListener(listener open_im_sdk_callback.OnFriendshipListener) {
listenerCall(UserForSDK.SetFriendListener, listener)
}
func SetCustomBusinessListener(listener open_im_sdk_callback.OnCustomBusinessListener) {
listenerCall(UserForSDK.SetCustomBusinessListener, listener)
}
func SetMessageKvInfoListener(listener open_im_sdk_callback.OnMessageKvInfoListener) {
listenerCall(UserForSDK.SetMessageKvInfoListener, listener)
}

View File

@@ -0,0 +1,32 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"github.com/openimsdk/openim-sdk-core/v3/internal/third"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
)
func UpdateFcmToken(callback open_im_sdk_callback.Base, operationID, fcmToken string, expireTime int64) {
call(callback, operationID, UserForSDK.Third().UpdateFcmToken, fcmToken, expireTime)
}
func SetAppBadge(callback open_im_sdk_callback.Base, operationID string, appUnreadCount int32) {
call(callback, operationID, UserForSDK.Third().SetAppBadge, appUnreadCount)
}
func UploadLogs(callback open_im_sdk_callback.Base, operationID string, progress open_im_sdk_callback.UploadLogProgress) {
call(callback, operationID, UserForSDK.Third().UploadLogs, third.Progress(progress))
}

View File

@@ -0,0 +1,91 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
)
func GetUsersInfo(callback open_im_sdk_callback.Base, operationID string, userIDs string) {
call(callback, operationID, UserForSDK.Full().GetUsersInfo, userIDs)
}
func GetUsersInfoWithCache(callback open_im_sdk_callback.Base, operationID string, userIDs, groupID string) {
call(callback, operationID, UserForSDK.Full().GetUsersInfoWithCache, userIDs, groupID)
}
// GetUsersInfoFromSrv obtains the information about multiple users.
func GetUsersInfoFromSrv(callback open_im_sdk_callback.Base, operationID string, userIDs string) {
call(callback, operationID, UserForSDK.User().GetUsersInfo, userIDs)
}
// SetSelfInfo sets the user's own information.
// Deprecated: user SetSelfInfoEx instead
func SetSelfInfo(callback open_im_sdk_callback.Base, operationID string, userInfo string) {
call(callback, operationID, UserForSDK.User().SetSelfInfo, userInfo)
}
// SetSelfInfoEx sets the user's own information with Ex field.
func SetSelfInfoEx(callback open_im_sdk_callback.Base, operationID string, userInfo string) {
call(callback, operationID, UserForSDK.User().SetSelfInfoEx, userInfo)
}
func SetGlobalRecvMessageOpt(callback open_im_sdk_callback.Base, operationID string, opt int) {
call(callback, operationID, UserForSDK.User().SetGlobalRecvMessageOpt, opt)
}
// GetSelfUserInfo obtains the user's own information.
func GetSelfUserInfo(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.User().GetSelfUserInfo)
}
// UpdateMsgSenderInfo updates the message sender's nickname and face URL.
func UpdateMsgSenderInfo(callback open_im_sdk_callback.Base, operationID string, nickname, faceURL string) {
call(callback, operationID, UserForSDK.User().UpdateMsgSenderInfo, nickname, faceURL)
}
// SubscribeUsersStatus Presence status of subscribed users.
func SubscribeUsersStatus(callback open_im_sdk_callback.Base, operationID string, userIDs string) {
call(callback, operationID, UserForSDK.User().SubscribeUsersStatus, userIDs)
}
// UnsubscribeUsersStatus Unsubscribe a user's presence.
func UnsubscribeUsersStatus(callback open_im_sdk_callback.Base, operationID string, userIDs string) {
call(callback, operationID, UserForSDK.User().UnsubscribeUsersStatus, userIDs)
}
// GetSubscribeUsersStatus Get the online status of subscribers.
func GetSubscribeUsersStatus(callback open_im_sdk_callback.Base, operationID string) {
call(callback, operationID, UserForSDK.User().GetSubscribeUsersStatus)
}
// GetUserStatus Get the online status of users.
func GetUserStatus(callback open_im_sdk_callback.Base, operationID string, userIDs string) {
call(callback, operationID, UserForSDK.User().GetUserStatus, userIDs)
}
// AddUserCommand add to user's favorite
func AddUserCommand(callback open_im_sdk_callback.Base, operationID string, Type int32, uuid string, value string) {
call(callback, operationID, UserForSDK.User().ProcessUserCommandAdd, Type, uuid, value)
}
// DeleteUserCommand delete from user's favorite
func DeleteUserCommand(callback open_im_sdk_callback.Base, operationID string, Type int32, uuid string) {
call(callback, operationID, UserForSDK.User().ProcessUserCommandDelete, Type, uuid)
}
// GetAllUserCommands get user's favorite
func GetAllUserCommands(callback open_im_sdk_callback.Base, operationID string, Type int32) {
call(callback, operationID, UserForSDK.User().ProcessUserCommandGetAll, Type)
}

View File

@@ -0,0 +1,464 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/internal/business"
conv "github.com/openimsdk/openim-sdk-core/v3/internal/conversation_msg"
"github.com/openimsdk/openim-sdk-core/v3/internal/file"
"github.com/openimsdk/openim-sdk-core/v3/internal/friend"
"github.com/openimsdk/openim-sdk-core/v3/internal/full"
"github.com/openimsdk/openim-sdk-core/v3/internal/group"
"github.com/openimsdk/openim-sdk-core/v3/internal/interaction"
"github.com/openimsdk/openim-sdk-core/v3/internal/third"
"github.com/openimsdk/openim-sdk-core/v3/internal/user"
"github.com/openimsdk/openim-sdk-core/v3/open_im_sdk_callback"
"github.com/openimsdk/openim-sdk-core/v3/pkg/ccontext"
"github.com/openimsdk/openim-sdk-core/v3/pkg/common"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/db_interface"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/sdkerrs"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
"github.com/openimsdk/protocol/push"
"github.com/openimsdk/protocol/sdkws"
"github.com/openimsdk/tools/log"
"strings"
"sync"
"time"
"unsafe"
)
const (
LogoutStatus = iota + 1
Logging
Logged
)
const (
LogoutTips = "js sdk socket close"
)
var (
// UserForSDK Client-independent user class
UserForSDK *LoginMgr
)
// CheckResourceLoad checks the SDK is resource load status.
func CheckResourceLoad(uSDK *LoginMgr, funcName string) error {
if uSDK == nil {
return utils.Wrap(errors.New("CheckResourceLoad failed uSDK == nil "), "")
}
if funcName == "" {
return nil
}
parts := strings.Split(funcName, ".")
if parts[len(parts)-1] == "Login-fm" {
return nil
}
if uSDK.Friend() == nil || uSDK.User() == nil || uSDK.Group() == nil || uSDK.Conversation() == nil ||
uSDK.Full() == nil {
return utils.Wrap(errors.New("CheckResourceLoad failed, resource nil "), "")
}
return nil
}
type LoginMgr struct {
friend *friend.Friend
group *group.Group
conversation *conv.Conversation
user *user.User
file *file.File
business *business.Business
full *full.Full
db db_interface.DataBase
longConnMgr *interaction.LongConnMgr
msgSyncer *interaction.MsgSyncer
third *third.Third
token string
loginUserID string
connListener open_im_sdk_callback.OnConnListener
justOnceFlag bool
w sync.Mutex
loginStatus int
groupListener open_im_sdk_callback.OnGroupListener
friendListener open_im_sdk_callback.OnFriendshipListener
conversationListener open_im_sdk_callback.OnConversationListener
advancedMsgListener open_im_sdk_callback.OnAdvancedMsgListener
batchMsgListener open_im_sdk_callback.OnBatchMsgListener
userListener open_im_sdk_callback.OnUserListener
signalingListener open_im_sdk_callback.OnSignalingListener
businessListener open_im_sdk_callback.OnCustomBusinessListener
msgKvListener open_im_sdk_callback.OnMessageKvInfoListener
conversationCh chan common.Cmd2Value
cmdWsCh chan common.Cmd2Value
heartbeatCmdCh chan common.Cmd2Value
pushMsgAndMaxSeqCh chan common.Cmd2Value
loginMgrCh chan common.Cmd2Value
ctx context.Context
cancel context.CancelFunc
info *ccontext.GlobalConfig
id2MinSeq map[string]int64
}
func (u *LoginMgr) GroupListener() open_im_sdk_callback.OnGroupListener {
return u.groupListener
}
func (u *LoginMgr) FriendListener() open_im_sdk_callback.OnFriendshipListener {
return u.friendListener
}
func (u *LoginMgr) ConversationListener() open_im_sdk_callback.OnConversationListener {
return u.conversationListener
}
func (u *LoginMgr) AdvancedMsgListener() open_im_sdk_callback.OnAdvancedMsgListener {
return u.advancedMsgListener
}
func (u *LoginMgr) BatchMsgListener() open_im_sdk_callback.OnBatchMsgListener {
return u.batchMsgListener
}
func (u *LoginMgr) UserListener() open_im_sdk_callback.OnUserListener {
return u.userListener
}
func (u *LoginMgr) SignalingListener() open_im_sdk_callback.OnSignalingListener {
return u.signalingListener
}
func (u *LoginMgr) BusinessListener() open_im_sdk_callback.OnCustomBusinessListener {
return u.businessListener
}
func (u *LoginMgr) MsgKvListener() open_im_sdk_callback.OnMessageKvInfoListener {
return u.msgKvListener
}
func (u *LoginMgr) BaseCtx() context.Context {
return u.ctx
}
func (u *LoginMgr) Exit() {
u.cancel()
}
func (u *LoginMgr) GetToken() string {
return u.token
}
func (u *LoginMgr) Third() *third.Third {
return u.third
}
func (u *LoginMgr) ImConfig() sdk_struct.IMConfig {
return sdk_struct.IMConfig{
PlatformID: u.info.PlatformID,
ApiAddr: u.info.ApiAddr,
WsAddr: u.info.WsAddr,
DataDir: u.info.DataDir,
LogLevel: u.info.LogLevel,
IsExternalExtensions: u.info.IsExternalExtensions,
}
}
func (u *LoginMgr) Conversation() *conv.Conversation {
return u.conversation
}
func (u *LoginMgr) User() *user.User {
return u.user
}
func (u *LoginMgr) File() *file.File {
return u.file
}
func (u *LoginMgr) Full() *full.Full {
return u.full
}
func (u *LoginMgr) Group() *group.Group {
return u.group
}
func (u *LoginMgr) Friend() *friend.Friend {
return u.friend
}
func (u *LoginMgr) SetConversationListener(conversationListener open_im_sdk_callback.OnConversationListener) {
u.conversationListener = conversationListener
}
func (u *LoginMgr) SetAdvancedMsgListener(advancedMsgListener open_im_sdk_callback.OnAdvancedMsgListener) {
u.advancedMsgListener = advancedMsgListener
}
func (u *LoginMgr) SetMessageKvInfoListener(messageKvInfoListener open_im_sdk_callback.OnMessageKvInfoListener) {
u.msgKvListener = messageKvInfoListener
}
func (u *LoginMgr) SetBatchMsgListener(batchMsgListener open_im_sdk_callback.OnBatchMsgListener) {
u.batchMsgListener = batchMsgListener
}
func (u *LoginMgr) SetFriendListener(friendListener open_im_sdk_callback.OnFriendshipListener) {
u.friendListener = friendListener
}
func (u *LoginMgr) SetGroupListener(groupListener open_im_sdk_callback.OnGroupListener) {
u.groupListener = groupListener
}
func (u *LoginMgr) SetUserListener(userListener open_im_sdk_callback.OnUserListener) {
u.userListener = userListener
}
func (u *LoginMgr) SetCustomBusinessListener(listener open_im_sdk_callback.OnCustomBusinessListener) {
u.businessListener = listener
}
func (u *LoginMgr) GetLoginUserID() string {
return u.loginUserID
}
func (u *LoginMgr) logoutListener(ctx context.Context) {
for {
select {
case <-u.loginMgrCh:
log.ZDebug(ctx, "logoutListener exit")
err := u.logout(ctx, true)
if err != nil {
log.ZError(ctx, "logout error", err)
}
case <-ctx.Done():
log.ZInfo(ctx, "logoutListener done sdk logout.....")
return
}
}
}
func NewLoginMgr() *LoginMgr {
return &LoginMgr{
info: &ccontext.GlobalConfig{}, // 分配内存空间
}
}
func (u *LoginMgr) getLoginStatus(_ context.Context) int {
u.w.Lock()
defer u.w.Unlock()
return u.loginStatus
}
func (u *LoginMgr) setLoginStatus(status int) {
u.w.Lock()
defer u.w.Unlock()
u.loginStatus = status
}
func (u *LoginMgr) checkSendingMessage(ctx context.Context) {
sendingMessages, err := u.db.GetAllSendingMessages(ctx)
if err != nil {
log.ZError(ctx, "GetAllSendingMessages failed", err)
}
for _, message := range sendingMessages {
if err := u.handlerSendingMsg(ctx, message); err != nil {
log.ZError(ctx, "handlerSendingMsg failed", err, "message", message)
}
if err := u.db.DeleteSendingMessage(ctx, message.ConversationID, message.ClientMsgID); err != nil {
log.ZError(ctx, "DeleteSendingMessage failed", err, "conversationID", message.ConversationID, "clientMsgID", message.ClientMsgID)
}
}
}
func (u *LoginMgr) handlerSendingMsg(ctx context.Context, sendingMsg *model_struct.LocalSendingMessages) error {
tableMessage, err := u.db.GetMessage(ctx, sendingMsg.ConversationID, sendingMsg.ClientMsgID)
if err != nil {
return err
}
if tableMessage.Status != constant.MsgStatusSending {
return nil
}
err = u.db.UpdateMessage(ctx, sendingMsg.ConversationID, &model_struct.LocalChatLog{ClientMsgID: sendingMsg.ClientMsgID, Status: constant.MsgStatusSendFailed})
if err != nil {
return err
}
conversation, err := u.db.GetConversation(ctx, sendingMsg.ConversationID)
if err != nil {
return err
}
latestMsg := &sdk_struct.MsgStruct{}
if err := json.Unmarshal([]byte(conversation.LatestMsg), &latestMsg); err != nil {
return err
}
if latestMsg.ClientMsgID == sendingMsg.ClientMsgID {
latestMsg.Status = constant.MsgStatusSendFailed
conversation.LatestMsg = utils.StructToJsonString(latestMsg)
return u.db.UpdateConversation(ctx, conversation)
}
return nil
}
func (u *LoginMgr) login(ctx context.Context, userID, token string) error {
if u.getLoginStatus(ctx) == Logged {
return sdkerrs.ErrLoginRepeat
}
u.setLoginStatus(Logging)
u.info.UserID = userID
u.info.Token = token
log.ZDebug(ctx, "login start... ", "userID", userID, "token", token)
t1 := time.Now()
u.token = token
u.loginUserID = userID
var err error
u.db, err = db.NewDataBase(ctx, userID, u.info.DataDir, int(u.info.LogLevel))
if err != nil {
return sdkerrs.ErrSdkInternal.WrapMsg("init database " + err.Error())
}
u.checkSendingMessage(ctx)
log.ZDebug(ctx, "NewDataBase ok", "userID", userID, "dataDir", u.info.DataDir, "login cost time", time.Since(t1))
u.user = user.NewUser(u.db, u.loginUserID, u.conversationCh)
u.file = file.NewFile(u.db, u.loginUserID)
u.friend = friend.NewFriend(u.loginUserID, u.db, u.user, u.conversationCh)
u.group = group.NewGroup(u.loginUserID, u.db, u.conversationCh)
u.full = full.NewFull(u.user, u.friend, u.group, u.conversationCh, u.db)
u.business = business.NewBusiness(u.db)
u.third = third.NewThird(u.info.PlatformID, u.loginUserID, constant.SdkVersion, u.info.SystemType, u.info.LogFilePath, u.file)
log.ZDebug(ctx, "forcedSynchronization success...", "login cost time: ", time.Since(t1))
u.msgSyncer, _ = interaction.NewMsgSyncer(ctx, u.conversationCh, u.pushMsgAndMaxSeqCh, u.loginUserID, u.longConnMgr, u.db, 0)
u.conversation = conv.NewConversation(ctx, u.longConnMgr, u.db, u.conversationCh,
u.friend, u.group, u.user, u.business, u.full, u.file)
u.setListener(ctx)
u.run(ctx)
u.setLoginStatus(Logged)
log.ZDebug(ctx, "login success...", "login cost time: ", time.Since(t1))
return nil
}
func (u *LoginMgr) setListener(ctx context.Context) {
setListener(ctx, &u.userListener, u.UserListener, u.user.SetListener, newEmptyUserListener)
setListener(ctx, &u.friendListener, u.FriendListener, u.friend.SetListener, newEmptyFriendshipListener)
setListener(ctx, &u.groupListener, u.GroupListener, u.group.SetGroupListener, newEmptyGroupListener)
setListener(ctx, &u.conversationListener, u.ConversationListener, u.conversation.SetConversationListener, newEmptyConversationListener)
setListener(ctx, &u.advancedMsgListener, u.AdvancedMsgListener, u.conversation.SetMsgListener, newEmptyAdvancedMsgListener)
setListener(ctx, &u.batchMsgListener, u.BatchMsgListener, u.conversation.SetBatchMsgListener, nil)
setListener(ctx, &u.businessListener, u.BusinessListener, u.business.SetListener, newEmptyCustomBusinessListener)
}
func setListener[T any](ctx context.Context, listener *T, getter func() T, setFunc func(listener func() T), newFunc func(context.Context) T) {
if *(*unsafe.Pointer)(unsafe.Pointer(listener)) == nil && newFunc != nil {
*listener = newFunc(ctx)
}
setFunc(getter)
}
func (u *LoginMgr) run(ctx context.Context) {
u.longConnMgr.Run(ctx)
go u.msgSyncer.DoListener(ctx)
go common.DoListener(u.conversation, u.ctx)
go u.logoutListener(ctx)
}
func (u *LoginMgr) InitSDK(config sdk_struct.IMConfig, listener open_im_sdk_callback.OnConnListener) bool {
if listener == nil {
return false
}
u.info = &ccontext.GlobalConfig{}
u.info.IMConfig = config
u.connListener = listener
u.initResources()
return true
}
func (u *LoginMgr) Context() context.Context {
return u.ctx
}
func (u *LoginMgr) initResources() {
ctx := ccontext.WithInfo(context.Background(), u.info)
u.ctx, u.cancel = context.WithCancel(ctx)
u.conversationCh = make(chan common.Cmd2Value, 1000)
u.heartbeatCmdCh = make(chan common.Cmd2Value, 10)
u.pushMsgAndMaxSeqCh = make(chan common.Cmd2Value, 1000)
u.loginMgrCh = make(chan common.Cmd2Value, 1)
u.longConnMgr = interaction.NewLongConnMgr(u.ctx, u.connListener, u.heartbeatCmdCh, u.pushMsgAndMaxSeqCh, u.loginMgrCh)
u.ctx = ccontext.WithApiErrCode(u.ctx, &apiErrCallback{loginMgrCh: u.loginMgrCh, listener: u.connListener})
u.setLoginStatus(LogoutStatus)
}
func (u *LoginMgr) UnInitSDK() {
if u.getLoginStatus(context.Background()) == Logged {
fmt.Println("sdk not logout, please logout first")
return
}
u.info = nil
u.setLoginStatus(0)
}
// token error recycle recourse, kicked not recycle
func (u *LoginMgr) logout(ctx context.Context, isTokenValid bool) error {
if ccontext.Info(ctx).OperationID() == LogoutTips {
isTokenValid = true
}
if !isTokenValid {
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
defer cancel()
err := u.longConnMgr.SendReqWaitResp(ctx, &push.DelUserPushTokenReq{UserID: u.info.UserID, PlatformID: u.info.PlatformID}, constant.LogoutMsg, &push.DelUserPushTokenResp{})
if err != nil {
log.ZWarn(ctx, "TriggerCmdLogout server recycle resources failed...", err)
} else {
log.ZDebug(ctx, "TriggerCmdLogout server recycle resources success...")
}
}
u.Exit()
err := u.db.Close(u.ctx)
if err != nil {
log.ZWarn(ctx, "TriggerCmdLogout db recycle resources failed...", err)
}
// user object must be rest when user logout
u.initResources()
log.ZDebug(ctx, "TriggerCmdLogout client success...", "isTokenValid", isTokenValid)
return nil
}
func (u *LoginMgr) setAppBackgroundStatus(ctx context.Context, isBackground bool) error {
if u.longConnMgr.GetConnectionStatus() == 0 {
u.longConnMgr.SetBackground(isBackground)
return nil
}
var resp sdkws.SetAppBackgroundStatusResp
err := u.longConnMgr.SendReqWaitResp(ctx, &sdkws.SetAppBackgroundStatusReq{UserID: u.loginUserID, IsBackground: isBackground}, constant.SetBackgroundStatus, &resp)
if err != nil {
return err
} else {
u.longConnMgr.SetBackground(isBackground)
if isBackground == false {
_ = common.TriggerCmdWakeUp(u.heartbeatCmdCh)
}
return nil
}
}

View File

@@ -0,0 +1,31 @@
// Copyright © 2023 OpenIM SDK. 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 open_im_sdk
//import (
// "open_im_sdk/open_im_sdk_callback"
//)
//
//funcation GetWorkMomentsUnReadCount(callback open_im_sdk_callback.Base, operationID string) {
// call(callback, operationID, UserForSDK.WorkMoments().GetWorkMomentsUnReadCount)
//}
//
//funcation GetWorkMomentsNotification(callback open_im_sdk_callback.Base, operationID string, offset int, count int) {
// call(callback, operationID, UserForSDK.WorkMoments().GetWorkMomentsNotification, offset, count)
//}
//
//funcation ClearWorkMomentsNotification(callback open_im_sdk_callback.Base, operationID string) {
// call(callback, operationID, UserForSDK.WorkMoments().ClearWorkMomentsNotification)
//}