目的
本篇讲述服务端如何集成环信SDK,实现IM系统。
流程
- 注册账号
- 创建应用
- 调用环信接口
使用
注册账号和创建应用
登录[https://www.easemob.com/]注册账号,选择注册即时通讯云,注册完毕后,登录即可创建应用创建之后可以在控制台看到你的应用
调用环信接口
首先我把环信服务端文档地址发出来,可以看文档,写的比较详细,毕竟别人要赚钱的,写的差也没人用了。
我们可以在控制台获取应用的一些信息,替换我的工具类的一些信息就可以使用了。其实服务端调用环信的sdk就是进行网络请求,进行网络请求有很多方式,比如http client,URLConnection,okhttp等,这里我使用spring提供的RestTemplate,因为RestTemplate进行rest调用相对来说比较简单。具体的请求接口请访问 http://api-docs.easemob.com/
public class HXUtil {
private static RestTemplate restTemplate = new RestTemplate();
private static final String ORG_NAME = "1166170913115446";//企业的唯一标识,开发者在环信开发者管理后台注册账号时填写的企业 ID
private static final String CLIENT_ID = "YXA6MvScoJhlEeeE2SOuxTV6gQ";//App的client_id
private static final String CLIENT_SECRET = "YXA6EUcZtNNyxqCXRN8pIxZuHBXQj3Y";//App的client_secret
private static final String APP_NAME = "im";// 同一“企业”下“APP”唯一标识,开发者在环信开发者管理后台创建应用时填写的“应用名称”
private static final String URL_PREFIX = "http://a1.easemob.com/" + ORG_NAME + "/" + APP_NAME + "/";//链接前缀
public enum HXMessageType {
//文本
txt,
img,//图片
loc,//位置
audio,//音频
video,//视频
file//文件
}
public static Token getToken() {
try {
JSONObject body = new JSONObject();
body.put("grant_type", "client_credentials");
body.put("client_id", CLIENT_ID);
body.put("client_secret", CLIENT_SECRET);
HttpEntity httpEntity = new HttpEntity(body.toString(), null);
ResponseEntity<Token> tokenResponseEntity = restTemplate.postForEntity(URL_PREFIX + "token", httpEntity, Token.class);
return tokenResponseEntity.getBody();
} catch (RestClientException e) {
e.printStackTrace();
return null;
}
}
/**
* 添加用户
*
* @param username 用户名称(手机号唯一非空)
* @param password 密码
* @return 是否成功
*/
public static boolean addUser(String username, String password) {
try {
JSONArray body = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put("username", username);
jsonObject.put("password", password);
body.add(jsonObject);
HttpEntity httpEntity = new HttpEntity(body.toString(), null);
ResponseEntity responseEntity = restTemplate.postForEntity(URL_PREFIX + "users", httpEntity, null);
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 修改用户密码
*
* @param username 用户名
* @param newpassword 新密码
* @return 是否成功
*/
public static boolean updatePassword(String username, String newpassword) {
try {
JSONObject body = new JSONObject();
body.put("newpassword", newpassword);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + getToken().getAccess_token());
HttpEntity httpEntity = new HttpEntity(body.toString(), headers);
ResponseEntity responseEntity = restTemplate.postForEntity(URL_PREFIX + "users/{username}/password", httpEntity, null, username);
System.out.println(responseEntity.getStatusCodeValue());
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 删除用户
*
* @param username 用户名
*/
public static boolean deleteUser(String username) {
try {
HttpEntity httpEntity = new HttpEntity(null, getHttpHeaders(MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON));
ResponseEntity<HXUser> responseEntity = restTemplate.exchange(URL_PREFIX + "users/{username}", HttpMethod.DELETE, httpEntity, HXUser.class, username);
System.out.println(responseEntity.getStatusCodeValue());
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 添加好友
*
* @param ownerUsername 用户名
* @param friendName 好友用户名
* @return 是否成功
*/
public static boolean addFriend(String ownerUsername, String friendName) {
try {
HttpEntity httpEntity = new HttpEntity(null, getHttpHeaders(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON));
ResponseEntity responseEntity = restTemplate.postForEntity(URL_PREFIX + "users/{owner_username}/contacts/users/{friend_username}", httpEntity, HXUser.class, ownerUsername, friendName);
System.out.println(responseEntity.getStatusCodeValue());
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 删除好友
*
* @param ownerUsername 用户名
* @param friendName 好友用户名
* @return 是否成功
*/
public static boolean deleteFriend(String ownerUsername, String friendName) {
try {
HttpEntity httpEntity = new HttpEntity(null, getHttpHeaders(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON));
ResponseEntity responseEntity = restTemplate.exchange(URL_PREFIX + "users/{owner_username}/contacts/users/{friend_username}", HttpMethod.DELETE, httpEntity, HXUser.class, ownerUsername, friendName);
System.out.println(responseEntity.getStatusCodeValue());
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 发送消息
*
* @param sendUser 发送用户
* @param targetUser 接收用户
* @param msg 发送消息
* @return 是否成功
*/
public static boolean sendToUser(String sendUser, String targetUser, String msg) {
try {
JSONObject body = new JSONObject();
body.put("target_type", "users");
JSONArray targetUserjson = new JSONArray();
targetUserjson.add(targetUser);
body.put("target", targetUserjson);
JSONObject msgJson = new JSONObject();
msgJson.put("type", HXMessageType.txt.name());
msgJson.put("msg", msg);
body.put("msg", msgJson);
body.put("from", sendUser);
HttpEntity httpEntity = new HttpEntity(body, getHttpHeaders(MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON));
ResponseEntity responseEntity = restTemplate.postForEntity(URL_PREFIX + "messages", httpEntity, null);
System.out.println(responseEntity.getStatusCodeValue());
return responseEntity.getStatusCodeValue() == 200;
} catch (RestClientException e) {
e.printStackTrace();
return false;
}
}
/**
* 获取HttpHeaders
*
* @param contentType 客户端发送类型
* @param accept 响应类型
* @return HttpHeaders
*/
private static HttpHeaders getHttpHeaders(MediaType contentType, MediaType... accept) {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Bearer " + getToken().getAccess_token());
headers.setContentType(contentType != null ? contentType : MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList((accept != null && accept.length > 0) ? accept : new MediaType[]{MediaType.APPLICATION_JSON}));
return headers;
}
}
这里并没有把所有的接口都写出来,只是写了部分的,其它的功能也是类似。
其中封装了一些实体类
HXUser
public class HXUser {
private String uuid; //用户的UUID,标识字段
private String type; //类型,“user”用户类型
private Long created;
private Long modified;
private String username; //用户名,也就是环信 ID,(唯一,非空)
private String nickName; //昵称
private boolean activated; //用户是否已激活,“true”已激活,“false“封禁,封禁需要通过解禁接口进行解禁,才能正常登录
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}
Token
public class Token {
private String access_token; //有效的token字符串
private String expires_in; //token 有效时间,以秒为单位,在有效期内不需要重复获取
private String application; //当前 App 的 UUID 值
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
public String getApplication() {
return application;
}
public void setApplication(String application) {
this.application = application;
}
建议
在使用环信SDK时,我有些建议:
- 聊天这种即时信息不走后端,前端直接使用环信的sdk,比如Android引入jar包等,当走后端调用时有两个缺点,1.如果后端宕机了,则不可使用im,不走则可以直接通向环信方服务器。2.网络延时导致达不到即时通讯的作用。
- 前端进行聊天记录与好友等信息的缓存,这样会降低网络访问,基本im应用都是这么做的
如何自己搭建一个im服务器
这里我们是使用了第三方的即时通讯,优点就是简单、方便、成熟可靠。缺点是我们不知道其具体细节,作为一个刨根问底的程序猿肯定是想继续研究的。可以看我的下一篇Tigase进行即时通讯的实现
更多推荐