当前位置: 首页 > news >正文

深圳人才网站建设/中国数据网

深圳人才网站建设,中国数据网,net core 仿wordpress,网页模板素材下载由于业务需求,需要在系统中集成环信,所以去看了下官方文档,写篇博客分享一下。 在开始之前,我们需要了解一下什么是REST。 REST(Representational State Transfer)是一种轻量级的 Web Service 架构风格&am…

由于业务需求,需要在系统中集成环信,所以去看了下官方文档,写篇博客分享一下。

在开始之前,我们需要了解一下什么是REST

REST(Representational State Transfer)是一种轻量级的 Web Service 架构风格,可以翻译成“表述性状态转移”,实现和操作明显比 SOAP 和 XML-RPC 更为简洁,可以完全通过 HTTP 协议实现,还可以利用缓存 Cache 来提高响应速度,性能、效率和易用性上都优于 SOAP 协议。

REST 架构遵循了 CRUD 原则,CRUD原则对于资源只需要四种行为:Create(创建)、Read(读取)、Update(更新)和Delete(删除)就可以完成对其操作和处理。这四个操作是一种原子操作,对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP 协议提供的 GET、POST、PUT 和 DELETE 方法,因此 REST 把 HTTP 对一个 URL 资源的操作限制在POST、GET、PUT 和 DELETE 这四个之内。这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

我看到一篇关于RESTful的很不错的文章:RESTful API 设计指南,有兴趣的可以看下,讲的很好。

环信 REST 平台

环信 REST 平台提供的是一个多租户用户体系,资源以集合(Collection)的形式来描述,这里所说的 Collection 包括 DataBase、企业(orgs)、应用(apps)、IM用户(users)、群组(chatgroups)、消息(chatmessages)、文件(chatfiles)等等,之间的包含关系是:

DB = {org1, org2, …}
org = {app1, app2, …}
app = {users, messages, chatfiles, chatmessages, chatgroups, …}
users = {user1, user2, …}
messages = {message1, message2, …}
chatfiles = {chatfile1, chatfile2, …}
chatmessages = {chatmessage1, chatmessage2, …}
chatgroups = {group1, group2, …}

多租户是指软件架构支持一个实例服务多个用户(Customer),每一个用户被称之为租户(Tenant),软件给予租户可以对系统进行部分定制的能力,如用户界面颜色或业务规则,但是他们不能定制修改软件的代码。详情可查看官方文档:服务端集成。

在环信服务体系中,不同org之间的用户数据相互隔离,同一个 org 下不同 APP 之间的用户数据相互隔离。

REST server

环信的服务器端接口都是通过REST服务方式提供的,REST API基于最简单的HTTP协议,在各个编程语言中都提供了良好的支持。

REST client

REST client 就是调用 REST API 的程序端,调用方式有多种:Linux curl、浏览器、编程语言 HTTP 请求访问实现等。

调用 REST API,本质就是发送 HTTP 请求,只不过大家常用的可能是 HTTP GET 和 HTTP POST 请求,但是在 REST 里面还经常用到 HTTP PUT 和 HTTP DELETE。在 REST 中,把这四种操作称之为动词,可以(但不是特别准确)想象成增删改查。

而动词所操作的对象,在 REST 中,被称之为“资源”,也就是 URL,而这些也都是标准的 HTTP 协议的内容。实际上,当我们在浏览器中打开一个网站的时候,例如,打开环信官网,浏览器实际上发送给网站服务器的,就是一个 HTTP GET 的请求。

需要注意的是,环信的 REST API 都是基于 JSON 的,所以在构造 HTTP 请求的时候,需要在 HTTP HEADER 中指明:

Header_nameHeader_valueDescription
Acceptapplication/json服务器端返回给客户端的数据类型
Content-Typeapplication/json客户端发送到服务器端的数据类型

JAVA

在 Java 中,REST client 实现方式有多种,比如 JBOss RestEasy、Sun Jersey、Dropwizard、Apache HTTPClient。
本文用的是Spring的RestTemplate。有一篇不错的博客:Spring RestTemplate中几种常见的请求方式,可以去看看。

在集成之前,我们得在环信上注册并创建一个账号。

注册开发者账号

第 1 步:进入环信官网,选择“注册 > 注册即时通讯云”,进入环信管理后台的注册页面。

- 注册环信开发者账号

第 2 步:在注册页面中,填写详细资料,并点击“注册”按钮。

注册成功后,我们会向您填写的邮箱中发送验证信息,请前往邮箱进行账号激活。

创建应用

账号激活成功后,回到控制台登录页面登录到开发者后台。

第 1 步:在我的应用中,点击创建应用按钮,如下图:
创建应用

第 2 步:填写创建应用的名称(内容只限于数字、大小写字母),如下图:

(应用名称会存在于你生成的 AppKey 中,如:测试 Demo 中 AppKey 为 easemob-demo#chatdemo,则 chatdemo 为填写的应用名称。注册授权根据需要自行选择,AppKey的长度限制为1k字节以内。)

- 填写应用名称

第 3 步:填写好应用名称后,点确定。创建成功,系统会为你生成 AppKey 以及相关配置信息,如下图:

查看AppKey
之后,将此 AppKey 配置到 Android、iOS、Web IM 上即可。

名词解释
org_name企业的唯一标识,开发者在环信开发者管理后台注册账号时填写的企业 ID
app_name同一“企业”下“APP”唯一标识,开发者在环信开发者管理后台创建应用时填写的“应用名称”
org_admin开发者在环信开发者管理后台注册时填写的“用户名”,企业管理员拥有对该企业账号下所有资源的操作权限
AppKey一个 APP 的唯一标识,规则是 ${org_name} # ${app_name}

这些在官方文档上都是有的,可点击查看:注册并创建应用

编写代码

接下来就开始用户集成了,详细的就不说了,可点击查看用户体系集成。

主要把写好的工具类分享一下。在对应的场景,只需调用对应的方法即可。


import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/***  环信工具类*/
public class HXUtil {private static RestTemplate restTemplate = new RestTemplate();// 企业的唯一标识,开发者在环信开发者管理后台注册账号时填写的企业 IDprivate static final String ORG_NAME = "1122161011178276";// App的client_idprivate static final String CLIENT_ID = "YXA6Irz_oI-GEead-FFvbfaMbQ";// App的client_secretprivate static final String CLIENT_SECRET = "YXA6VsR5JypETS3iPFvNNxYklmho0Vw";// 同一“企业”下“APP”唯一标识,开发者在环信开发者管理后台创建应用时填写的“应用名称”private static final String APP_NAME = "testapp";// 链接前缀private static final String URL_PREFIX = "http://a1.easemob.com/" + ORG_NAME + "/" + APP_NAME + "/";// 缓存的tokenprivate static Token token;// token的失效时间private static long expiresTime;public enum HXMessageType {txt,// 文本img,// 图片loc,// 位置audio,// 音频video,// 视频file// 文件}/*** 获取Token* 注意:关于有效时间,我在网上找过,说的是7天,但是返回的是5184000,* 			但是官网上说是以秒为单位,这么算下来就是60天了,* 			觉得不太对,就先将有效时间设为了7天* @return token*/public static Token getToken() {// 判断Token是否已经过期,如果过期需要重新获取if (token == null || expiresTime < new Date().getTime()) {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);token =  tokenResponseEntity.getBody();// 设置7天后过期Calendar c = Calendar.getInstance();c.add(Calendar.DATE, 7);expiresTime = c.getTime().getTime();} catch (RestClientException e) {e.printStackTrace();}}return token;}/*** 添加用户** @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、Token

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 值// getter and setter
}

本来还是想把上传文件和发送图片等写上的,后来由于需求,决定把聊天这部分交由前端直接访问环信了,所以写完发送消息就没再写了。

其实聊天这部分本人也是推荐由前端来写的。即时通信讲究的就是一个即时性,如果由后端来的话,就不能保证这个即时性了,因为如果前端走后端,后端再走环信,需要两步,而前端直接走环信,则只需要一步,就算网络等外界因素的存在,也不会太慢。而且前端也可以对消息进行一个缓存,从而降低网络访问,而且现在的IM应用也基本上都是这么来的。

以上仅供参考,如有不妥的地方请留下您的见解,谢谢。

http://www.lbrq.cn/news/1409635.html

相关文章:

  • 优秀网页案例/新网站怎么做优化
  • 微商城手机网站制作/嘉兴网站建设方案优化
  • 中国做爰网站/sem招聘
  • 杨和网站建设/百度广告怎么做
  • 上海制作网站的网站/网络推广工作室
  • 个人网站做经营性/如何学会推广和营销
  • 网站建设哪个公司好/百度竞价关键词优化
  • 建网站需要了解什么/qq营销软件
  • 活动vi设计公司/上海百度seo点击软件
  • 济南网站建设/app接入广告变现
  • 代购网站建设/海外推广渠道都有哪些
  • 做公益网站的目的/优秀网站设计赏析
  • 做一个网站大概要多少钱/好口碑关键词优化
  • 做网站上饶/app推广代理
  • 杭州网站建设 网络服务/网站建设技术
  • 注册做网站的公司/优化搜索引擎营销
  • c2c商城网站建设方案/网页设计费用报价
  • 做网站还有价值吗/网站开发制作培训学校
  • 杭州网站设计询问蓝韵网络/营销策划机构
  • 行业猎头网/seo整站优化什么价格
  • 南京网站建设开发/seo3的空间构型
  • 响应式网站建设特征/微信朋友圈广告在哪里做
  • 做网站滚屏广告软件/semir是什么意思
  • 湘潭网站建设 诚信磐石网络/网站推广排名哪家公司好
  • wordpress 简历主题/企业seo推广
  • 泰安网站开发公司/百度热搜关键词排行榜
  • 南康做网站/网站推广和网站优化
  • 怎么自己编写网站/市场调研问卷调查怎么做
  • 驻马店市旅游网站建设/今日军事新闻头条
  • 手机app是怎么开发出来的/seo关键词布局
  • 当使用STL容器去存放数据时,是存放对象合适,还是存放对象指针(对象地址)合适?
  • 静配中心配药智能化:基于高并发架构的Go语言实现
  • 给纯小白的Python操作 PDF 笔记
  • (nice!!!)(LeetCode 每日一题) 837. 新 21 点 (动态规划、数学)
  • Rust:DLL 输出对象的生命周期管理
  • 【PHP】Hyperf:接入 Nacos