社交項目中不免會遇到發送消息,客戶端發送消息暫時不做介紹,這裏講述的是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