网易云信
一、网易云信基础--云信ID
1、网易云信功能的实现,必须基于云信本身的账户,即用户必须注册云信用户,一切操作基于云信ID;
2、Server端所有请求云信服务必须基于云信提供的统一校验方法。
3、accid建议使用本地账户id、方便同步,token用云信生成的,存储到本地数据库,云信提供修改token的服务
功能所需jar包--版本自定
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.3.3</version> </dependency>
CheckSumBuilder.class 云信提供对请求校验处理的方法
package com.guduo.common.wangyi; import java.security.MessageDigest; /** * 网易提供:生成CheckSum * @author shb * */ public class CheckSumBuilder { // 计算并获取CheckSum public static String getCheckSum( String appSecret,String nonce,String curTime) { return encode("sha1", appSecret + nonce + curTime); } // 计算并获取md5值 public static String getMD5(String requestBody) { return encode("md5", requestBody); } private static String encode(String algorithm, String value) { if (value == null) { return null; } try { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(value.getBytes()); return getFormattedText(messageDigest.digest()); } catch (Exception e) { throw new RuntimeException(e); } } private static String getFormattedText(byte[] bytes) { int len = bytes.length; StringBuilder buf = new StringBuilder(len * 2); for (int j = 0; j < len; j++) { buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); buf.append(HEX_DIGITS[bytes[j] & 0x0f]); } return buf.toString(); } private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; }
统一实现请求服务
package com.guduo.common.wangyi; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import com.guduo.common.utils.string.StringUtil; /** * 网易server请求封装类 * @author shb * */ @SuppressWarnings("deprecation") public class WangyiParamUtil { /** * * @param url:远程请求地址 * @param param:特有请求的特定参数 * @param type:请求类型 * @throws Exception */ public static String util(Map<String, String> param,int type) throws Exception { String url = null; // 设置请求的参数 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); //判断请求类型,设置请求参数 //注册云信id if(type==WangYiReqEnum.WANGYI_REGISTER.type) { url = WangyiConstant.WANGYI_REGISTER_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid") )); nvps.add(new BasicNameValuePair("name",param.get("nickName") )); nvps.add(new BasicNameValuePair("icon","http://www.baidu.com/img/logo.gif" )); } //更新用户名片(昵称、图像地址)-- 名片 if(type==WangYiReqEnum.WANGYI_UPDATE_YUN.type) { url = WangyiConstant.WANGYI_UPDATE_YUN_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid") )); if(!StringUtil.isEmpty(param.get("name"))) nvps.add(new BasicNameValuePair("name",param.get("name") )); if(!StringUtil.isEmpty(param.get("icon"))) nvps.add(new BasicNameValuePair("icon",param.get("icon") )); if(!StringUtil.isEmpty(param.get("icon"))) nvps.add(new BasicNameValuePair("icon",param.get("icon") )); } //封禁云信id if(type==WangYiReqEnum.WANGYI_FORBID.type) { url = WangyiConstant.WANGYI_FORBID_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid") )); } //解禁云信id if(type==WangYiReqEnum.WANGYI_UNBLOCK.type) { url = WangyiConstant.WANGYI_UNBLOCK_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid") )); } //创建房间 if(type==WangYiReqEnum.WANGYI_CREATE_ROOM.type) { url = WangyiConstant.WANGYI_CREATE_ROOM_URL; nvps.add(new BasicNameValuePair("creator",param.get("creator") )); nvps.add(new BasicNameValuePair("name",param.get("name") )); } //查询房间信息 if(type==WangYiReqEnum.WANGYI_SEARCH_ROOM.type) { url = WangyiConstant.WANGYI_SEARCH_ROOM_URL; nvps.add(new BasicNameValuePair("needOnlineUserCount",param.get("true") )); nvps.add(new BasicNameValuePair("roomid",param.get("roomId") )); } //请求聊天室地址 if(type==WangYiReqEnum.WANGYI_ROOM_ADDR.type) { url = WangyiConstant.WANGYI_ROOM_ADDR_URL; nvps.add(new BasicNameValuePair("roomid",param.get("roomid"))); nvps.add(new BasicNameValuePair("accid",param.get("accid"))); } //关闭聊天室 if(type==WangYiReqEnum.WANYI_ROOM_CLOSE.type) { url = WangyiConstant.WANYI_ROOM_CLOSE_URL; } //建立好友关系 if(type==WangYiReqEnum.WANYI_FRIENDS.type) { url = WangyiConstant.WANYI_FRIENDS_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid"))); nvps.add(new BasicNameValuePair("faccid",param.get("faccid"))); nvps.add(new BasicNameValuePair("type","1")); } //修改云信账户token if(type==WangYiReqEnum.WANYI_TOKEN.type) { url = WangyiConstant.WANYI_TOKEN_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid"))); } //修改云信ID-- 云信id更新(token、prop) if(type==WangYiReqEnum.WANYI_UPDATE.type) { url = WangyiConstant.WANYI_UPDATE_URL; nvps.add(new BasicNameValuePair("accid",param.get("accid"))); nvps.add(new BasicNameValuePair("props",param.get("props"))); } return sendRequest(nvps,url); }
//发送请求 public static String sendRequest(List<NameValuePair> nvps,String url) throws Exception { @SuppressWarnings("resource") DefaultHttpClient httpClient = new DefaultHttpClient(); String appKey = WangyiConstant.appKey; String appSecret = WangyiConstant.appSecret; String nonce = WangyiConstant.nonce; String curTime = String.valueOf(new Date().getTime()); String checkSum = CheckSumBuilder.getCheckSum(appSecret, nonce, curTime); HttpPost httpPost = new HttpPost(url); httpPost.addHeader("AppKey", appKey); httpPost.addHeader("Nonce", nonce); httpPost.addHeader("CurTime", curTime); httpPost.addHeader("CheckSum", checkSum); httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8")); // 执行请求 HttpResponse response = httpClient.execute(httpPost); return EntityUtils.toString(response.getEntity(), "utf-8"); } }
二、好友托管
通过accid建立
三、消息推送
需要根据业务需求,定义业务模块、具体业务两个附加字段,APP端接收到消息后,根据两个附加字段做界面展示处理
序号 |
type |
cmdID |
描述 |
1 |
0001 |
1001 |
紧急业务推送 |
2 |
0002 |
2001 |
系统通知 |
3 |
0003 |
3001 |
我的。。。 |
4 |
3002 |
我的。。。 |
|
5 |
3003 |
我的。。。 |
|
6 |
3004 |
我的。。。 |
|
7 |
3005 |
我的。。。 |
点对点、批量点对点
import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; /** * 发送推送 * @author shb * */ public class SendPromotion { /** * 服务器消息推送:点对点、批量点对点 * @param accid:接收人云信id==用户id * @param type:业务模块 * @param cmdID:具体业务 * @param isArrive:是否必须送达(1表示只发在线,2表示会存离线) * @param sendType:消息发送类型(1:点对点,2:批量点对点) * @param toAccids */ public static String sendMsg(String accid,String type,String cmdID,String isArrive,String sendType,JSONArray toAccids) throws Exception { //获取系统注册的云信id String systemYunId = ""; //封装负数参数 Map<String, String> map = new HashMap<String, String>(); map.put("type", type); map.put("cmdID", cmdID); String attach = JSONObject.toJSONString(map); // 设置请求的参数 List<NameValuePair> nvps = new ArrayList<NameValuePair>(); nvps.add(new BasicNameValuePair("from",systemYunId ));//发送者accid,用户帐号,最大32字符,APP内唯一 nvps.add(new BasicNameValuePair("msgtype","0" ));//0:点对点自定义通知,1:群消息自定义通知,其他返回414 nvps.add(new BasicNameValuePair("save",isArrive ));//1表示只发在线,2表示会存离线,其他会报414错误。默认会存离线 nvps.add(new BasicNameValuePair("attach",attach ));//自定义通知内容,第三方组装的字符串,建议是JSON串,最大长度4096字符 //初始化请求的地址 String url = ""; if(sendType.equals("1")) { url = WangyiConstant.ONE_TO_ONE_URL; nvps.add(new BasicNameValuePair("to",accid ));//msgtype==0是表示accid即用户id,msgtype==1表示tid即群id }else{ url = WangyiConstant.ONE_TO_MANY_URL; nvps.add(new BasicNameValuePair("toAccids",toAccids.toJSONString()));//msgtype==0是表示accid即用户id,msgtype==1表示tid即群id } return WangyiParamUtil.sendRequest(nvps, url); } }
四、IM功能(群组、好友、聊天室)
创建聊天室、关闭聊天室参考文档
五、消息抄送
参考代码:http://bbs.netease.im/read-tid-385 @SuppressWarnings("unused")
@ResponseBody @RequestMapping("receiveMsg") public JSONObject receiveMsg(HttpServletRequest request){ //byte[] body = null; JSONObject result = new JSONObject(); try { byte[] body = new byte[request.getContentLength()]; IOUtils.readFully(request.getInputStream(), body); if (body == null) { logger.warn("request wrong, empty body!"); result.put("code", 414); return result; } // 将请求体转成String格式,并打印 String requestBody = new String(body, "utf-8"); System.out.println(requestBody); //roomService.receiveMsg(requestBody,new Date());
//获取返回的JSON对象
JSONObject json = JSONObject.parseObject(requestBody);
//获取抄送类型,其余的key-value是同一级别
String eventType = json.getString("eventType");
} catch (Exception e) { result.put("code", 414); } }