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

环信服务端下载消息文件---菜鸟教程

前言

在服务端,下载消息文件是一个重要的功能。它允许您从服务器端获取并保存聊天消息、文件等数据,以便在本地进行进一步的处理和分析。本指南将指导您完成环信服务端下载消息文件的步骤。
环信服务端下载消息文件是指在环信服务端上,通过调用相应的API接口,从服务器端下载聊天消息、文件等数据的过程。因环信服务端保存的消息漫游是有时间限制,有用户需要漫游全部的消息或者自己服务端做所有消息记录的备份。可以从环信服务端下载消息文件来进行解压,读取消息文件内容进行存储到自己的服务端。

前提条件

  • 已在环信即时通讯控制台 开通配置环信即时通讯 IM 服务。
    注册环信即时通讯IM
  • 了解环信 IM REST API 的调用频率限制
  • 环信接口文档介绍:

一、下载消息文件

以下将介绍如何通过环信接口获取到的URL来进行下载文件,解压文件,读取文件。
注:
time参数: 历史消息记录查询的起始时间。UTC 时间,使用 ISO8601 标准,格式为 yyyyMMddHH。例如 time 为 2018112717,则表示查询 2018 年 11 月 27 日 17 时至 2018 年 11 月 27 日 18 时期间的历史消息。若海外集群为 UTC 时区,需要根据自己所在的时区进行时间转换。
在这里插入图片描述
上图是环信官方文档中给出的获取历史消息记录响应示例。从示例中可以看出我们请求以后可以得到一个URL,这个URL为消息文件的下载URL。

1、下载消息文件环信rest 接口请求代码如下:
String url = "https://{{RestApi}}/{{org_name}}/{{app_name}}/chatmessages/2023122010";
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type","application/json");
headers.add("Authorization","Bearer Authorization");
Map<String, String> body = new HashMap<>();
HttpEntity<Map<String, String>> entity = new HttpEntity<>(body, headers);
ResponseEntity<Map> response;
try {response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class);System.out.print("消息文件下载成功---"+response.toString());
} catch (Exception e) {System.out.print("消息文件下载失败---"+e.toString());
}
2、消息文件下载,通过请求环信下载历史消息文件接口获取到的URL 进行下载。

示例代码:

String url = "";
String targetUrl = "";
download(url,targetUrl);
/** 
* 根据url下载文件,保存到filepath中 
* 
* @param url 文件的url 
* @param diskUrl 本地存储路径 
* @return 
*/
public static String download(String url, String diskUrl) {String filepath = "";String filename = "";try {HttpClient client = HttpClients.createDefault();HttpGet httpget = new HttpGet(url);// 加入Referer,防止防盗链        httpget.setHeader("Referer", url);HttpResponse response = client.execute(httpget);HttpEntity entity = response.getEntity();InputStream is = entity.getContent();if (StringUtils.isBlank(filepath)){Map<String,String> map = getFilePath(response,url,diskUrl);filepath = map.get("filepath");filename = map.get("filename");}File file = new File(filepath);file.getParentFile().mkdirs();FileOutputStream fileout = new FileOutputStream(file);byte[] buffer = new byte[cache];int ch = 0;while ((ch = is.read(buffer)) != -1) {fileout.write(buffer, 0, ch);}is.close();fileout.flush();fileout.close();} catch (Exception e) {e.printStackTrace();}return filename;
}/** 
* 获取response要下载的文件的默认路径 
** @param response* @return */public static Map<String,String> getFilePath(HttpResponse response, String url, String diskUrl) {Map<String,String> map = new HashMap<>();String filepath = diskUrl;String filename = getFileName(response, url);String contentType = response.getEntity().getContentType().getValue();if(StringUtils.isNotEmpty(contentType)){// 获取后缀        String regEx = ".+(.+)$";Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(filename);if (!m.find()) {// 如果正则匹配后没有后缀,则需要通过response中的ContentType的值进行匹配                filename = filename +".gz";}else{if(filename.length()>20){filename = getRandomFileName() + ".gz";}}}if (filename != null) {filepath += filename;} else {filepath += getRandomFileName();}map.put("filename", filename);map.put("filepath", filepath);return map;
}/*** 获取response header中Content-Disposition中的filename值* @param response * @param url* @return*/public static String getFileName(HttpResponse response,String url) {Header contentHeader = response.getFirstHeader("Content-Disposition");String filename = null;if (contentHeader != null) {// 如果contentHeader存在        HeaderElement[] values = contentHeader.getElements();if (values.length == 1) {NameValuePair param = values[0].getParameterByName("filename");if (param != null) {try {filename = param.getValue();} catch (Exception e) {e.printStackTrace();}}}}else{// 正则匹配后缀        filename = getSuffix(url);}return filename;
}/** 
* 获取随机文件名 
* 
* @return 
*/
public static String getRandomFileName() {return String.valueOf(System.currentTimeMillis());
}/** 
* 获取文件名后缀 
* @param url 
* @return 
*/
public static String getSuffix(String url) {// 正则表达式“.+/(.+)$”的含义就是:被匹配的字符串以任意字符序列开始,后边紧跟着字符“/”,    // 最后以任意字符序列结尾,“()”代表分组操作,这里就是把文件名做为分组,匹配完毕我们就可以通过Matcher    // 类的group方法取到我们所定义的分组了。需要注意的这里的分组的索引值是从1开始的,所以取第一个分组的方法是m.group(1)而不是m.group(0)。    String regEx = ".+/(.+)$";Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(url);if (!m.find()) {// 格式错误,则随机生成个文件名        return String.valueOf(System.currentTimeMillis());}return m.group(1);}
  • url为第一步中从环信下载历史消息文件接口中请求返回的url(消息文件下载地址)
  • targetUrl 为下载的本地存储路径

下载以后从对应的路径下就可以看到所下载的文件。
在这里插入图片描述

3、消息文件解压,下载完的文件是以.gz结尾的压缩文件,需要对压缩文件进行解压
 public static void unGzipFile(String gzFilePath,String directoryPath) {String ouputfile = "";try {//建立gzip压缩文件输入流            FileInputStream fin = new FileInputStream(gzFilePath);//建立gzip解压工作流            GZIPInputStream gzin = new GZIPInputStream(fin);//建立解压文件输出流//              ouputfile = sourcedir.substring(0,sourcedir.lastIndexOf('.'));//              ouputfile = ouputfile.substring(0,ouputfile.lastIndexOf('.'));            FileOutputStream fout = new FileOutputStream(directoryPath);int num;byte[] buf=new byte[1024];while ((num = gzin.read(buf,0,buf.length)) != -1) {fout.write(buf,0,num);}gzin.close();fout.close();fin.close();} catch (Exception ex){System.err.println(ex.toString());}return;}

gzFilePath:压缩文件路径
directoryPath:加压到的文件目录路径
解压后的文件如下图所示:
在这里插入图片描述

4、文件读取,将解压后的文件读取出来
FileInputStream inputStream = null;
try {inputStream = new FileInputStream("/Users/liupeng/Downloads/download/1234567890");BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));String str = null;long i = 0;while(true){try {if (!((str = bufferedReader.readLine()) != null)) break;} catch (IOException e) {e.printStackTrace();}JSONObject jo = JSONObject.parseObject(str);System.out.println("==========================================" + i);System.out.println("消息id:" + jo.get("msg_id"));System.out.println("发送id:" + jo.get("from"));System.out.println("接收id:" + jo.get("to"));System.out.println("服务器时间戳:" + jo.get("timestamp"));System.out.println("会话类型:" + jo.get("chat_type"));System.out.println("消息扩展:" + jo.getJSONObject("payload").get("ext"));System.out.println("消息体:" + jo.getJSONObject("payload").getJSONArray("bodies").get(0));i ++;if (i > 100) break;}//close    try {inputStream.close();bufferedReader.close();} catch (IOException e) {e.printStackTrace();}} catch (FileNotFoundException e) {e.printStackTrace();
}

解析完以后日志打印如下:
在这里插入图片描述
至此,解析完以后可以将解析的数据进行存储。

相关文档:

注册环信即时通讯IM:https://console.easemob.com/user/register

环信IM集成文档:https://docs-im-beta.easemob.com/document/ios/quickstart.html

IMGeek社区支持:https://www.imgeek.net/

相关文章:

环信服务端下载消息文件---菜鸟教程

前言 在服务端&#xff0c;下载消息文件是一个重要的功能。它允许您从服务器端获取并保存聊天消息、文件等数据&#xff0c;以便在本地进行进一步的处理和分析。本指南将指导您完成环信服务端下载消息文件的步骤。 环信服务端下载消息文件是指在环信服务端上&#xff0c;通过调…...

创建型模式 | 建造者模式

一、建造者模式 1、原理 建造者模式又叫生成器模式&#xff0c;是一种对象的构建模式。它可以将复杂对象的建造过程抽象出来&#xff0c;使这个抽象过程的不同实现方法可以构造出不同表现&#xff08;属性&#xff09;的对象。创建者模式是一步一步创建一个复杂的对象&#xf…...

MVC设计模式

在当今的软件开发领域&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;设计模式已经成为了一种广泛使用的架构模式。它为应用程序提供了一种结构化的方法&#xff0c;将数据、用户界面和业务逻辑分开&#xff0c;从而使得应用程序更易于维护、扩展和重用。 一、…...

WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir 错误解决

[TOC](WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir 错误解决) 1. 错误信息 <3>WSL (2103) ERROR: CreateProcessEntryCommon:493: chdir(/mnt/d/Program Files/PowerShell/7) failed 52. 解决方法 wsl --shutdownwslrefer: https://github.com/microsoft/…...

【二、自动化测试】为什么要做自动化测试?哪种项目适合做自动化?

自动化测试是一种软件测试方法&#xff0c;通过编写和使用自动化脚本和工具&#xff0c;以自动执行测试用例并生成结果。 自动化旨在替代手动测试过程&#xff0c;提高测试效率和准确性。 自动化测试可以覆盖多种测试类型&#xff0c;包括功能测试、性能测试、安全测试等&…...

用ChatGPT来造一个ChatGPT:计算机领域智能问答系统实践(2)

在PHP语言中&#xff0c;你可以使用MySQL数据库来存储知识库&#xff0c;并使用PHP来实现系统的逻辑。以下是一个简单的示例&#xff1a; 创建数据库表&#xff1a; 首先&#xff0c;创建一个名为 computer_knowledge 的表来存储计算机知识。可以使用以下SQL语句&#xff1a;…...

Ubuntu开机自动挂载硬盘

前言&#xff1a; 因为我的电脑是WIN10 Ubuntu18.04双系统&#xff0c;且两个系统都装在C盘上&#xff0c;而D盘作为数据和代码存储盘&#xff0c;经常会开机就被访问&#xff0c;例如上一次关机前用VS Code访问D盘代码&#xff0c;然后下一次开机的时候打开VSCode发现打不开…...

vue3基础:单文件组件介绍

介绍 Vue 的单文件组件 (即 *.vue 文件&#xff0c;简称 SFC&#xff0c;全称是single file component) 是一种特殊的文件格式&#xff0c;使我们能够将一个 Vue 组件的模板、逻辑与样式封装在单个文件中。下面是一个单文件组件的示例&#xff1a; <script> export def…...

OCR字符识别:开始批量识别身份证信息

身份证信息批量识别OCR是一项解决方案&#xff0c;它能够将身份证照片打包成zip格式或通过URL地址进行提交&#xff0c;并能够识别照片中的文本信息。最终&#xff0c;用户可以将识别结果生成为excel文件进行下载。 API接口功能&#xff1a; 1. 批量识别&#xff1a;支持将多…...

php多小区智慧物业管理系统源码带文字安装教程

多小区智慧物业管理系统源码带文字安装教程 运行环境 服务器宝塔面板 PHP 7.0 Mysql 5.5及以上版本 Linux Centos7以上 统计分析以小区为单位&#xff0c;统计如下数据&#xff1a;小区总栋数、小区总户数、小区总人数、 小区租户数量、小区每月收费金额统计、小区车位统计、小…...

解决虚拟机的网络图标不见之问题

在WIN11中&#xff0c;启动虚拟机后&#xff0c;发现网络图标不见了&#xff0c;见下图&#xff1a; 1、打开虚拟机终端 输入“sudo server network-manager stop”&#xff0c;停止网络管理器 输入“cd /回车” &#xff0c; 切换到根目录 输入“cd var回车” &#xff0c;…...

【Spring类路径Bean定义信息扫描】

Spring类路径Bean定义信息扫描 1. ClassPathBeanDefinitionScanner作用2. 类声明3. 属性4. 构造器5. 扫描方法6. 真正扫描方法7. postProcessBeanDefinition8. 注册bean定义 1. ClassPathBeanDefinitionScanner作用 扫描类路径下的类注册为bean定义。2. 类声明 public class …...

Ubuntu上安装VMware+win11系统手册

Ubuntu安装vmware 下载&#xff1a; Linux 版下载地址&#xff1a;https://www.vmware.com/go/getworkstation-linux 安装&#xff1a; sudo chmod x VMware-Workstation-Full-17.5.0-22583795.x86_64.bundle 执行安装命令&#xff1a; sudo ./VMware-Workstation-Full-17.5.0…...

2024年1月12日:清爽无糖rio留下唇齿之间的香甜

友利奈绪的时间管理 2024年1月12日08:02:28进行java程序设计的上课准备 2024年1月12日08:02:44知道java的题目有18道 2024年1月12日08:43:07随机数去重比较 2024年1月12日08:54:03C语言题目最小公倍数 2024年1月12日08:58:37C语言题目二维数组变一维数组 2024年1月12日10…...

群晖Synology Drive同步文件时过滤指定文件夹“dist“, “node_modules“

群晖Synology Drive同步文件时过滤指定文件夹"dist", “node_modules” mac用户 安装Synology Drive创建同步任务修改Synology Drive配置 打开/Users/[用户名]/Library/Application Support/SynologyDrive/data/session/[同步任务序号&#xff0c;第一个同步任务就…...

小程序中滚动字幕

需求&#xff1a;在录像时需要在屏幕上提示字幕&#xff0c;整体匀速向上滚动 html部分&#xff1a; <view class"subtitles_main"><view style"font-size:34rpx;color: #fff;line-height: 60rpx;" animation"{{animation}}">人生的…...

MySQL中约束是什么?

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;重拾MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出现错误&am…...

若依在表格中如何将字典的键值转为中文

文章目录 一、需求&#xff1a;二、问题解决步骤1、给需要转换的列绑定formatter属性2、获取字典项3、编写formatter属性绑定的方法 一、需求&#xff1a; 后端有时候返回的是字典的键值&#xff0c;在前端展示时需要转成中文值 后端返回的是dictValue&#xff0c;现在要转换…...

用笨办法-刻意练习来提高自己的编程能力

尝试了很多学习方法&#xff0c;企图快速提高编程能力&#xff0c;但最终发现&#xff0c;唯有老老实实刻意练习1&#xff0c;在辛苦与时间积累下&#xff0c;逐渐提升能力&#xff0c;才是最有效的方式。 将自己的笨办法总结了一下&#xff0c;主要包含7个步骤&#xff1a; …...

FineBI报表页面大屏小屏自适应显示问题

大屏正常显示 显示正常 小屏BI自适应显示 存在遮挡字体情况 小屏浏览器缩放显示 等比缩放后显示正常...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

Spring Security 认证流程——补充

一、认证流程概述 Spring Security 的认证流程基于 过滤器链&#xff08;Filter Chain&#xff09;&#xff0c;核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤&#xff1a; 用户提交登录请求拦…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

篇章一 论坛系统——前置知识

目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构​编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...

JS设计模式(5): 发布订阅模式

解锁JavaScript发布订阅模式&#xff1a;让代码沟通更优雅 在JavaScript的世界里&#xff0c;我们常常会遇到这样的场景&#xff1a;多个模块之间需要相互通信&#xff0c;但是又不想让它们产生过于紧密的耦合。这时候&#xff0c;发布订阅模式就像一位优雅的信使&#xff0c;…...

STM32CubeMX-H7-19-ESP8266通信(中)--单片机控制ESP8266实现TCP地址通信

前言 上篇文章我们已经能够使用串口助手实现esp8266的几种通信&#xff0c;接下来我们使用单片机控制实现。这篇文章会附带教程&#xff0c;增加.c和,.h&#xff0c;把串口和定时器放到对应的编号&#xff0c;然后调用初始化就可以使用了。 先讲解&#xff0c;然后末尾再放源码…...

【Unity】R3 CSharp 响应式编程 - 使用篇(二)

一、通用的事件监听用法 using System;using R3;using UnityEngine;namespace Aladdin.Standard.Observable.Common{public class CommonObservable : MonoBehaviour{// 默认会调用1次public SerializableReactiveProperty<int> serializableReactiveProperty;…...

【笔记】PyCharm 使用问题反馈与官方进展速览

#工作记录 https://youtrack.jetbrains.com/issue/IJPL-190308 【笔记】记一次PyCharm的问题反馈_the polyglot context is using an implementation th-CSDN博客 【笔记】与PyCharm官方沟通解决开发环境问题-CSDN博客 与 JetBrains 官方沟通记录&#xff08;PyCharm 相关问题…...

跟进一下目前最新的大数据技术

搭建最新平台 40C64G服务器&#xff0c;搭建3节点kvm&#xff0c;8C12G。 apache-hive-4.0.1-bin apache-tez-0.10.4-bin flink-1.20.1 hadoop-3.4.1 hbase-2.6.2 jdk-11.0.276 jdk8u452-b09 jdk8终于可以不用了 spark-3.5.5-bin-hadoop3 zookeeper-3.9.3 trino…...