使用融云发送消息

社交项目中难免会遇到发送消息,客户端发送消息暂时不作介绍,这里讲述的是Java服务端发送消息,其中,消息类型包括:单聊消息、系统消息和自定义消息。

当然,这些内容在融云官网上也有,这里只做记录以及遇到的坑。其中,这里涉及的API主要有:获取融云tokem、注册用户、更新用户、发送单聊消息、给多人发送消息、给所有用户发送消息、检查用户在线状态。

pom依赖
1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>cn.rongcloud.im</groupId>
<artifactId>server-sdk-java</artifactId>
<version>3.0.1</version>
</dependency>

<dependency>
<groupId>de.taimos</groupId>
<artifactId>httputils</artifactId>
<version>1.11</version>
</dependency>
IM接口定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import com.app.exception.CusException;
import com.app.im.model.MediaMessage;
import io.rong.messages.BaseMessage;

/**
* IM相关操作
*/
public interface IMService {

/**
* 注册IM用户
* @param id
* @param name
* @param portrait
* @return
* @throws CusException
*/
boolean addUser(String id,String name,String portrait) throws CusException;

/**
* 修改IM用户信息
* @param id
* @param name
* @param portrait
* @return
* @throws CusException
*/
boolean updateUser(String id,String name,String portrait)throws CusException;

/**
* 单聊模块 发送文本、图片、图文消息
* @param fromId 发送人 Id
* @param targetIds 接收人 Id
* @param msg 消息体
* @param pushContent push 内容, 分为两类 内置消息 Push 、自定义消息 Push
* @param pushData iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData
* @return
* @throws CusException
*/
boolean sendPrivateMsg(String fromId, String[] targetIds,BaseMessage msg, String pushContent, String pushData) throws CusException;

/**
* 系统消息,发送给多人
* @param fromId 发送人 Id
* @param targetIds 接收方 Id
* @param msg 消息
* @param msg 消息内容
* @param pushContent push 内容, 分为两类 内置消息 Push 、自定义消息 Push
* @param pushData iOS 平台为 Push 通知时附加到 payload 中,Android 客户端收到推送消息时对应字段名为 pushData
* @return
* @throws CusException
*/
boolean sendSystemMax100Msg(String fromId,String[] targetIds,BaseMessage msg,String pushContent,String pushData)throws CusException;

/**
* 发送消息给系统所有人
* @param fromId
* @param msg
* @param pushContent
* @param pushData
* @return
* @throws CusException
*/
boolean sendSystemBroadcastMsg(String fromId, BaseMessage msg, String pushContent, String pushData)throws CusException;

/**
* 获取融云token
* @param userId
* @param name
* @param portraitUri
* @return
* @throws CusException
*/
String getToken(String userId, String name, String portraitUri) throws CusException;


/**
* 单聊模块 发送自定义消息
* @param fromId 发送人 Id
* @param targetIds 接收人 Id
* @param msg 自定义 消息体
* @param pushContent 定义显示的 Push 内容,如果 objectName 为融云内置消息类型时,则发送后用户一定会收到 Push 信息
* @param pushData 针对 iOS 平台为 Push 通知时附加到 payload 中
* @return
* @throws CusException
*/
boolean sendUserDefinedMsg(String fromId, String[] targetIds, MediaMessage msg,
String pushContent, String pushData) throws CusException;

/**
* 检查用户在线状态方法
* 调用频率:每秒钟限 100 次
* @param userId
* @return
* @throws CusException
*/
Integer checkOnline(String userId) throws CusException;
}

IM接口实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.app.exception.CusException;
import com.app.im.model.MediaMessage;
import com.app.im.service.IMService;
import com.app.util.CusLogger;
import de.taimos.httputils.HTTPRequest;
import de.taimos.httputils.WS;
import io.rong.RongCloud;
import io.rong.messages.BaseMessage;
import io.rong.methods.message.system.MsgSystem;
import io.rong.models.Result;
import io.rong.models.message.BroadcastMessage;
import io.rong.models.message.PrivateMessage;
import io.rong.models.message.SystemMessage;
import io.rong.models.response.ResponseResult;
import io.rong.models.response.TokenResult;
import io.rong.models.user.UserModel;
import org.apache.http.HttpResponse;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.Reader;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

/**
* IM相关操作 实现类
*/
@Component
public class IMServiceImpl implements IMService {
// 融云AppKey
String appKey = "XXXXXXXXX";
// 融云AppSecret
String appSecret = "XXXXXXXX";
RongCloud imClient;

@PostConstruct
public void init() {
imClient = RongCloud.getInstance(appKey, appSecret);
}

@Override
public boolean addUser(String id, String name, String portrait) throws CusException {
try {
UserModel user = new UserModel(id,name,portrait);
TokenResult result = imClient.user.register(user);
if(result.code == 200){
return true;
}else{
throw new CusException("901","同步注册im用户出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public boolean updateUser(String id, String name, String portrait) throws CusException {
try {
UserModel user = new UserModel(id,name,portrait);
Result result = imClient.user.update(user);
if(result.code == 200){
return true;
}else{
throw new CusException("902","同步更新im用户出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public boolean sendPrivateMsg(String fromId, String[] targetIds,BaseMessage msg, String pushContent, String pushData) throws CusException {
Reader reader = null ;
PrivateMessage privateMessage = new PrivateMessage()
.setSenderId(fromId)
.setTargetId(targetIds)
.setObjectName(msg.getType())
.setContent(msg)
.setPushContent(pushContent)
.setPushData(pushData)
.setVerifyBlacklist(0)
.setIsPersisted(0)
.setIsCounted(0)
.setIsIncludeSender(0);
ResponseResult result = null;
try {
result = imClient.message.msgPrivate.send(privateMessage);
if(result.code == 200){
return true;
}else{
throw new CusException("903","发送系统消息出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public boolean sendSystemMax100Msg(String fromId, String[] targetIds,BaseMessage msg, String pushContent, String pushData) throws CusException {
try {
MsgSystem system = imClient.message.system;
SystemMessage systemMessage = new SystemMessage()
.setSenderId(fromId)
.setTargetId(targetIds)
.setObjectName(msg.getType())
.setContent(msg)
.setPushContent(pushData)
.setPushData(pushData)
.setIsPersisted(0)
.setIsCounted(0)
.setContentAvailable(0);
ResponseResult result = system.send(systemMessage);
if(result.code == 200){
return true;
}else{
throw new CusException("903","发送系统消息出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public boolean sendSystemBroadcastMsg(String fromId,BaseMessage msg, String pushContent, String pushData) throws CusException {
try {
BroadcastMessage message = new BroadcastMessage()
.setSenderId(fromId)
.setObjectName(msg.getType())
.setContent(msg)
.setPushContent(pushContent)
.setPushData(pushData);
ResponseResult result = imClient.message.system.broadcast(message);
if(result.code == 200){
return true;
}else{
throw new CusException("903","发送系统消息出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public String getToken(String userId, String name, String portraitUri) throws CusException {
try {
HTTPRequest req = WS.url("http://api.cn.ronghub.com/user/getToken.json");
Map<String,String> params = new HashMap<String,String>();
params.put("userId",userId);
params.put("name",name);
params.put("portraitUri",portraitUri);
java.util.Random r= new java.util.Random();
String nonce = (r.nextInt(100000)+1)+"";
String timestamp = System.currentTimeMillis()+"";
String signature =string2Sha1(appSecret+nonce+timestamp);
HttpResponse res = req.form(params).header("App-Key",appKey).header("Nonce",nonce).header("Timestamp",timestamp).header("Signature",signature).post();
String body = WS.getResponseAsString(res);
JSONObject jo = JSONObject.parseObject(body);
if(null!=jo && jo.getInteger("code")==200){
return jo.getString("token");
}else{
new CusException("904","获取IM token 出现问题");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
return null;
}

@Override
public boolean sendUserDefinedMsg(String fromId, String[] targetIds, MediaMessage msg, String pushContent, String pushData) throws CusException {
Reader reader = null ;
PrivateMessage privateMessage = new PrivateMessage()
.setSenderId(fromId)
.setTargetId(targetIds)
.setObjectName(msg.getType())
.setContent(msg)
.setPushContent(pushContent)
.setPushData(pushData)
.setCount("1")
.setVerifyBlacklist(0)
.setIsPersisted(0)
.setIsCounted(0)
.setIsIncludeSender(0);
ResponseResult result = null;
try {
// 发送单聊方法
result = imClient.message.msgPrivate.send(privateMessage);
if(result.code == 200){
return true;
}else{
throw new CusException("903","发送自定义单聊消息出错");
}
} catch (Exception e) {
throw new CusException("99","系统异常");
}
}

@Override
public Integer checkOnline(String userId) throws CusException {
HTTPRequest req = WS.url("http://api.cn.ronghub.com/user/checkOnline.json");
Map<String,String> params = new HashMap<String,String>();
params.put("userId",userId);
java.util.Random r = new java.util.Random();
String nonce = (r.nextInt(100000)+1)+"";
String timestamp = System.currentTimeMillis()+"";
String signature =string2Sha1(appSecret + nonce + timestamp);
HttpResponse res = req.timeout(3000).form(params).header("App-Key",appKey).header("Nonce",nonce).header("Timestamp",timestamp).header("Signature",signature).post();
String result = WS.getResponseAsString(res);
Map<String,Object> resMap = JSON.parseObject(result, Map.class);
Integer code = (Integer) resMap.get("code");
if(code != 200) {
CusLogger.error(userId + "调用是否在线接口结果为:" + result);
return 2;
}
String status = (String)resMap.get("status");
Integer resStatus = 0;
if("0".equals(status)) {
resStatus = 0;
} else if("1".equals(status)) {
resStatus = 1;
} else {
resStatus = 2;
}
return resStatus;
}

private static String string2Sha1(String str){
if(str==null||str.length()==0){
return null;
}
char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));

byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j*2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
}
自定义消息实体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import io.rong.messages.BaseMessage;
import io.rong.util.GsonUtil;

public class MediaMessage extends BaseMessage {

// 自定义消息标志
private static final transient String TYPE = "go:media";

private String content = "";

// 以下是自定义参数
private String targetId ;
private String sendId;
private Long sendTime;
private Long receptTime;
private String userAge;
private String userCount;

public MediaMessage() {
}

public MediaMessage(String content) {
this.content = content;
}

// 省略get set
……………………

@Override
public String getType() {
return "rx:media";
}

@Override
public String toString() {
return GsonUtil.toJson(this, MediaMessage.class);
}
}

上面提到的坑就是发送自定义消息。和客户端定义的是发送JSON格式,那好,我就把定义好的JSON赋值到content中,然而,客户端获取到的值都为空,后面,一同事提示,试一下把定义的消息字段放到自定义实体中,我擦,真的可以了。虽然字段的值可以获取到了,但是 有些值获取到的不对,其中,这些字段的类型都是int 或者 Integer,定义的字段为 age和count,怀疑是 字段类型 或者 字段名 定义的不支持,于是,将 这两种都改掉,类型 改为String,字段 改为userAge和userCount,完美解决。

欢迎关注我的公众号~ 搜索公众号: 翻身码农把歌唱 或者 扫描下方二维码:

img

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------本文结束感谢您的阅读-------------
分享到:
0%