集成环信即时通讯(IM)及使用——服务端

目的

本篇讲述服务端如何集成环信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进行即时通讯的实现

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈大侠在江湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值