社交项目中不免会遇到发送消息,客户端发送消息暂时不做介绍,这里讲述的是Java服务端发送消息,其中,消息类型包括:单聊消息、系统消息和自定义消息。html
固然,这些内容在融云官网上也有,这里只作记录以及遇到的坑。其中,这里涉及的API主要有:获取融云tokem、注册用户、更新用户、发送单聊消息、给多人发送消息、给全部用户发送消息、检查用户在线状态。java
<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>
复制代码
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接口实现git
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;
}
}
}
复制代码
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,完美解决。spring
欢迎关注个人公众号~ 搜索公众号: 翻身码农把歌唱 或者 扫描下方二维码:apache