GithubHelp home page GithubHelp logo

doocs / qcloud-im-server-sdk-java Goto Github PK

View Code? Open in Web Editor NEW
104.0 8.0 39.0 4.21 MB

☁ Tencent Cloud IM Server SDK in Java | 腾讯云 IM 服务端 SDK Java 版

Home Page: https://doocs.github.io/qcloud-im-server-sdk-java

License: Apache License 2.0

Java 99.98% Shell 0.02%
im instance-message sdk tencent-cloud java

qcloud-im-server-sdk-java's Introduction

Tencent Cloud IM Server SDK in Java

maven license prs welcome open-source-organization

The Tencent Cloud IM Server SDK for Java enables Java developers to easily work with Tencent Cloud IM.

中文文档

Documentation

Quick Start

1. Add Dependency

Note: Tencent Cloud IM Server SDK requires JDK 1.8 or later.

If you're using Maven, just add the following dependency in pom.xml.

<dependency>
  <groupId>io.github.doocs</groupId>
  <artifactId>im-server-sdk-java</artifactId>
  <version>0.4.05</version>
</dependency>

If not, you can download JAR in Maven Center Repository.

2. Getting Started

Here is a quick teaser of an application using Tencent Cloud IM Server SDK in Java:

// sdk appId
long appId = 1400554812;

// admin userId
String userId = "test";

// application key
String key = "60c6c5925f3ae52c7325ac5a8ec78e44c056d1dd84d54e12ffa39911267a2a70";

// create ImClient instance
ImClient client = ImClient.getInstance(appId, userId, key);

// import account
AccountImportRequest request = new AccountImportRequest("doocs");
request.setFaceUrl("https://avatars.githubusercontent.com/u/43716716?s=200&v=4");
request.setNick("Doocs Community");
try {
    AccountImportResult result = client.account.accountImport(request);
    // handle result
} catch (IOException e) {
    // handle exception
}

Contributing

Contributions are always welcomed!

We use the dev branch as the development branch, which indicates that this is a unstable branch.

Here are the workflow for contributors:

  1. Fork to your own
  2. Clone fork to local repository
  3. Create a new branch and work on it
  4. Keep your branch in sync
  5. Commit your changes (make sure your commit message concise)
  6. Push your commits to your forked repository
  7. Create a pull request

Please refer to CONTRIBUTING for detailed guidelines.

License

Apache-2.0 License.

qcloud-im-server-sdk-java's People

Contributors

acbin avatar antenbabby avatar dependabot[bot] avatar github-actions[bot] avatar hongyiheng avatar imgbot[bot] avatar jiyangtang avatar joelcho avatar yanglbme avatar yxxy1002 avatar zhouzonghan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qcloud-im-server-sdk-java's Issues

发送消息的apns对象属性没有更新

"ApnsInfo": {
"Sound": "apns.mp3",
"BadgeMode": 1, // 这个字段缺省或者为 0 表示需要计数,为 1 表示本条消息不需要计数,即右上角图标数字不增加
"Title":"apns title", // apns title
"SubTitle":"apns subtitle", // apns subtitle
"Image":"www.image.com" // image url
}
image
字段不一致

UserSig 失效

UserSig

目前项目中设置过期时间为1天,且无自动刷新机制(io.github.doocs.im.ClientConfiguration)。
在服务器稳定运行一天后,会出现问题。

群成员列表功能问题

MemberProfile->muteUntil字段为Integer类型,当调用群成员列表功能时如果群成员被永久禁言,腾讯云的禁言时间会返回4294967295,超出了Integer的最大范围代码报错。

设置用户资料接口中自定义字段设置未生效问题(有时候生效)

设置用户资料接口现在情况是设置昵称,头像,自定义字段等数据时调用接口返回成功,然后调用拉取资料查询,昵称,头像是更新成功的,但是自定义字段更新未成功,自定义字段是正确的key,因为有时候自定义字段是更新成功的,查看了入参都没发现啥问题
okhttp request:

Request{method=POST, url=https://console.tim.qq.com/v4/profile/portrait_set?sdkappid=xxxxx&identifier=administrator&usersig=xxxxx&random=2136887377&contenttype=json, headers=[User-Agent:qcloud-im-server-sdk-java/null(Mac OS X/13.0/aarch64;11.0.14.1)]}

okhttp requestString: {"From_Account":"xxxxxx","ProfileItem":[{"Tag":"Tag_Profile_IM_Nick","Value":"对对对"},{"Tag":"Tag_Profile_IM_Image","Value":"https:/xxxx.oss-cn-shanghai.aliyuncs.com/dams/47ed6184c7ee4ffeb9b6cabd7.png"},{"Tag":"Tag_Profile_Custom_Data","Value":"{"mobileNo":"13311111111","roleNameList":["SA"]}"}]}

okhttp response:

Response{protocol=http/1.1, code=200, message=OK, url=https://console.tim.qq.com/v4/profile/portrait_set?sdkappid=dddd&identifier=administrator&usersig=ddddd*&random=2136887377&contenttype=json}

多次调用接口都是返回成功的,自定义字段实际未生效, 查看入参都没问题,费解 是有什么要注意的吗 im后台设置的用户自定义字段key是 : Tag_Profile_Custom_Data 大小写是注意到了 没啥问题

新 API 列表

@JsonProperty 注解value值错误

在离线推送设置中
io.github.doocs.im.model.request.AndroidInfo#googleChannelId 字段和io.github.doocs.im.model.request.AndroidInfo#oppoChannelId 字段的@JsonProperty value值一样,都是 @JsonProperty("OPPOChannelID")。
用到这两个字段会报错:
Caused by: java.lang.IllegalArgumentException: Conflicting getter definitions for property "OPPOChannelID": io.github.doocs.im.model.request.AndroidInfo#getOppoChannelId(0 params) vs io.github.doocs.im.model.request.AndroidInfo#getGoogleChannelId(0 params)

msgRandom类型问题

官方文档中msgRandom属性接收是用int类型,SDK代码中用的是long,但是有一个数据范围[0,4294967295]的提示,为什么不直接使用Integer呢?是有什么特殊原因吗?

SendGroupMsgResult 实体映射错误

@com.fasterxml.jackson.annotation.JsonProperty("MsgTime")
private java.lang.Integer msgTime;
@com.fasterxml.jackson.annotation.JsonProperty("msgSeq")
private java.lang.Long msgSeq;

中msgSeq为应该为MsgSeq

创建群组问题

创建群组时,如果定义了群组自定义字段对象且赋值,im会返回{groupId='null', actionStatus='FAIL', errorInfo='all defined key is invalid', errorCode=10004}参数无效。如果不传自定义字段或者只定义自定义字段对象不赋值则没有问题。将源码的AppDefinedDataItem key字段和value字段改为Key和Value也没有问题。
image
image

MismatchedInputException

BeforeCreateGroupCallback.java

@JsonProperty("CreatedGroupNum")
private Integer createdGroupNum;

callback body

{
    "CallbackCommand": "Group.CallbackBeforeCreateGroup",
    "CreatedGroupNum": {
        "Public": 5
    }
}

一点疑问,望回复。

这个地方每次都要重新初始化okHttpClient,这块不会浪费资源嘛。(源码点进去格式奇怪 看不明白)
image

在设置超时时间的时候,默认都是3s,我上游调用的时候,应该设置多少s才能保证这里sdk一个请求响应已经结束,9s?

`
public class ClientConfiguration {
/**
* 默认 UA
*/
public static final String DEFAULT_USER_AGENT = VersionInfoUtil.getDefaultUserAgent();

/**
 * 默认最大重试次数
 */
public static final int DEFAULT_MAX_RETRIES = 3;

/**
 * 默认自动更新签名
 */
public static final boolean DEFAULT_RENEW_SIG = true;
/**
 * 默认超时时间(毫秒)
 */
public static final long DEFAULT_CONNECT_TIMEOUT = 3000L;
public static final long DEFAULT_READ_TIMEOUT = 3000L;
public static final long DEFAULT_WRITE_TIMEOUT = 3000L;、

...
//其他code
`

Integer for Timestamp type is out of range

Calling method:

io.github.doocs.im.core.Group#getMembers(io.github.doocs.im.model.request.GetMembersRequest)

Error while process response JSON.

at io.github.doocs.im.core.Group.getMembers(Group.java:503) \
at io.github.doocs.im.util.HttpUtil.post(HttpUtil.java:76) \ 
at io.github.doocs.im.util.JsonUtil.str2Obj(JsonUtil.java:34) \
com.fasterxml.jackson.core.exc.InputCoercionException: \
Numeric value (1718192416797) out of range of int (-2147483648 - 2147483647)

update IM_BIRTHDAY tencent need int but give a string

// tencent doc
Tag_Profile_IM_BirthDay | uint32 | 生日 | 有 | 推荐用法:20190419

// code
profiles.add(ProfileItem.builder().tag(TagProfile.IM_BIRTHDAY).value(birth).build());

tks for your work.
best wishes.

Change okhttp version to 3.13.1 ,"java.net.SocketTimeoutException: connect timed out" appears

java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:1.8.0_322]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[?:1.8.0_322]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[?:1.8.0_322]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[?:1.8.0_322]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:1.8.0_322]
at java.net.Socket.connect(Socket.java:607) ~[?:1.8.0_322]
at okhttp3.internal.platform.Platform.connectSocket(Platform.java:130) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:247) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.13.1.jar!/:?]
at com.tencent.im.v2.util.RetryInterceptor.intercept(HttpUtil.java:111) ~[tencent-im-sdk-v2-1.0.4.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:264) ~[okhttp-3.13.1.jar!/:?]
at okhttp3.RealCall.execute(RealCall.java:93) ~[okhttp-3.13.1.jar!/:?]

不太建议接口直接throw IOException,用起来很不方便。

我这边通过一个模板方式,对IM的所有接口进行了包装,如果方法显性的扔出IOException,代码不太优雅。
我目前是这样写的

   TxClientTemplate.call(room.getConfigId(),
                (imClient) -> imClient.group.sendGroupMsg(request));

然后 TxClientTemplate.call 的代码是这样的

 public static <T extends GenericResult> T call(Long configId, Function<ImClient, T> function) {
        ImClient imClient = CLIENTS.get(configId);
        if (imClient == null) {
            throw new RuntimeException("缺少" + configId + "的imClient的配置");
        }

        try {
            T result = function.apply(imClient);
            log.info("请求腾讯云直播接口,响应:{}", JsonUtil.toJsonString(result));
            if (!"OK".equals(result.getActionStatus()) || 0 != result.getErrorCode()) {
                log.error("请求腾讯云失败,状态非OK");
                throw BizException.create("103", result.getErrorInfo());
            }
            return result;
        } catch (Throwable throwable) {
            log.error("调用腾讯云发生异常,错误信息:{}", ExceptionUtil.getMessage(throwable), throwable);
            throw BizException.create("103", "调用腾讯云接口失败");
        }
    }

如果显性的有IOException,那我的代码就需要每个都需要 try - catch 了就变成了,感觉很不优雅。

  TxClientTemplate.call(room.getConfigId(),
                (imClient) -> {
                    try {
                        return imClient.group.sendGroupMsg(request);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });

回调demo及验签处理

我翻了一下代码,sdk中提供了回调的接受参数,但没有找到验签相关的内容及单元测试,是我没找到吗

IOS离线推送字段类型错误

IOS离线推送参数io.github.doocs.im.model.request.ApnsInfo#badgeMode字段应该是Integer类型,但是现在是String类型,序列化时会报错

获取群组消息的时候,返回的next超出int最大值报错

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Numeric value (9040992949) out of range of int (-2147483648 - 2147483647)
这是源代码
public static void init() throws IOException {
long appId = xxxxxxx;
String userId = "xxxxxxxxxx";
String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
ClientConfiguration config = new ClientConfiguration();
config.setExpireTime(7 * 24 * 60 * 60L);
config.setAutoRenewSig(false);
ImClient client = ImClient.getInstance(appId, userId, key, config);
GetAppIdGroupListRequest request = GetAppIdGroupListRequest.builder()
.limit(50)
.groupType(GroupType.PUBLIC)
.next(0)
.build();
GetAppIdGroupListResult result = client.group.getAppIdGroupList(request);
System.out.println(request);
}

IMClient 没有自动更新 userSig 的过期时间

这里获取 client instance 后, 从 cache 中获取的 client 的话,是不会更新 userSig 的过期时间的.

    public static IMClient getInstance(Long sdkAppId, String userId, String key) {
        String identify = sdkAppId + "_" + userId;
        if (IM_CLIENT.get(identify) == null) {
            IM_CLIENT.putIfAbsent(identify, new IMClient(sdkAppId, userId, key, 24 * 60 * 60L));
        }
        return IM_CLIENT.get(identify);
    }

获取消息列表的接口少了IsPeerRead已读状态字段

"MsgList": [
       {
           "From_Account": "user1",
           "To_Account": "user2",
           "MsgSeq": 549396494,
           "MsgRandom": 2578554,
           "MsgTimeStamp": 1584669680,
           "MsgFlagBits": 0,
           "IsPeerRead": 0,
           "MsgKey": "549396494_2578554_1584669680",
           "MsgBody": [
               {
                   "MsgType": "TIMTextElem",
                   "MsgContent": {
                       "Text": "msg 1"
                   }
               }
           ],
           "CloudCustomData": "your cloud custom data"
       }
]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.