最近项目中用到了腾讯IM,写篇文章记录一下。
文章目录
- 1.对接方法代码
- 2.碰到的一些坑
1.对接方法代码
@Slf4j
public class IMUtil {private static Logger logger = LogManager.getLogger(IMUtil.class);//创建应用时即时通信 IM 控制台分配的 SDKAppIDprivate static long sdkappid = ImConfig.sdkappid; //App 管理员帐号private static String identifier = ImConfig.identifier;//账号秘钥,用于生成签名private static String key = ImConfig.key;//签名过期时间private static String expire = ImConfig.expire;//服务器域名private static String host= ImConfig.host;/*** 获取用户签名** @return*/public static String getSign(String identifier) {//TLSSigAPIv2这个类就是官方给的,直接拿过来就是了TLSSigAPIv2 tlsSigAPIv2 = new TLSSigAPIv2(sdkappid, key);//这两行可以忽略,因为我存在properties文件中的格式是24*3600*180String[] time = expire.split("\\*");long expireTime = Long.valueOf(time[0]) * Long.valueOf(time[1]) * Long.valueOf(time[2]);return tlsSigAPIv2.genSig(identifier, expireTime);}/*** 调用接口** @param url* @param json* @return*/public static String doPostJson(String url, String json) {//获取签名String userSig = getSign(identifier);//请求地址String address = "https://console.tim.qq.com/" + url + "?sdkappid=" +sdkappid + "&identifier=" + identifier + "&usersig=" +userSig + "&random=99999999&contenttype=json";// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(address);RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(1000).setSocketTimeout(5000).build();httpPost.setConfig(requestConfig);// 创建请求内容StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);httpPost.setEntity(entity);// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}JSONObject jsonObject = new JSONObject(resultString);if (jsonObject.get("ActionStatus").equals("FAIL")) {logger.error("IM发送异常 jsonObject=" + jsonObject);throw new BizException("腾讯IM校验失败,请重试!");}return resultString;}/*** 修改头像、姓名** @param id* @param head* @param name* @return*/public static String updateHeadOrName(String id, String head, String name) {JSONArray list = new JSONArray();if (StringUtils.isNotBlank(head)) {JSONObject headJson = new JSONObject();headJson.put("Tag", "Tag_Profile_IM_Image");if (head.startsWith("/pic")) {headJson.put("Value", host + head);} else {headJson.put("Value", head);}list.put(headJson);}if (StringUtils.isNotBlank(name)) {JSONObject nameJson = new JSONObject();nameJson.put("Tag", "Tag_Profile_IM_Nick");nameJson.put("Value", name);list.put(nameJson);}JSONObject json = new JSONObject();json.put("From_Account", id);json.put("ProfileItem", list);String result = doPostJson("v4/profile/portrait_set", json.toString());return result;}/*** 加入群组** @param imIdentifier* @param groupId* @return*/public static String joinGroup(String imIdentifier, String groupId) {JSONObject stuJson = new JSONObject();stuJson.put("Member_Account", imIdentifier);JSONArray stuArray = new JSONArray();stuArray.put(stuJson);JSONObject json = new JSONObject();json.put("GroupId", groupId);json.put("Silence", 1);json.put("MemberList", stuArray);return doPostJson("v4/group_open_http_svc/add_group_member", json.toString());}/*** 发送系统通知** @param groupId* @param content* @return*/public static String sendGroupNotice(String groupId, String content) {JSONObject msg = new JSONObject();msg.put("Text", content);JSONObject msgJson = new JSONObject();msgJson.put("MsgType", "TIMTextElem");msgJson.put("MsgContent", msg);JSONArray msgArr = new JSONArray();msgArr.put(msgJson);JSONObject json = new JSONObject();json.put("GroupId", groupId);json.put("Random", 8912345);json.put("MsgBody", msgArr);return IMUtil.doPostJson("v4/group_open_http_svc/send_group_msg", json.toString());}/*** 注册im账号** @param imIdentifier* @param name* @return*/public static String register(String imIdentifier, String name, String headUrl) {JSONObject json = new JSONObject();json.put("Identifier", imIdentifier);json.put("Nick", name);if (StringUtils.isNotBlank(headUrl)) {//pic是我本地服务器存放图片的目录,这里可以根据自己情况改一下if (headUrl.startsWith("/pic")) {json.put("FaceUrl",host + headUrl);} else {json.put("FaceUrl", headUrl);}}return IMUtil.doPostJson("v4/im_open_login_svc/account_import", json.toString());}/*** 设置用户角色** @param imIdentifier* @param role* @return*/public static String setRole(String imIdentifier, int role) {JSONObject json = new JSONObject();JSONObject keyJson = new JSONObject();keyJson.put("Tag", "Tag_Profile_IM_Role");keyJson.put("Value", role);JSONArray keyArr = new JSONArray();keyArr.put(keyJson);json.put("From_Account", imIdentifier);json.put("ProfileItem", keyArr);return IMUtil.doPostJson("v4/profile/portrait_set", json.toString());}/*** 删除群组信息** @return*/public static String deleteGroup(String groupId) {JSONObject json = new JSONObject();json.put("GroupId", groupId);String result = IMUtil.doPostJson("v4/group_open_http_svc/destroy_group", json.toString());return result;}/*** 获取群组信息** @return*/public static String getGroupInfo(String groupId) {JSONObject json = new JSONObject();List<String> list = Lists.newArrayList();list.add(groupId);json.put("GroupIdList", list);json.put("GroupBaseInfoFilter", "GroupBaseInfoFilter");String result = IMUtil.doPostJson("v4/group_open_http_svc/get_group_info", json.toString());result = result.substring(result.indexOf("Name") + 7, result.indexOf("NextMsgSeq") - 3);System.out.println("[------------" + result + "-----------------]");return result;}/*** 更新群组名称** @return*/public static String updateGroupInfo(String groupId, String name) {JSONObject json = new JSONObject();json.put("GroupId", groupId);json.put("Name", name);String result = IMUtil.doPostJson("v4/group_open_http_svc/modify_group_base_info", json.toString());return result;}/*** 帐号检查接口** @param userId* @return*/public static Boolean accountCheck(String userId) {JSONObject userJson = new JSONObject();userJson.put("UserID", userId);JSONObject json = new JSONObject();List list = new ArrayList();list.add(userJson);json.put("CheckItem", list);String result = IMUtil.doPostJson("v4/im_open_login_svc/account_check", json.toString());JSONObject jsonResult = new JSONObject(result);JSONArray jsonArray = (JSONArray) jsonResult.get("ResultItem");JSONObject jsonObject = (JSONObject) jsonArray.get(0);return (Integer) jsonObject.get("ResultCode") == 0 && "Imported".equals(jsonObject.get("AccountStatus"));}}
2.碰到的一些坑
- 类找不到异常:sun.misc.BASE64Encoder
使用官方文档中生成签名的方法中用到这个类,一开始在本地可以,部署到服务器却一直报类找不到,看了一眼这个类是jdk里的呀,怎么会找不到,难道是jdk中有猫腻?
马上查了一下本地和服务器jdk的版本,果然不一样,本地1.8,服务器11,11中就删了?
百度了一下,果然,从jdk9开始删除了rt.jar,而这个类正好在这个jar中,解决办法就是换一种base64的解密类,有很多,我换成了:
java.util.Base64
加密:Base64.getEncoder().encodeToString
解密:Base64.getDecoder().decode
- 注册好的用户无法登录
我们这边具体的聊天是直接在前端调用腾讯IM的,要传ID和用户签名,ID我直接用的我们数据库的ID,问题就出在签名上。
一开始自己用的注册的那个签名,最后发现不是,那个签名是管理员的签名,每个用户自己的签名还需要调用一次生成签名的方法生成签名,每个人都不一样的。 - 头像无法显示
一开始自己直接把服务器上的头像地址直接给了腾讯IM,发现那边无法访问,需要在这个基础前面再加上你服务器的域名前缀,像http://xx.xx.xx:8080这种,如果直接用的第三方的头像就不用加了,所以我在代码加了个判断。