java实现即时通信的完整步骤分享
前言
移动社交是我们日常生活中很常见的软件,最近在做即时通信,我用的是环信,和大家分享一下~~
环信的API都是基于JSON的,所以在构造HTTP请求的时候,要指定请求头:
注意==》环信API必须携带token才可以访问。
创建一个认证类
public class Authentic { private static Token token = new Token(); private TalkHttpService service; public Authentic(TalkHttpService service) { this.service = service; } public Authentic(TalkHttpService service, Token token) { this.service = service; if (token != null) { Authentic.token = token; } } public Token getToken() { this.flush(); return token; } public void task() { this.flush(); } /** * @describe 申请认证 POST PUT 这两种请求携带参数 * @author 何章怀晓 hezhanghuaixiao * @date 2020/9/8 17:02 * @other */ public void applyAuthentication(HttpEntityEnclosingRequestBase request) { this.flush(); request.addHeader("Authorization", "Bearer " + token.toString()); } /** * @describe 申请认证 GET DELETE 这两种请求不携带参数 * @author 何章怀晓 hezhanghuaixiao * @date 2020/9/8 17:02 * @other */ public void applyAuthentication(HttpRequestBase request) { this.flush(); request.addHeader("Authorization", "Bearer " + token.toString()); } private void flush() { synchronized (Authentic.class) { try { //如果超时 if (token.isExpire()) { //判断APPID和秘钥信息 if (_Global.APP_CLIENT_ID != null && _Global.APP_CLIENT_SECRET != null) { Map<String, Object> param = new HashMap<String, Object>(); param.put("grant_type", "client_credentials"); param.put("client_id", _Global.APP_CLIENT_ID); param.put("client_secret", _Global.APP_CLIENT_SECRET); //请求获取token TalkNode res = service .request(_Global.URR_TOKEN, _Global.HTTP_METHOD_POST, param, null, null); //成功获取token if (res != null && res.getAccess_token() != null && res.getExpires_in() != null && res.getExpires_in() > 0) { //赋值 token = new Token(res.getAccess_token(), res.getExpires_in() * 1000 + System.currentTimeMillis()); } } } } catch (Exception e) { e.printStackTrace(); } } } public static class Token { private String token; private Long expire; public Token() { } public Token(String token, long expire) { this.token = token; this.expire = expire; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } public Long getExpire() { return expire; } public void setExpire(Long expire) { this.expire = expire; } public boolean isExpire() { return expire == null || System.currentTimeMillis() > expire; } @Override public String toString() { return token; } } }
创建请求接口
public interface TalkHttpService { /** @describe @param * @param url 请求地址 * @param method 请求方法 * @param param 参数 * @param auth 加密认证 * @param field 字段转换 @return com.hedashi.protal.model.TalkNode @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:21 @other */ TalkNode request(String url, int method, Object param, Authentic auth, String[][] field) throws Exception; /** @describe @param * @param url 请求地址 * @param file 文件名称 * @param auth 加密认证 * @param equal 字段转换 @return com.hedashi.protal.model.TalkNode @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:21 @other */ TalkNode upload(String url, File file, Authentic auth, String[][] equal) throws Exception; /** @describe @param * @param url 请求地址 * @param file 文件名称 * @param auth 加密认证 * @param header 请求头 @return void @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:21 @other */ void downLoad(String url, File file, Authentic auth, Map<String, String> header) throws Exception; }
创建全局变量对不同模块操作
/* @describe 全局变量 @params @return @author 何章怀晓 @date 2020/7/30 9:30 @other */ public class _Global { public static String APP_KEY = ""; public static String APP_CLIENT_ID = ""; public static String APP_CLIENT_SECRET = ""; //每页数量 public static int APP_PAGE_SIZE = 10; public static final int HTTP_METHOD_GET = 1; public static final int HTTP_METHOD_POST = 2; public static final int HTTP_METHOD_PUT = 3; public static final int HTTP_METHOD_DELETE = 4; public static final String URL_HOST = "http://a1.easemob.com/"+APP_KEY.replace("#","/")+"/"; public static final String URR_TOKEN = URL_HOST+"token"; public static final String URL_CHAT = URL_HOST+"chatmessages"; public static final String URL_GROUP = URL_HOST+"chatgroups"; public static final String URL_FILE = URL_HOST+"chatfiles"; public static final String URL_ROOM = URL_HOST+"chatrooms"; public static final String URL_MESSAGES = URL_HOST+"messages"; public static final String URL_USER = URL_HOST+"users"; }
请求管理类
package com.hedashi.protal.service.impl; import com.hedashi.protal.model.TalkNode; import com.hedashi.protal.model.Authentic; import com.hedashi.protal.service.TalkHttpService; import com.hedashi.protal.util.JsonTool; import com.hedashi.protal.util._Global; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.URI; import java.util.Map; import java.util.Map.Entry; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Service; @Service public class TalkHttpServiceImplApache implements TalkHttpService { /** @describe @param * @param url 请求路径 * @param method 方式 * @param param 参数 * @param auth 认证 * @param field 将相应结果封装到本地 @return com.hedashi.protal.model.TalkNode @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:39 @other */ @Override public TalkNode request(String url, int method, Object param, Authentic auth, String[][] field) throws Exception { //获得可关闭的连接 CloseableHttpClient client = this.getClient(); try { HttpResponse response = null; //区分请求方式 switch (method) { case _Global.HTTP_METHOD_GET: //构建请求 HttpGet get = new HttpGet(url); if (auth != null) { //如果未认证 请求认证 auth.applyAuthentication(get); } //固定请求头信息为JSON get.addHeader("Content-Type", "application/json"); response = client.execute(get); break; case _Global.HTTP_METHOD_POST: HttpPost post = new HttpPost(url); if (auth != null) { auth.applyAuthentication(post); } //POST携带参数 if (param != null) { //参数编码放入请求体 post.setEntity(new StringEntity(JsonTool.write(param), "UTF-8")); } post.addHeader("Content-Type", "application/json"); response = client.execute(post); break; case _Global.HTTP_METHOD_PUT: HttpPut put = new HttpPut(url); if (put != null) { auth.applyAuthentication(put); } if (param != null) { put.setEntity(new StringEntity(JsonTool.write(param), "UTF-8")); } put.addHeader("Content-Type", "application/json"); response = client.execute(put); break; case _Global.HTTP_METHOD_DELETE: HttpDelete delete = new HttpDelete(url); if (auth != null) { auth.applyAuthentication(delete); } delete.addHeader("Content-Type", "application/json"); response = client.execute(delete); break; default: throw new Exception("非法请求方式"); } int code = response.getStatusLine().getStatusCode(); //判断返回code 如果为200 if (code == HttpStatus.SC_OK) { //获取响应体 HttpEntity entity = response.getEntity(); if (entity != null) { //解析 String json = EntityUtils.toString(entity, "UTF-8"); if (field != null && field.length > 0) { for (String[] temp : field) { json = json.replace(temp[0], temp[1]); } } //解析为实体类 TalkNode talkNode = (TalkNode) JsonTool.read(json, TalkNode.class); talkNode.setStatusCode(code); return talkNode; } } else { //非200将code返回 return new TalkNode(code); } } catch (Exception e) { throw e; } finally { client.close(); } return null; } @Override public TalkNode upload(String url, File file, Authentic auth, String[][] equal) throws Exception { CloseableHttpClient client = this.getClient(); try { HttpPost post = new HttpPost(); post.setURI(new URI(url)); if (auth != null) { auth.applyAuthentication(post); } post.addHeader("restrict-access", "true"); ContentBody body = new FileBody(file); MultipartEntity part = new MultipartEntity(); part.addPart("file", body); post.setEntity(part); HttpResponse response = client.execute(post); int code = response.getStatusLine().getStatusCode(); if (code == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { String json = EntityUtils.toString(entity, "UTF-8"); if (equal != null && equal.length > 0) { for (String[] temp : equal) { json = json.replace(temp[0], temp[1]); } } TalkNode talkNode = (TalkNode) JsonTool.read(json, TalkNode.class); talkNode.setStatusCode(code); return talkNode; } } } catch (Exception e) { throw e; } finally { client.close(); } return null; } @Override public void downLoad(String url, File file, Authentic auth, Map<String, String> header) throws Exception { CloseableHttpClient client = this.getClient(); try { HttpGet get = new HttpGet(); get.setURI(new URI(url)); if (auth != null) { auth.applyAuthentication(get); } for (Entry<String, String> en : header.entrySet()) { get.addHeader(en.getKey(), en.getValue()); } HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { InputStream in = entity.getContent(); FileOutputStream fos = new FileOutputStream(file); byte[] data = new byte[10 * 1024]; int len = 0; while ((len = in.read(data)) != -1) { fos.write(data, 0, len); } fos.flush(); fos.close(); in.close(); } } } catch (Exception e) { throw e; } finally { client.close(); } } private CloseableHttpClient getClient() { return HttpClients.createDefault(); } }
创建业务请求和响应格式类
package com.hedashi.protal.model; import java.util.List; import java.util.Map; /** @describe 根据不同的业务封装不同的返回结果,该格式在发送请求的时候就被指定 @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:42 @other */ public class TalkNode { public static final String[][] DATA_ENTITIES = new String[][]{{"entities", "entities_share"}, {"share-secret", "share_secret"}}; public static final String[][] DATA_ARRAY = new String[][]{{"data", "data_array"}}; public static final String[][] DATA_LIST = new String[][]{{"data", "data_list"}}; public static final String[][] DATA_MAP = new String[][]{{"data", "data_map"}}; public static final String[][] DATA_CHAT_LIST = new String[][]{{"entities", "data_chat_list"}}; public static final String[][] DATA_ROOM = new String[][]{{"data", "data_room"}}; public static final String[][] DATA_ROOM_LIST = new String[][]{{"data", "data_room_list"}, {"public", "public_room"}}; public static final String[][] DATA_ROOM_REDO = new String[][]{{"data", "data_room_rodo"}}; public static final String[][] DATA_ROOM_REDO_LIST = new String[][]{ {"data", "data_room_redo_list"}}; public static final String[][] DATA_GROUP = new String[][]{{"data", "data_group"}}; public static final String[][] DATA_GROUP_UPDATE = new String[][]{{"data", "data_group_update"}}; public static final String[][] DATA_GROUP_OWNER = new String[][]{{"data", "data_group_owner"}}; public static final String[][] DATA_GROUP_LIST = new String[][]{{"data", "data_group_list"}}; public static final String[][] DATA_GROUP_LIST_MEMBER = new String[][]{ {"data", "data_group_list_member"}}; public static final String[][] DATA_GROUP_LIST_NEW = new String[][]{ {"data", "data_group_list_new"}, {"public", "public_group"}}; public static final String[][] DATA_GROUP_FRIEND = new String[][]{{"data", "data_group_friend"}}; public static final String[][] DATA_GROUP_FRIEND_LIST = new String[][]{ {"data", "data_group_friend_list"}}; private String access_token; private String action; private String application; private String applicationName; private Long count; private String cursor; private Integer duration; private Long expires_in; private String organization; private String path; private Integer statusCode; private Long timestamp; private String uri; private Map<String, Object> params; private TalkUser user; private List<TalkUser> entities; private String[] data_array; private Map<String, String> data_map; private List<Map<String, Object>> data_list; private List<TalkMsg> data_chat_list; private TalkRoom data_room; private List<TalkRoom> data_room_list; private TalkRoomRedo data_room_rodo; private List<TalkRoomRedo> data_room_redo_list; private TalkGroup data_group; private TalkGroupMember data_group_update; private TalkGroupMember data_group_owner; private List<TalkGroup> data_group_list; private List<TalkGroupMember> data_group_list_member; private List<TalkGroupNew> data_group_list_new; private TalkGroupFriend data_group_friend; private List<TalkGroupFriend> data_group_friend_list; public TalkNode() { } public TalkNode(Integer statusCode) { this.statusCode = statusCode; } public String getAccess_token() { return access_token; } public void setAccess_token(String access_token) { this.access_token = access_token; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getApplication() { return application; } public void setApplication(String application) { this.application = application; } public String getApplicationName() { return applicationName; } public void setApplicationName(String applicationName) { this.applicationName = applicationName; } public Long getCount() { return count; } public void setCount(Long count) { this.count = count; } public String getCursor() { return cursor; } public void setCursor(String cursor) { this.cursor = cursor; } public Integer getDuration() { return duration; } public void setDuration(Integer duration) { this.duration = duration; } public Long getExpires_in() { return expires_in; } public void setExpires_in(Long expires_in) { this.expires_in = expires_in; } public String getOrganization() { return organization; } public void setOrganization(String organization) { this.organization = organization; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public Integer getStatusCode() { return statusCode; } public void setStatusCode(Integer statusCode) { this.statusCode = statusCode; } public Long getTimestamp() { return timestamp; } public void setTimestamp(Long timestamp) { this.timestamp = timestamp; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public Map<String, Object> getParams() { return params; } public void setParams(Map<String, Object> params) { this.params = params; } public TalkUser getUser() { return user; } public void setUser(TalkUser user) { this.user = user; } public List<TalkUser> getEntities() { return entities; } public void setEntities(List<TalkUser> entities) { this.entities = entities; } public String[] getData_array() { return data_array; } public void setData_array(String[] data_array) { this.data_array = data_array; } public Map<String, String> getData_map() { return data_map; } public void setData_map(Map<String, String> data_map) { this.data_map = data_map; } public List<Map<String, Object>> getData_list() { return data_list; } public void setData_list(List<Map<String, Object>> data_list) { this.data_list = data_list; } public List<TalkMsg> getData_chat_list() { return data_chat_list; } public void setData_chat_list(List<TalkMsg> data_chat_list) { this.data_chat_list = data_chat_list; } public TalkRoom getData_room() { return data_room; } public void setData_room(TalkRoom data_room) { this.data_room = data_room; } public List<TalkRoom> getData_room_list() { return data_room_list; } public void setData_room_list(List<TalkRoom> data_room_list) { this.data_room_list = data_room_list; } public TalkRoomRedo getData_room_rodo() { return data_room_rodo; } public void setData_room_rodo(TalkRoomRedo data_room_rodo) { this.data_room_rodo = data_room_rodo; } public List<TalkRoomRedo> getData_room_redo_list() { return data_room_redo_list; } public void setData_room_redo_list(List<TalkRoomRedo> data_room_redo_list) { this.data_room_redo_list = data_room_redo_list; } public TalkGroup getData_group() { return data_group; } public void setData_group(TalkGroup data_group) { this.data_group = data_group; } public TalkGroupMember getData_group_update() { return data_group_update; } public void setData_group_update(TalkGroupMember data_group_update) { this.data_group_update = data_group_update; } public TalkGroupMember getData_group_owner() { return data_group_owner; } public void setData_group_owner(TalkGroupMember data_group_owner) { this.data_group_owner = data_group_owner; } public List<TalkGroup> getData_group_list() { return data_group_list; } public void setData_group_list(List<TalkGroup> data_group_list) { this.data_group_list = data_group_list; } public List<TalkGroupMember> getData_group_list_member() { return data_group_list_member; } public void setData_group_list_member( List<TalkGroupMember> data_group_list_member) { this.data_group_list_member = data_group_list_member; } public List<TalkGroupNew> getData_group_list_new() { return data_group_list_new; } public void setData_group_list_new(List<TalkGroupNew> data_group_list_new) { this.data_group_list_new = data_group_list_new; } public TalkGroupFriend getData_group_friend() { return data_group_friend; } public void setData_group_friend(TalkGroupFriend data_group_friend) { this.data_group_friend = data_group_friend; } public List<TalkGroupFriend> getData_group_friend_list() { return data_group_friend_list; } public void setData_group_friend_list( List<TalkGroupFriend> data_group_friend_list) { this.data_group_friend_list = data_group_friend_list; } }
工具类
public class HuanXinUtil { private static TalkDataService service = null; /** @describe 初始化 @param * @param @return void @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:26 @other */ private static void init(){ if(service == null){ // 初始服务端Token Authentic.Token token = new Authentic(new TalkHttpServiceImplApache()).getToken(); //token和过期时间 Authentic.Token TEST_TOKEN = new Authentic.Token(token.getToken(),token.getExpire()); //新建一个链接服务 service = new TalkDataServiceImpl(new TalkHttpServiceImplApache()); // 修改数据业务Token service.setToken(TEST_TOKEN); } } /** @describe 添加管理员 @param * @param groupId 群组id * @param userid 管理员id @return boolean @author 何章怀晓 hezhanghuaixiao @date 2020/9/8 17:54 @other */ public static boolean addGroupManager(String groupId,String userid) { try { init(); TalkNode talkNode = service.addGroupManager(groupId,userid); if(talkNode.getStatusCode()==200){ return true; } } catch (Exception e) { e.printStackTrace(); } return false; } }
service调用
@Override public TalkNode addGroupManager(String id, String userId) throws Exception { Map<String, Object> param = new HashMap<String, Object>(); param.put("newadmin", userId); return service.request(_Global.URL_GROUP + "/" + id + "/admin", _Global.HTTP_METHOD_POST, param, auth, TalkNode.DATA_GROUP); }
/** * @param [groupId, managerId] * @return com.hedashi.common.api.CommonResult * @describe 后台添加群组管理员 * @author 何章怀晓 hezhanghuaixiao * @date 2020/9/8 14:28 * @other */ @Override public CommonResult addGroupManager(String groupId, String managerId) { boolean b = HuanXinUtil.addGroupManager(groupId, managerId); if(b){ System.out.println("环信添加管理员成功=========================="); //本地添加管理员 addGroupAdmin(groupId,managerId); return CommonResult.success("SUCCESS"); } return CommonResult.failed("FAILED"); }
@ApiOperation(value = "群组添加管理员") @RequestMapping(value = "/addGroupManager", method = RequestMethod.POST) @ResponseBody public CommonResult<HeAdmin> addGroupManager( @RequestParam @ApiParam(value = "群组环信ID", required = true) String groupId, @RequestParam @ApiParam(value = "管理员环信id", required = true) String managerId ) { return heUGroupService.addGroupManager(groupId,managerId); }
swagger调用
token 信息
{“application”:“53e3eeb5-6926-46dd-bc61-4e214342ef7e”,“access_token”:“YWMtXDS-uPG6EeqItFktBQxljAAAAAAAAAAAAAAAAAAAAAFT4-61aSZG3bxhTiFDQu9-AgMAAAF0bSppWwBPGgBXDkgrlvguBLEe966D_LnbgNyNz2OOsTgP4okhQGoOdA”,“expires_in”:5184000}
swagger返回结果
控制台
数据库:
总结
到此这篇关于java实现即时通信的文章就介绍到这了,更多相关java实现即时通信内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
赞 (0)