2
回复

环信IM的开发者用户体验就靠你了 !!【内推职位招聘】环信Web/android/ios前端技术支持工程师 环信

开发讨论beyond 回复了问题 • 3 人关注 • 213 次浏览 • 2020-06-28 10:24 • 来自相关话题

8
评论

【源码下载】一款使用环信实现的开源灵魂社交APP(含服务器) 猿匹配 开源

开发讨论beyond 发表了文章 • 20030 次浏览 • 2019-07-01 10:48 • 来自相关话题

#前言
近期,环信热心开发者-穿裤衩闯天下使用环信IM开发了一款实时聊天应用,包含简单的服务器端,现在正式开源给小伙伴们。感兴趣的同学可以一起搞一下哦,详细介绍请往下看。






  上代码
服务器:VMServer
客户端:VMMatch
 
 #VMMatch
猿匹配 —— 国内首个程序猿非严肃婚恋交友应用,让我们一言不合就来场匹配吧
 
#介绍#
首先说下中文名:为什么叫这个名字呢,因为这是一个程序猿(媛)之间匹配交流的应用啊其实这是一个使用环信 IM 开发的一款开源聊天项目,涵盖了时下流行的一些聊天元素,同时已将 IM 功能封装为单独库,可以直接引用,方便使用
项目还处在初期阶段,还有许多功能需要实现,有兴趣的可以一起来
项目资源均来自于互联网,如果有侵权请联系我
 
 #下载体验
猿匹配 小米商店 审核中
猿匹配 Google Play
 
  #项目截图

























  
 #开发环境
项目基本属于在最新的Android开发环境下开发,使用Java8的一些新特性,比如Lambda表达式,
然后项目已经适配Android6.x以上的动态权限适配,以及7.x的文件选择,和8.x的通知提醒等;
· Mac OS 10.14.4
· Android Studio 3.3.2
  #项目模块儿
本项目包含两部分:
一部分是项目主模块app,这部分主要包含了项目的业务逻辑,比如匹配、信息修改、设置等
另一部分是封装成library的vmim,这是为了方便大家引用到自己的项目中做的一步封装,不用再去复杂的复制代码和资源等,
只需要将vmim以module导入到自己的项目中就行了,具体使用方式参见项目app模块儿;
 
  #功能与 TODO
IM部分功能
· [x] 链接监听
· [x] 登录注册
· [x] 会话功能
      。[x] 置顶
      。[x] 标为未读
      。[x] 删除与清空
      。[x] 草稿功能
· [x] 消息功能
      。[x] 下拉加载更多
      。[x] 消息复制(仅文字类消息)
      。[x] 消息删除
      。[x] 文本+Emoji消息收发
      。[x] 大表情消息收发
      。[x] 图片消息
        ~[x] 查看大图
        ~[ ] 保存图片
      。[x] 语音消息
        ~[x] 语音录制
        ~[x] 语音播放(可暂停,波形待优化)
        ~[x] 听筒和扬声器播放切换
      。[x] 语音实时通话功能
      。[x] 视频实时通话功能
      。[x] 通话过程中的娱乐消息收发
        ~[x] 骰子
        ~[x] 石头剪刀布
        ~[x] 大表情
      。[x] 昵称头像处理(通过回调实现)
App部分功能
· [x] 登录注册(包括业务逻辑和 IM 逻辑)
· [x] 匹配
      。[x] 提交匹配信息
      。[x] 拉取匹配信息
· [x] 聊天(这里直接加载 IM 模块儿)
· [x] 我的
      。[x] 个人信息展示
      。[x] 上传头像
      。[x] 设置昵称
      。[x] 设置签名
· [x] 设置
      。[x] 个人信息设置
      。[x] 通知提醒
      。[x] 聊天
      。[ ] 隐私(随业务部分一起完善)
      。[ ] 通用(随业务部分一起完善)
      。[ ] 帮助反馈(随业务部分一起完善)
      。[x] 关于
      。[x] 退出
· [ ] 社区
      。[ ] 发布
      。[ ] 评论
      。[ ] 收藏
      。[ ] 关注
发布功能
· [x] 多渠道打包
· [x] 签名配置
· [x] 开发与线上环境配置
· [x] 敏感信息保护
 
  #配置运行
1.首先复制config.default.gradle到config.gradle
2.配置下config.gradle环信appkey以及bugly统计Id
3.正式打包需要配置下签名信息,同时将签名文件放置在项目根目录
 
  #参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge
 
 #关联项目
服务器端由nodejs实现,地址见这里 VMServer
 
  #VMServer
是为Android开源项目VMMatch项目(中文名猿匹配)实现的服务端
 
  #简介
这个项目包含两部分
· 根目录:服务逻辑及API接口实现
· client目录:前端界面,和服务器端代码端放置在同一仓库下(暂未实现)
 
 #使用
简单介绍下运行环境及部署方法
1.安装nodejs开发时使用的是v10.16.0版本
2.需要安装mongodb并启动,开发使用版本4.0.10
3.下载项目到服务器,可以下载压缩包,或者用git clone命令
4.复制config_default.js到config.js,可根据自己需要修改配置文件
5.安装依赖npm install
6.全局安装pm2npm install pm2 -g 
7.运行 vmshell.sh
 




扫码备注【开源项目】邀你加入环信开源社群
 
转载自https://blog.melove.net/develop-open-source-im-match-and-server/ 
  查看全部
#前言
近期,环信热心开发者-穿裤衩闯天下使用环信IM开发了一款实时聊天应用,包含简单的服务器端,现在正式开源给小伙伴们。感兴趣的同学可以一起搞一下哦,详细介绍请往下看。

猿匹配_logo_副本.png


  上代码
服务器:VMServer
客户端:VMMatch
 
 #VMMatch
猿匹配 —— 国内首个程序猿非严肃婚恋交友应用,让我们一言不合就来场匹配吧
 
#介绍#
首先说下中文名:为什么叫这个名字呢,因为这是一个程序猿(媛)之间匹配交流的应用啊其实这是一个使用环信 IM 开发的一款开源聊天项目,涵盖了时下流行的一些聊天元素,同时已将 IM 功能封装为单独库,可以直接引用,方便使用
项目还处在初期阶段,还有许多功能需要实现,有兴趣的可以一起来
项目资源均来自于互联网,如果有侵权请联系我
 
 #下载体验
猿匹配 小米商店 审核中
猿匹配 Google Play
 
  #项目截图

1.png

2.png

3.png

4.png

5.png

6.png

  
 #开发环境
项目基本属于在最新的Android开发环境下开发,使用Java8的一些新特性,比如Lambda表达式,
然后项目已经适配Android6.x以上的动态权限适配,以及7.x的文件选择,和8.x的通知提醒等;
· Mac OS 10.14.4
· Android Studio 3.3.2
  #项目模块儿
本项目包含两部分:
一部分是项目主模块app,这部分主要包含了项目的业务逻辑,比如匹配、信息修改、设置等
另一部分是封装成library的vmim,这是为了方便大家引用到自己的项目中做的一步封装,不用再去复杂的复制代码和资源等,
只需要将vmim以module导入到自己的项目中就行了,具体使用方式参见项目app模块儿;
 
  #功能与 TODO
IM部分功能
· [x] 链接监听
· [x] 登录注册
· [x] 会话功能
      。[x] 置顶
      。[x] 标为未读
      。[x] 删除与清空
      。[x] 草稿功能
· [x] 消息功能
      。[x] 下拉加载更多
      。[x] 消息复制(仅文字类消息)
      。[x] 消息删除
      。[x] 文本+Emoji消息收发
      。[x] 大表情消息收发
      。[x] 图片消息
        ~[x] 查看大图
        ~[ ] 保存图片
      。[x] 语音消息
        ~[x] 语音录制
        ~[x] 语音播放(可暂停,波形待优化)
        ~[x] 听筒和扬声器播放切换
      。[x] 语音实时通话功能
      。[x] 视频实时通话功能
      。[x] 通话过程中的娱乐消息收发
        ~[x] 骰子
        ~[x] 石头剪刀布
        ~[x] 大表情
      。[x] 昵称头像处理(通过回调实现)
App部分功能
· [x] 登录注册(包括业务逻辑和 IM 逻辑)
· [x] 匹配
      。[x] 提交匹配信息
      。[x] 拉取匹配信息
· [x] 聊天(这里直接加载 IM 模块儿)
· [x] 我的
      。[x] 个人信息展示
      。[x] 上传头像
      。[x] 设置昵称
      。[x] 设置签名
· [x] 设置
      。[x] 个人信息设置
      。[x] 通知提醒
      。[x] 聊天
      。[ ] 隐私(随业务部分一起完善)
      。[ ] 通用(随业务部分一起完善)
      。[ ] 帮助反馈(随业务部分一起完善)
      。[x] 关于
      。[x] 退出
· [ ] 社区
      。[ ] 发布
      。[ ] 评论
      。[ ] 收藏
      。[ ] 关注
发布功能
· [x] 多渠道打包
· [x] 签名配置
· [x] 开发与线上环境配置
· [x] 敏感信息保护
 
  #配置运行
1.首先复制config.default.gradle到config.gradle
2.配置下config.gradle环信appkey以及bugly统计Id
3.正式打包需要配置下签名信息,同时将签名文件放置在项目根目录
 
  #参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge
 
 #关联项目
服务器端由nodejs实现,地址见这里 VMServer
 
  #VMServer
是为Android开源项目VMMatch项目(中文名猿匹配)实现的服务端
 
  #简介
这个项目包含两部分
· 根目录:服务逻辑及API接口实现
· client目录:前端界面,和服务器端代码端放置在同一仓库下(暂未实现)
 
 #使用
简单介绍下运行环境及部署方法
1.安装nodejs开发时使用的是v10.16.0版本
2.需要安装mongodb并启动,开发使用版本4.0.10
3.下载项目到服务器,可以下载压缩包,或者用git clone命令
4.复制config_default.js到config.js,可根据自己需要修改配置文件
5.安装依赖
npm install

6.全局安装pm2
npm install pm2 -g
 
7.运行 vmshell.sh
 
环信冬冬_副本.jpg

扫码备注【开源项目】邀你加入环信开源社群
 
转载自https://blog.melove.net/develop-open-source-im-match-and-server/ 
 
0
回复

ios如何使用手表语音 iWatch

回复

iOS 讨论区Zero 发起了问题 • 1 人关注 • 10 次浏览 • 2020-07-02 14:29 • 来自相关话题

0
评论

企业微信机器人在大型财务共享中心的应用实践 环信机器人

开发讨论beyond 发表了文章 • 303 次浏览 • 2020-05-25 10:48 • 来自相关话题

在很多大型企业里,出于安全和便捷方面考虑往往会采用企业微信或者自行开发的IM作为内部沟通的主要渠道。其中,员工和财务部门之间的财务咨询是频次很高的场景,尤其是销售型公司,例如报销流程咨询、发票问题咨询、单据审核咨询、招投标资料索取咨询等,占据了财务人员很多的时间。如何将财务人员从其中一部分简单、重复、低价值的工作中释放出来去做更有价值的工作呢?
根据对部分大型企业的财务共享中心的调研,财务部门员工认为他们60%的时间被用于处理来自电话、微信、企业微信、内部IM等渠道的公司内部咨询问题,严重影响了财务部门的效率。
如何将财务人员从其中一部分简单、重复、低价值的工作中释放出来去做更有价值的工作呢?
针对这种情况,环信最新推出企业微信机器人解决方案,基于100%企业微信官方API和环信机器人,只需4步即可助力财务部门紧抓企业微信和人工智能两大红利。基于环信企业微信机器人方案,对内财务部门可以大幅度提高工作效率、增强财务部门员工的“工作幸福感”,对外可以面向企业全体员工提供更迅捷更方便的财务支持服务,让财务部门成为企业数字化转型的排头兵。
企业微信机器人的开通和使用步骤如下,enjoy:

01
在环信中开通企业微信接入渠道
这个很简单,基本就是点按钮,做一下企业微信授权就可以了。详细文档请点:http://docs.easemob.com/cs/connect-to-enterprisewechat

02
员工通过企业微信咨询财务问题
开通了环信客服云的企业微信长的是什么样子呢?在企业微信的工作台,会出现一个“财务助手”(这个名字是企业自己取的)的按钮:





 
点这个按钮后就进入到原生的会话页面。在这个会话页面上,员工就可以向财务同事咨询问题了。





 
03
财务同事使用客服工作台回答问题
财务同事那一端的工作界面是什么样子的呢?一定要记住!专门做服务支持的财务同事,不要直接用企业微信来回答问题。为什么?
首先,在这种专业的高密度沟通场景下,一定要用专业的客服效率工具,比如环信客服工作台。下面是一个典型的环信客户工作台的示意图,你可以看到,这里有几十项工具,包括快捷回复、人机协作等,它们被设计出来的唯一目的就是让你回答访客的问题更快速更高效!





 
其次,有人的地方就有管理,有管理就需要各种考核和报表工具。环信客服云有多达几十项的客服考核指标。这些都是企业微信本身不具备的。





 
 04
使用机器人降本增效
在财务部门对内提供咨询服务的这个场景下,场景收敛,有大量相对简单重复的问题,机器人落地效果已经得到了验证,财务人员被释放出来去做更有价值的工作。当然,这也是有前提的。具体来说,你需要具备以下条件:
1.首先,你需要一个先进的客服机器人产品。比如环信机器人:)
2.你需要进行有质量的财务知识库的建设。关于如何进行高质量的知识库建设,可以联系环信客户经理进行相应的交流沟通和培训。
3.很多财务咨询都需要进行多轮对话并对接业务系统来返回实时数据结果。所以你的机器人产品需要支持多轮对话,还需要可以低成本的快速对接第三方业务系统。
下面是一个典型的员工通过企业微信向财务部门咨询问题,由财务机器人来回答问题的截图:





 同时,使用机器人还可以做到7X24小时不间断的财务服务。比如,下班时间,可以设置为完全由机器人接待。上班时间所有的进线咨询优先由机器人接待,机器人解决不了的问题,再转人工。如果可以做到30%的转人工率(大部分使用环信机器人的客户是可以达到这个转人工率的),那就意味着帮助财务部门节省了70%的人工。转人工时,还可以设置转给特定的技能组并安排一个排班接待制度,这样财务部门就可以按照自己的方式来实现资源的最佳调配。
TIPS:近期权威机构发布的《2019人工智能客服平台排行榜》,环信稳居智能客服行业榜首哦!同时,环信机器人将定期举行线上培训。如果你希望把企业微信机器人用好,真正帮助到财务部门的小姐姐们,建议你参加“环信机器人使用进阶”和“环信机器人知识库调优最佳实践”这2个培训。请联系你的环信客户经理或者留言免费报名。 查看全部
在很多大型企业里,出于安全和便捷方面考虑往往会采用企业微信或者自行开发的IM作为内部沟通的主要渠道。其中,员工和财务部门之间的财务咨询是频次很高的场景,尤其是销售型公司,例如报销流程咨询、发票问题咨询、单据审核咨询、招投标资料索取咨询等,占据了财务人员很多的时间。如何将财务人员从其中一部分简单、重复、低价值的工作中释放出来去做更有价值的工作呢?
根据对部分大型企业的财务共享中心的调研,财务部门员工认为他们60%的时间被用于处理来自电话、微信、企业微信、内部IM等渠道的公司内部咨询问题,严重影响了财务部门的效率。
如何将财务人员从其中一部分简单、重复、低价值的工作中释放出来去做更有价值的工作呢?
针对这种情况,环信最新推出企业微信机器人解决方案,基于100%企业微信官方API和环信机器人,只需4步即可助力财务部门紧抓企业微信和人工智能两大红利。基于环信企业微信机器人方案,对内财务部门可以大幅度提高工作效率、增强财务部门员工的“工作幸福感”,对外可以面向企业全体员工提供更迅捷更方便的财务支持服务,让财务部门成为企业数字化转型的排头兵。
企业微信机器人的开通和使用步骤如下,enjoy:

01
在环信中开通企业微信接入渠道

这个很简单,基本就是点按钮,做一下企业微信授权就可以了。详细文档请点:http://docs.easemob.com/cs/connect-to-enterprisewechat

02
员工通过企业微信咨询财务问题

开通了环信客服云的企业微信长的是什么样子呢?在企业微信的工作台,会出现一个“财务助手”(这个名字是企业自己取的)的按钮:

1.png

 
点这个按钮后就进入到原生的会话页面。在这个会话页面上,员工就可以向财务同事咨询问题了。

2.png

 
03
财务同事使用客服工作台回答问题

财务同事那一端的工作界面是什么样子的呢?一定要记住!专门做服务支持的财务同事,不要直接用企业微信来回答问题。为什么?
首先,在这种专业的高密度沟通场景下,一定要用专业的客服效率工具,比如环信客服工作台。下面是一个典型的环信客户工作台的示意图,你可以看到,这里有几十项工具,包括快捷回复、人机协作等,它们被设计出来的唯一目的就是让你回答访客的问题更快速更高效!

3.png

 
其次,有人的地方就有管理,有管理就需要各种考核和报表工具。环信客服云有多达几十项的客服考核指标。这些都是企业微信本身不具备的。

4.png

 
 04
使用机器人降本增效

在财务部门对内提供咨询服务的这个场景下,场景收敛,有大量相对简单重复的问题,机器人落地效果已经得到了验证,财务人员被释放出来去做更有价值的工作。当然,这也是有前提的。具体来说,你需要具备以下条件:
1.首先,你需要一个先进的客服机器人产品。比如环信机器人:)
2.你需要进行有质量的财务知识库的建设。关于如何进行高质量的知识库建设,可以联系环信客户经理进行相应的交流沟通和培训。
3.很多财务咨询都需要进行多轮对话并对接业务系统来返回实时数据结果。所以你的机器人产品需要支持多轮对话,还需要可以低成本的快速对接第三方业务系统。
下面是一个典型的员工通过企业微信向财务部门咨询问题,由财务机器人来回答问题的截图:

5.png

 同时,使用机器人还可以做到7X24小时不间断的财务服务。比如,下班时间,可以设置为完全由机器人接待。上班时间所有的进线咨询优先由机器人接待,机器人解决不了的问题,再转人工。如果可以做到30%的转人工率(大部分使用环信机器人的客户是可以达到这个转人工率的),那就意味着帮助财务部门节省了70%的人工。转人工时,还可以设置转给特定的技能组并安排一个排班接待制度,这样财务部门就可以按照自己的方式来实现资源的最佳调配。
TIPS:近期权威机构发布的《2019人工智能客服平台排行榜》,环信稳居智能客服行业榜首哦!同时,环信机器人将定期举行线上培训。如果你希望把企业微信机器人用好,真正帮助到财务部门的小姐姐们,建议你参加“环信机器人使用进阶”和“环信机器人知识库调优最佳实践”这2个培训。请联系你的环信客户经理或者留言免费报名。
0
评论

【公开课预告】如何更好的使用环信机器人 机器人 环信

开发讨论beyond 发表了文章 • 388 次浏览 • 2020-05-12 10:19 • 来自相关话题

时间:2020年5月15日下午15:00
时长:半小时
课程主题:如何更好的使用环信机器人
主讲人:环信AI训练师 赵星星
               
课程介绍:
1.培训对象:环信机器人运营人员。已掌握最基本的机器人操作能力,希望进一步提升机器人的使用效果,让机器人为企业创造更大价值
 
2.难度级别:中级
 3.培训要达成的目标:
A.机器人平台日常使用技能的查缺补漏及部分高级技能
B.成为创建及维护机器人知识库的专家
C.理解机器人的关键运营指标
D.知识库调优
 4.培训大纲:
A.如何快速启动环信机器人:机器人平台日常使用技能的查缺补漏及部分高级技能
B.学会搭建完善的知识库
C.懂得知识运营六大关键指标体系
D.监控日常运营的那些数据-数据管理
E.怎么调优知识库-服务优化
 
参考网址:http://docs-ai.easemob.com/cs/start 
 点击链接直接加入会议:
https://meeting.tencent.com/s/51uTAmIf21b2 
会议 ID:979 281 483
 手机一键拨号入会
+8675536550000,,979281483# (中国大陆)
+85230018898,,,2,979281483# (中国香港)
根据您的位置拨号
+8675536550000 (中国大陆)
+85230018898 (中国香港)
  查看全部

时间:2020年5月15日下午15:00
时长:半小时
课程主题:如何更好的使用环信机器人
主讲人:环信AI训练师 赵星星
               
课程介绍:
1.培训对象:环信机器人运营人员。已掌握最基本的机器人操作能力,希望进一步提升机器人的使用效果,让机器人为企业创造更大价值
 
2.难度级别:中级
 3.培训要达成的目标:
A.机器人平台日常使用技能的查缺补漏及部分高级技能
B.成为创建及维护机器人知识库的专家
C.理解机器人的关键运营指标
D.知识库调优
 4.培训大纲:
A.如何快速启动环信机器人:机器人平台日常使用技能的查缺补漏及部分高级技能
B.学会搭建完善的知识库
C.懂得知识运营六大关键指标体系
D.监控日常运营的那些数据-数据管理
E.怎么调优知识库-服务优化
 
参考网址:http://docs-ai.easemob.com/cs/start 
 点击链接直接加入会议:
https://meeting.tencent.com/s/51uTAmIf21b2 
会议 ID:979 281 483
 手机一键拨号入会
+8675536550000,,979281483# (中国大陆)
+85230018898,,,2,979281483# (中国香港)
根据您的位置拨号
+8675536550000 (中国大陆)
+85230018898 (中国香港)
 
0
评论

(客服云)APNs推送收不到怎么办? 离线推送

开发讨论kijieoeew 发表了文章 • 511 次浏览 • 2020-03-25 15:47 • 来自相关话题

集成离线推送,一次就Pass很难得,难免有收不到的情况。没有头绪的时候请不要着急,按照下面步骤一步一步进行排查:
 
0、如果您app的离线推送之前可以,现在收不到了,请您先移步苹果开发者中心查看推送证书是否过期哦。如果过期了,一般会被封禁,需要联系我们这边进行解封操作。

1、首先已经按照文档集成了离线推送:APNs离线推送
 
2、如果是iOS13及以上的系统,那么需要将IM SDK更新到3.6.4或以上版本,客服SDK更新到1.2.5或以上版本。
   (Hyphenate、HyphenateLite 是 IM SDK,HelpDesk、HelpDeskLite 是客服SDK)
     如果更新后还不行那么退出登录、重启app、再登录试下。
 
     初始化sdk成功之后打印版本号:
     NSString *kfVer = [HDClient sharedClient].sdkVersion;
     NSString *imVer = [HDClient sharedClient].imSdkVersion;

3、测试APNs推送的时候,接收方的APP需要是杀死状态,需要用户长连接断开才会发APNs推送;
     直接上划杀死APP测试。
 
4、请确保导出p12时使用的Mac和创建CertificateSigningRequest.certSigningRequest文件的Mac是同一台,导出证书的时候要直接点击导出,不要点击秘钥的内容导出,确认APP ID是否带有推送功能;

5、环信管理后台上传证书时填写的Bundle ID须与工程中的Bundle ID、推送证书的APP ID相同;选择的证书类型须与推送证书的环境一致;导出.p12文件需要设置密码,并在上传管理后台时传入;

关于环信管理后台,这里有话要说:
登录客服系统,来到 管理员模式--渠道管理--手机APP 页面,
如果手机APP里的【直接登录IM关联后台】按钮可点击,那这个app关联就是快速创建的,点击【直接登录IM关联后台】按钮进入管理后台上传
如果手机APP里的【直接登录IM关联后台】按钮不可点击,那这个app关联就是手动关联的,要到IM的Console后台上传证书,地址:https://console.easemob.com/user/login

6、工程中初始化SDK那里填的证书名与环信管理后台上传的证书名称必须是相同的;

7、Xcode直接运行安装是development环境,需要使用development环境的推送证书,IPA后是production环境,需要使用production环境的推送证书;

8、APP杀死后至环信管理后台对应的应用下查看登录的用户ID,确认证书名称是否有绑定(绑定后会显示推送证书名称);还需要确认绑定的证书名称和管理后台上传的证书名称是否一致。
如果没绑定上,那么退出登录重新登录再试下。
如果证书名称不一致,改正过来后重新登录试下。

快速创建的:




手动关联的:




 
9、如果以上都确认无误,可以联系我们排查。需提供以下信息(请勿遗漏,以免反复询问耽误您的时间):
     appkey、devicetoken、bundle id、证书的.p12文件、证书名称、证书密码、收不到推送的环信id、测试的环境(development or production)、测试推送消息的内容、发送的时间 查看全部
集成离线推送,一次就Pass很难得,难免有收不到的情况。没有头绪的时候请不要着急,按照下面步骤一步一步进行排查:
 
0、如果您app的离线推送之前可以,现在收不到了,请您先移步苹果开发者中心查看推送证书是否过期哦。如果过期了,一般会被封禁,需要联系我们这边进行解封操作。

1、首先已经按照文档集成了离线推送:APNs离线推送
 
2、如果是iOS13及以上的系统,那么需要将IM SDK更新到3.6.4或以上版本,客服SDK更新到1.2.5或以上版本。
   (Hyphenate、HyphenateLite 是 IM SDK,HelpDesk、HelpDeskLite 是客服SDK)
     如果更新后还不行那么退出登录、重启app、再登录试下。
 
     初始化sdk成功之后打印版本号:
     NSString *kfVer = [HDClient sharedClient].sdkVersion;
     NSString *imVer = [HDClient sharedClient].imSdkVersion;

3、测试APNs推送的时候,接收方的APP需要是杀死状态,需要用户长连接断开才会发APNs推送;
     直接上划杀死APP测试。
 
4、请确保导出p12时使用的Mac和创建CertificateSigningRequest.certSigningRequest文件的Mac是同一台,导出证书的时候要直接点击导出,不要点击秘钥的内容导出,确认APP ID是否带有推送功能;

5、环信管理后台上传证书时填写的Bundle ID须与工程中的Bundle ID、推送证书的APP ID相同;选择的证书类型须与推送证书的环境一致;导出.p12文件需要设置密码,并在上传管理后台时传入;

关于环信管理后台,这里有话要说:
登录客服系统,来到 管理员模式--渠道管理--手机APP 页面,
如果手机APP里的【直接登录IM关联后台】按钮可点击,那这个app关联就是快速创建的,点击【直接登录IM关联后台】按钮进入管理后台上传
如果手机APP里的【直接登录IM关联后台】按钮不可点击,那这个app关联就是手动关联的,要到IM的Console后台上传证书,地址:https://console.easemob.com/user/login

6、工程中初始化SDK那里填的证书名与环信管理后台上传的证书名称必须是相同的;

7、Xcode直接运行安装是development环境,需要使用development环境的推送证书,IPA后是production环境,需要使用production环境的推送证书;

8、APP杀死后至环信管理后台对应的应用下查看登录的用户ID,确认证书名称是否有绑定(绑定后会显示推送证书名称);还需要确认绑定的证书名称和管理后台上传的证书名称是否一致。
如果没绑定上,那么退出登录重新登录再试下。
如果证书名称不一致,改正过来后重新登录试下。

快速创建的:
客服管理后台.png

手动关联的:
console管理后台.png

 
9、如果以上都确认无误,可以联系我们排查。需提供以下信息(请勿遗漏,以免反复询问耽误您的时间):
     appkey、devicetoken、bundle id、证书的.p12文件、证书名称、证书密码、收不到推送的环信id、测试的环境(development or production)、测试推送消息的内容、发送的时间
0
评论

微信公众号客服系统,有哪些功能? 微信公众号

开发讨论ds_ 发表了文章 • 596 次浏览 • 2020-03-20 14:45 • 来自相关话题

对于企业而言,微信公众号在用户获取和服务方面发挥着重大作用,那么有没有好用的公众号运营工具来辅助粉丝运营呢,不仅仅解决沟通而已,还承担着私域流量,后续转化等。

公众号怎么接入客服系统?哪些亮点功能提示运营/服务效率?

本文将从七大能力说明
一、及时沟通能力
二、主动营销能力
三、增强运营能力
四、推广分析能力
五、用户管理能力
六、客服协同能力
七、数据分析能力
 
使用公众号客服系统的三种方法
 
微信公众号后台提供的客服功能插件自主开发的客服系统通过微信接口接入的第三方客服系统

使用微信内置客服简单,功能较基础(如只能在电脑上回复,没有消息提醒等),只能满足基本的沟通需求,想要更多功能除了自主开发(成本过大,时间较长),第三方在线客服系统是一个比较合适的方法。
 
公众号如何接入客服系统?
 
对运营来说,使用公众号管理员微信账号扫码授权,即可轻松完成接入。不需要开发,不需要下载软件APP等,直接在网页或小程序上使用。

对用户来说,有2种选择。直接在公众号的聊天框聊天,和原来使用习惯一样。或者点击公众号菜单栏中的客服链接咨询(跳转到H5聊天页面)。公众号客服系统的功能优势
 
一、及时沟通能力

消息提醒:再也不怕丢消息了!消息来了第一时间查看
在电脑上,有消息提示音,客服聊天页标签滚动,浏览器右下角弹窗提示消息(显示最新的一条)。一声二提示,一清二楚,轻轻一点,直达接待用户页面。
在手机端上,收到微信模板消息通知,点击卡片即可聊天,避免等待时间太长,漏回等造成粉丝流失。

手机回复:摆脱电脑限制,用手机可以随时随地在线回复粉丝消息

沟通丰富:支持发送文字,图片、图文链接、H5、表情,语音,视频,快捷回复,微信素材,文件传输等多种消息形式,满足与用户的交流需求,全方位展示产品与服务。

快捷回复:让消息问候等常用语,一触即发,更快的到达用户面前,让客服告别以往的文档复制粘贴,减轻已经很繁琐的工作,沟通更便捷高效。可分为公共回复,个人回复。支持归类、编辑、查询等操作。

微信素材:客服在电脑手机上,支持发送微信公众号素材,自动回复也支持。

邀请粉丝评价:客服发出邀请,用户可评价。就像淘宝外卖等评分一样,从用户感受,客服服务中,找到进步的地方。

聊天记录长期保存:公众平台消息只能保存5天,可实现消息记录和用户数据长期保存,方便随时查阅,全面了解客户跟进情况。

多渠道接入+统一后台处理消息:支持订阅号,服务号,小程序,APP,网站等,后台统一管理多个渠道的用户消息和管理工作,快速回复,提高工作效率。

二、主动营销能力

触发会话:主动邀请粉丝对话。对粉丝在公众号的行为(粉丝关注,粉丝扫码,粉丝点击菜单,粉丝上传位置)追踪记录,在客服端会触发一个对话窗口进入聊天界面,实时提醒与粉丝沟通,不错过任何一次互动机会,大幅提升粉丝体验!

群发消息:挖掘用户多次沟通。可群发图文、文字、图片、网址、小程序卡片、智能菜单等消息给48小时内联系的粉丝,支持标签分组群发,活跃粉丝标签群发,定时群发, 延时群发,防骚扰群发等精准推送,帮助公众号推广,小程序推广,召回用户,提升销售转化和复购。让营销更聪明,内容运营更精细!

模板消息:向用户主动推送提醒,不用选择发短信打电话等节省推广费用。没有48小时限制,不占用群发次数,跳转到指定页面(外链/小程序页面),插入粉丝昵称,自定义文字颜色,加入表情,按多标签/用户openid等精准群发,个性化的模板消息推送,可以有效拉进与用户的距离,提高打开率。

三、增强运营能力

自动回复:芝麻小客服后台可设置公众号被关注回复小程序卡片,多条消息等

自定义菜单:超过公众号菜单栏名字限制达到5个字,点菜单栏可以回复多条消息,记录行为唤醒粉丝,点对应菜单咨询相关客服让交流更高效

智能引导菜单:粉丝不需要用户手动输入关键词,就可以更快速的查看所需内容,解决复杂的业务咨询,提高接待体验,让用户后续轻松咨询。

四、推广分析能力

谈私域流量,找到一个值得精准投放的好渠道,来源透明化、信息营销化,统计即时化。

小客服支持生成不限数量的参数二维码,可以给每个推广渠道设置一个专用的二维码,自定义设置扫码回复的话术,粉丝扫码被自动打上标签,可以精确统计每个粉丝的来源渠道,随时查看粉丝增长来源报表,优化分析投放效果,再选择优质的推广渠道,节省成本。

追踪粉丝来源、监测渠道效果、多渠道消息推送、实现病毒推广,后续粉丝精细化运营,跟踪维护,留存唤醒。

五、用户管理能力

用户标签:根据用户信息,聊天信息,对粉丝进行多维度的精细化标签分类(年龄,性别,备注等),细化粉丝画像以及用户管理。

会话标签:客服通过会话分类标签,可主动记录用户问题,更加系统的知道用户到底在意点,统一筛选查看!

六、客服协同能力

当一个用户进入咨询页面时,系统会按什么的方式让客服来接待?多客服,一对一,在线离线,客服人员怎么管理?客户来自哪个公众号?

多客服管理:可添加多个客服,在线协同解决问题

智能接待分配:根据实际需求选择合适的接待方式。销售线索优先,熟客分配,客服空闲,客轮流分配,补齐分配,按权重分配,来源分配等

系统回复:例如提示客户被接待,前面咨询有多少人,对话结束,工作时间等,提升用户体验感,让用户理解客服,更加人性化,减少双方不确定的交流。

转人工客服:当客服接待不过来时,可以转人工(有提示语),人工客服以服务有需求的用户为主,减轻工作压力,节省企业成本。只有当客户输入特定的关键字才能触发人工客服接入,服务咨询更有针对性。

同事会话:管理员实时看所有客服(或指定客服)的接待情况,客服帮其他客服回复消息,以及帮管理员回复

转接客服:当客服遇到无法解决的问题或临时有事无法提供客服服务时,可以将客户转接给其他客服人员以解决客户问题。寻求同事帮助,跨部门协同,上级反馈等。聊天记录/客户资料共享。

工单系统:当客服没有及时解决用户的问题,可利用客服系统的工单处理机制,提交一张工单给相关部门/团队来解决客户问题,按优先级划分、多部门协调处理。工单系统像一个问题追踪器,能很清晰的追踪,处理和归类问题,让客户问题得到高效满意解决。

七、数据分析能力

客服了解自己的工作情况,管理员多维度的查看各项数据,查看满意度评价等数据分析,制定当前公众号客服的运营策略。

小客服能够通过分析客服工作量在一定时间内的工作量,考勤,接待量、会话详情、客户排队统计、平均响应时长、解决时长、满意度统计等数据,帮助企业实时掌控客服工作状况,及时发现问题并作出调整,也能够为客服人员的绩效考核提供依据。

以上就是公众号客服系统的七大能力分析。 查看全部
对于企业而言,微信公众号在用户获取和服务方面发挥着重大作用,那么有没有好用的公众号运营工具来辅助粉丝运营呢,不仅仅解决沟通而已,还承担着私域流量,后续转化等

公众号怎么接入客服系统?哪些亮点功能提示运营/服务效率?

本文将从七大能力说明
一、及时沟通能力
二、主动营销能力
三、增强运营能力
四、推广分析能力
五、用户管理能力
六、客服协同能力
七、数据分析能力

 
使用公众号客服系统的三种方法
 
  • 微信公众号后台提供的客服功能插件
  • 自主开发的客服系统
  • 通过微信接口接入的第三方客服系统


使用微信内置客服简单,功能较基础(如只能在电脑上回复,没有消息提醒等),只能满足基本的沟通需求,想要更多功能除了自主开发(成本过大,时间较长),第三方在线客服系统是一个比较合适的方法。
 
公众号如何接入客服系统?
 
对运营来说,使用公众号管理员微信账号扫码授权,即可轻松完成接入。不需要开发,不需要下载软件APP等,直接在网页或小程序上使用。

对用户来说,有2种选择。直接在公众号的聊天框聊天,和原来使用习惯一样。或者点击公众号菜单栏中的客服链接咨询(跳转到H5聊天页面)。公众号客服系统的功能优势
 
一、及时沟通能力

消息提醒:再也不怕丢消息了!消息来了第一时间查看
在电脑上,有消息提示音,客服聊天页标签滚动,浏览器右下角弹窗提示消息(显示最新的一条)。一声二提示,一清二楚,轻轻一点,直达接待用户页面。
在手机端上,收到微信模板消息通知,点击卡片即可聊天,避免等待时间太长,漏回等造成粉丝流失。

手机回复:摆脱电脑限制,用手机可以随时随地在线回复粉丝消息

沟通丰富:支持发送文字,图片、图文链接、H5、表情,语音,视频,快捷回复,微信素材,文件传输等多种消息形式,满足与用户的交流需求,全方位展示产品与服务。

快捷回复:让消息问候等常用语,一触即发,更快的到达用户面前,让客服告别以往的文档复制粘贴,减轻已经很繁琐的工作,沟通更便捷高效。可分为公共回复,个人回复。支持归类、编辑、查询等操作。

微信素材:客服在电脑手机上,支持发送微信公众号素材,自动回复也支持。

邀请粉丝评价:客服发出邀请,用户可评价。就像淘宝外卖等评分一样,从用户感受,客服服务中,找到进步的地方。

聊天记录长期保存:公众平台消息只能保存5天,可实现消息记录和用户数据长期保存,方便随时查阅,全面了解客户跟进情况。

多渠道接入+统一后台处理消息:支持订阅号,服务号,小程序,APP,网站等,后台统一管理多个渠道的用户消息和管理工作,快速回复,提高工作效率。

二、主动营销能力

触发会话:主动邀请粉丝对话。对粉丝在公众号的行为(粉丝关注,粉丝扫码,粉丝点击菜单,粉丝上传位置)追踪记录,在客服端会触发一个对话窗口进入聊天界面,实时提醒与粉丝沟通,不错过任何一次互动机会,大幅提升粉丝体验!

群发消息:挖掘用户多次沟通。可群发图文、文字、图片、网址、小程序卡片、智能菜单等消息给48小时内联系的粉丝,支持标签分组群发,活跃粉丝标签群发,定时群发, 延时群发,防骚扰群发等精准推送,帮助公众号推广,小程序推广,召回用户,提升销售转化和复购。让营销更聪明,内容运营更精细!

模板消息:向用户主动推送提醒,不用选择发短信打电话等节省推广费用。没有48小时限制,不占用群发次数,跳转到指定页面(外链/小程序页面),插入粉丝昵称,自定义文字颜色,加入表情,按多标签/用户openid等精准群发,个性化的模板消息推送,可以有效拉进与用户的距离,提高打开率。

三、增强运营能力

自动回复:芝麻小客服后台可设置公众号被关注回复小程序卡片,多条消息等

自定义菜单:超过公众号菜单栏名字限制达到5个字,点菜单栏可以回复多条消息,记录行为唤醒粉丝,点对应菜单咨询相关客服让交流更高效

智能引导菜单:粉丝不需要用户手动输入关键词,就可以更快速的查看所需内容,解决复杂的业务咨询,提高接待体验,让用户后续轻松咨询。

四、推广分析能力

谈私域流量,找到一个值得精准投放的好渠道,来源透明化、信息营销化,统计即时化。

小客服支持生成不限数量的参数二维码,可以给每个推广渠道设置一个专用的二维码,自定义设置扫码回复的话术,粉丝扫码被自动打上标签,可以精确统计每个粉丝的来源渠道,随时查看粉丝增长来源报表,优化分析投放效果,再选择优质的推广渠道,节省成本。

追踪粉丝来源、监测渠道效果、多渠道消息推送、实现病毒推广,后续粉丝精细化运营,跟踪维护,留存唤醒。

五、用户管理能力

用户标签:根据用户信息,聊天信息,对粉丝进行多维度的精细化标签分类(年龄,性别,备注等),细化粉丝画像以及用户管理。

会话标签:客服通过会话分类标签,可主动记录用户问题,更加系统的知道用户到底在意点,统一筛选查看!

六、客服协同能力

当一个用户进入咨询页面时,系统会按什么的方式让客服来接待?多客服,一对一,在线离线,客服人员怎么管理?客户来自哪个公众号?

多客服管理:可添加多个客服,在线协同解决问题

智能接待分配:根据实际需求选择合适的接待方式。销售线索优先,熟客分配,客服空闲,客轮流分配,补齐分配,按权重分配,来源分配等

系统回复:例如提示客户被接待,前面咨询有多少人,对话结束,工作时间等,提升用户体验感,让用户理解客服,更加人性化,减少双方不确定的交流。

转人工客服:当客服接待不过来时,可以转人工(有提示语),人工客服以服务有需求的用户为主,减轻工作压力,节省企业成本。只有当客户输入特定的关键字才能触发人工客服接入,服务咨询更有针对性。

同事会话:管理员实时看所有客服(或指定客服)的接待情况,客服帮其他客服回复消息,以及帮管理员回复

转接客服:当客服遇到无法解决的问题或临时有事无法提供客服服务时,可以将客户转接给其他客服人员以解决客户问题。寻求同事帮助,跨部门协同,上级反馈等。聊天记录/客户资料共享。

工单系统:当客服没有及时解决用户的问题,可利用客服系统的工单处理机制,提交一张工单给相关部门/团队来解决客户问题,按优先级划分、多部门协调处理。工单系统像一个问题追踪器,能很清晰的追踪,处理和归类问题,让客户问题得到高效满意解决。

七、数据分析能力

客服了解自己的工作情况,管理员多维度的查看各项数据,查看满意度评价等数据分析,制定当前公众号客服的运营策略。

小客服能够通过分析客服工作量在一定时间内的工作量,考勤,接待量、会话详情、客户排队统计、平均响应时长、解决时长、满意度统计等数据,帮助企业实时掌控客服工作状况,及时发现问题并作出调整,也能够为客服人员的绩效考核提供依据。

以上就是公众号客服系统的七大能力分析。
0
评论

科普:QUIC协议原理分析 QUIC协议

开发讨论beyond 发表了文章 • 707 次浏览 • 2019-11-29 18:33 • 来自相关话题

作者介绍:罗成,腾讯资深研发工程师。目前主要负责腾讯 stgw(腾讯安全云网关)的相关工作,整体推进腾讯内部及腾讯公有云,混合云的七层负载均衡及全站 HTTPS 接入。对 HTTPS,SPDY,HTTP2,QUIC 等应用层协议、高性能服务器技术、云网络技术、用户访问速度、分布式文件传输等有较深的理解。

本文主要介绍 QUIC 协议产生的背景和核心特性。

写在前面

如果你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度。特别是弱网络的时候能够提升 20% 以上的访问速度。

如果你的 App,在频繁切换 4G 和 WIFI 网络的情况下,不会断线,不需要重连,用户无任何感知。如果你的 App,既需要 TLS 的安全,也想实现 HTTP2 多路复用的强大。

如果你刚刚才听说 HTTP2 是下一代互联网协议,如果你刚刚才关注到 TLS1.3 是一个革命性具有里程碑意义的协议,但是这两个协议却一直在被另一个更新兴的协议所影响和挑战。

如果这个新兴的协议,它的名字就叫做“快”,并且正在标准化为新一代的互联网传输协议。

你愿意花一点点时间了解这个协议吗?你愿意投入精力去研究这个协议吗?你愿意全力推动业务来使用这个协议吗?

QUIC 概述

Quic 全称 quick udp internet connection [1],“快速 UDP 互联网连接”,(和英文 quick 谐音,简称“快”)是由 google 提出的使用 udp 进行多路并发传输的协议。

Quic 相比现在广泛应用的 http2+tcp+tls 协议有如下优势 [2]:

减少了 TCP 三次握手及 TLS 握手时间。

改进的拥塞控制。

避免队头阻塞的多路复用。

连接迁移。

前向冗余纠错。

为什么需要 QUIC

从上个世纪 90 年代互联网开始兴起一直到现在,大部分的互联网流量传输只使用了几个网络协议。使用 IPv4 进行路由,使用 TCP 进行连接层面的流量控制,使用 SSL/TLS 协议实现传输安全,使用 DNS 进行域名解析,使用 HTTP 进行应用数据的传输。

而且近三十年来,这几个协议的发展都非常缓慢。TCP 主要是拥塞控制算法的改进,SSL/TLS 基本上停留在原地,几个小版本的改动主要是密码套件的升级,TLS1.3[3] 是一个飞跃式的变化,但截止到今天,还没有正式发布。IPv4 虽然有一个大的进步,实现了 IPv6,DNS 也增加了一个安全的 DNSSEC,但和 IPv6 一样,部署进度较慢。

随着移动互联网快速发展以及物联网的逐步兴起,网络交互的场景越来越丰富,网络传输的内容也越来越庞大,用户对网络传输效率和 WEB 响应速度的要求也越来越高。

一方面是历史悠久使用广泛的古老协议,另外一方面用户的使用场景对传输性能的要求又越来越高。如下几个由来已久的问题和矛盾就变得越来越突出。

协议历史悠久导致中间设备僵化。

依赖于操作系统的实现导致协议本身僵化。

建立连接的握手延迟大。

队头阻塞。

这里分小节简单说明一下:

中间设备的僵化

可能是 TCP 协议使用得太久,也非常可靠。所以我们很多中间设备,包括防火墙、NAT 网关,整流器等出现了一些约定俗成的动作。

比如有些防火墙只允许通过 80 和 443,不放通其他端口。NAT 网关在转换网络地址时重写传输层的头部,有可能导致双方无法使用新的传输格式。整流器和中间代理有时候出于安全的需要,会删除一些它们不认识的选项字段。

TCP 协议本来是支持端口、选项及特性的增加和修改。但是由于 TCP 协议和知名端口及选项使用的历史太悠久,中间设备已经依赖于这些潜规则,所以对这些内容的修改很容易遭到中间环节的干扰而失败。

而这些干扰,也导致很多在 TCP 协议上的优化变得小心谨慎,步履维艰。

依赖于操作系统的实现导致协议僵化

TCP 是由操作系统在内核西方栈层面实现的,应用程序只能使用,不能直接修改。虽然应用程序的更新迭代非常快速和简单。但是 TCP 的迭代却非常缓慢,原因就是操作系统升级很麻烦。

现在移动终端更加流行,但是移动端部分用户的操作系统升级依然可能滞后数年时间。PC 端的系统升级滞后得更加严重,windows xp 现在还有大量用户在使用,尽管它已经存在快 20 年。

服务端系统不依赖用户升级,但是由于操作系统升级涉及到底层软件和运行库的更新,所以也比较保守和缓慢。

这也就意味着即使 TCP 有比较好的特性更新,也很难快速推广。比如 TCP Fast Open。它虽然 2013 年就被提出了,但是 Windows 很多系统版本依然不支持它。

建立连接的握手延迟大

不管是 HTTP1.0/1.1 还是 HTTPS,HTTP2,都使用了 TCP 进行传输。HTTPS 和 HTTP2 还需要使用 TLS 协议来进行安全传输。这就出现了两个握手延迟:

1.TCP 三次握手导致的 TCP 连接建立的延迟。

2.TLS 完全握手需要至少 2 个 RTT 才能建立,简化握手需要 1 个 RTT 的握手延迟。

对于很多短连接场景,这样的握手延迟影响很大,且无法消除。

队头阻塞

队头阻塞主要是 TCP 协议的可靠性机制引入的。TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,如果前面的数据丢失,后面的数据就算到达了也不会通知应用层来处理。

另外 TLS 协议层面也有一个队头阻塞,因为 TLS 协议都是按照 record 来处理数据的,如果一个 record 中丢失了数据,也会导致整个 record 无法正确处理。

概括来讲,TCP 和 TLS1.2 之前的协议存在着结构性的问题,如果继续在现有的 TCP、TLS 协议之上实现一个全新的应用层协议,依赖于操作系统、中间设备还有用户的支持。部署成本非常高,阻力非常大。

所以 QUIC 协议选择了 UDP,因为 UDP 本身没有连接的概念,不需要三次握手,优化了连接建立的握手延迟,同时在应用程序层面实现了 TCP 的可靠性,TLS 的安全性和 HTTP2 的并发性,只需要用户端和服务端的应用程序支持 QUIC 协议,完全避开了操作系统和中间设备的限制。

QUIC 核心特性连接建立延时低

0RTT 建连可以说是 QUIC 相比 HTTP2 最大的性能优势。那什么是 0RTT 建连呢?这里面有两层含义。

传输层 0RTT 就能建立连接。
加密层 0RTT 就能建立加密连接。





 
图 1 HTTPS 及 QUIC 建连过程
比如上图左边是 HTTPS 的一次完全握手的建连过程,需要 3 个 RTT。就算是 Session Resumption[14],也需要至少 2 个 RTT。
而 QUIC 呢?由于建立在 UDP 的基础上,同时又实现了 0RTT 的安全握手,所以在大部分情况下,只需要 0 个 RTT 就能实现数据发送,在实现前向加密 [15] 的基础上,并且 0RTT 的成功率相比 TLS 的 Sesison Ticket[13] 要高很多。

改进的拥塞控制

TCP 的拥塞控制实际上包含了四个算法:慢启动,拥塞避免,快速重传,快速恢复 [22]。

QUIC 协议当前默认使用了 TCP 协议的 Cubic 拥塞控制算法 [6],同时也支持 CubicBytes, Reno, RenoBytes, BBR, PCC 等拥塞控制算法。

从拥塞算法本身来看,QUIC 只是按照 TCP 协议重新实现了一遍,那么 QUIC 协议到底改进在哪些方面呢?主要有如下几点:

可插拔

什么叫可插拔呢?就是能够非常灵活地生效,变更和停止。体现在如下方面:

应用程序层面就能实现不同的拥塞控制算法,不需要操作系统,不需要内核支持。这是一个飞跃,因为传统的 TCP 拥塞控制,必须要端到端的网络协议栈支持,才能实现控制效果。而内核和操作系统的部署成本非常高,升级周期很长,这在产品快速迭代,网络爆炸式增长的今天,显然有点满足不了需求。

即使是单个应用程序的不同连接也能支持配置不同的拥塞控制。就算是一台服务器,接入的用户网络环境也千差万别,结合大数据及人工智能处理,我们能为各个用户提供不同的但又更加精准更加有效的拥塞控制。比如 BBR 适合,Cubic 适合。

应用程序不需要停机和升级就能实现拥塞控制的变更,我们在服务端只需要修改一下配置,reload 一下,完全不需要停止服务就能实现拥塞控制的切换。

STGW 在配置层面进行了优化,我们可以针对不同业务,不同网络制式,甚至不同的 RTT,使用不同的拥塞控制算法。

单调递增的 Packet Number

TCP 为了保证可靠性,使用了基于字节序号的 Sequence Number 及 Ack 来确认消息的有序到达。
QUIC 同样是一个可靠的协议,它使用 Packet Number 代替了 TCP 的 sequence number,并且每个 Packet Number 都严格递增,也就是说就算 Packet N 丢失了,重传的 Packet N 的 Packet Number 已经不是 N,而是一个比 N 大的值。而 TCP 呢,重传 segment 的 sequence number 和原始的 segment 的 Sequence Number 保持不变,也正是由于这个特性,引入了 Tcp 重传的歧义问题。





 
图 2 Tcp 重传歧义性
如上图所示,超时事件 RTO 发生后,客户端发起重传,然后接收到了 Ack 数据。由于序列号一样,这个 Ack 数据到底是原始请求的响应还是重传请求的响应呢?不好判断。
如果算成原始请求的响应,但实际上是重传请求的响应(上图左),会导致采样 RTT 变大。如果算成重传请求的响应,但实际上是原始请求的响应,又很容易导致采样 RTT 过小。
由于 Quic 重传的 Packet 和原始 Packet 的 Pakcet Number 是严格递增的,所以很容易就解决了这个问题。





 
图 3 Quic 重传没有歧义性
如上图所示,RTO 发生后,根据重传的 Packet Number 就能确定精确的 RTT 计算。如果 Ack 的 Packet Number 是 N+M,就根据重传请求计算采样 RTT。如果 Ack 的 Pakcet Number 是 N,就根据原始请求的时间计算采样 RTT,没有歧义性。
但是单纯依靠严格递增的 Packet Number 肯定是无法保证数据的顺序性和可靠性。QUIC 又引入了一个 Stream Offset 的概念。

即一个 Stream 可以经过多个 Packet 传输,Packet Number 严格递增,没有依赖。但是 Packet 里的 Payload 如果是 Stream 的话,就需要依靠 Stream 的 Offset 来保证应用数据的顺序。如错误! 未找到引用源。所示,发送端先后发送了 Pakcet N 和 Pakcet N+1,Stream 的 Offset 分别是 x 和 x+y。
假设 Packet N 丢失了,发起重传,重传的 Packet Number 是 N+2,但是它的 Stream 的 Offset 依然是 x,这样就算 Packet N + 2 是后到的,依然可以将 Stream x 和 Stream x+y 按照顺序组织起来,交给应用程序处理。





 
图 4 Stream Offset 保证有序性
 
不允许 Reneging
什么叫 Reneging 呢?就是接收方丢弃已经接收并且上报给 SACK 选项的内容 [8]。TCP 协议不鼓励这种行为,但是协议层面允许这样的行为。主要是考虑到服务器资源有限,比如 Buffer 溢出,内存不够等情况。

Reneging 对数据重传会产生很大的干扰。因为 Sack 都已经表明接收到了,但是接收端事实上丢弃了该数据。

QUIC 在协议层面禁止 Reneging,一个 Packet 只要被 Ack,就认为它一定被正确接收,减少了这种干扰。

更多的 Ack 块

TCP 的 Sack 选项能够告诉发送方已经接收到的连续 Segment 的范围,方便发送方进行选择性重传。

由于 TCP 头部最大只有 60 个字节,标准头部占用了 20 字节,所以 Tcp Option 最大长度只有 40 字节,再加上 Tcp Timestamp option 占用了 10 个字节 [25],所以留给 Sack 选项的只有 30 个字节。

每一个 Sack Block 的长度是 8 个,加上 Sack Option 头部 2 个字节,也就意味着 Tcp Sack Option 最大只能提供 3 个 Block。

但是 Quic Ack Frame 可以同时提供 256 个 Ack Block,在丢包率比较高的网络下,更多的 Sack Block 可以提升网络的恢复速度,减少重传量。

Ack Delay 时间

Tcp 的 Timestamp 选项存在一个问题 [25],它只是回显了发送方的时间戳,但是没有计算接收端接收到 segment 到发送 Ack 该 segment 的时间。这个时间可以简称为 Ack Delay。
这样就会导致 RTT 计算误差。如下图:





 可以认为 TCP 的 RTT 计算:






而 Quic 计算如下:






当然 RTT 的具体计算没有这么简单,需要采样,参考历史数值进行平滑计算,参考如下公式 [9]。






基于 stream 和 connecton 级别的流量控制

QUIC 的流量控制 [22] 类似 HTTP2,即在 Connection 和 Stream 级别提供了两种流量控制。为什么需要两类流量控制呢?主要是因为 QUIC 支持多路复用。

Stream 可以认为就是一条 HTTP 请求。

Connection 可以类比一条 TCP 连接。多路复用意味着在一条 Connetion 上会同时存在多条 Stream。既需要对单个 Stream 进行控制,又需要针对所有 Stream 进行总体控制。

QUIC 实现流量控制的原理比较简单:

通过 window_update 帧告诉对端自己可以接收的字节数,这样发送方就不会发送超过这个数量的数据。

通过 BlockFrame 告诉对端由于流量控制被阻塞了,无法发送数据。

QUIC 的流量控制和 TCP 有点区别,TCP 为了保证可靠性,窗口左边沿向右滑动时的长度取决于已经确认的字节数。如果中间出现丢包,就算接收到了更大序号的 Segment,窗口也无法超过这个序列号。
但 QUIC 不同,就算此前有些 packet 没有接收到,它的滑动只取决于接收到的最大偏移字节数。





 
图 5 Quic Flow Control针对 Stream:





针对 Connection:






同样地,STGW 也在连接和 Stream 级别设置了不同的窗口数。

最重要的是,我们可以在内存不足或者上游处理性能出现问题时,通过流量控制来限制传输速率,保障服务可用性。

没有队头阻塞的多路复用

QUIC 的多路复用和 HTTP2 类似。在一条 QUIC 连接上可以并发发送多个 HTTP 请求 (stream)。但是 QUIC 的多路复用相比 HTTP2 有一个很大的优势。

QUIC 一个连接上的多个 stream 之间没有依赖。这样假如 stream2 丢了一个 udp packet,也只会影响 stream2 的处理。不会影响 stream2 之前及之后的 stream 的处理。

这也就在很大程度上缓解甚至消除了队头阻塞的影响。
多路复用是 HTTP2 最强大的特性 [7],能够将多条请求在一条 TCP 连接上同时发出去。但也恶化了 TCP 的一个问题,队头阻塞 [11],如下图示:





 
图 6 HTTP2 队头阻塞
HTTP2 在一个 TCP 连接上同时发送 4 个 Stream。其中 Stream1 已经正确到达,并被应用层读取。但是 Stream2 的第三个 tcp segment 丢失了,TCP 为了保证数据的可靠性,需要发送端重传第 3 个 segment 才能通知应用层读取接下去的数据,虽然这个时候 Stream3 和 Stream4 的全部数据已经到达了接收端,但都被阻塞住了。 
不仅如此,由于 HTTP2 强制使用 TLS,还存在一个 TLS 协议层面的队头阻塞 [12]。





 
图 7 TLS 队头阻塞
Record 是 TLS 协议处理的最小单位,最大不能超过 16K,一些服务器比如 Nginx 默认的大小就是 16K。由于一个 record 必须经过数据一致性校验才能进行加解密,所以一个 16K 的 record,就算丢了一个字节,也会导致已经接收到的 15.99K 数据无法处理,因为它不完整。
那 QUIC 多路复用为什么能避免上述问题呢?

QUIC 最基本的传输单元是 Packet,不会超过 MTU 的大小,整个加密和认证过程都是基于 Packet 的,不会跨越多个 Packet。这样就能避免 TLS 协议存在的队头阻塞。
Stream 之间相互独立,比如 Stream2 丢了一个 Pakcet,不会影响 Stream3 和 Stream4。不存在 TCP 队头阻塞。





 
图 8 QUIC 多路复用时没有队头阻塞的问题
当然,并不是所有的 QUIC 数据都不会受到队头阻塞的影响,比如 QUIC 当前也是使用 Hpack 压缩算法 [10],由于算法的限制,丢失一个头部数据时,可能遇到队头阻塞。
总体来说,QUIC 在传输大量数据时,比如视频,受到队头阻塞的影响很小。

加密认证的报文

TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击。

但是 QUIC 的 packet 可以说是武装到了牙齿。除了个别报文比如 PUBLIC_RESET 和 CHLO,所有报文头部都是经过认证的,报文 Body 都是经过加密的。

这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险。

如下图所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,全部经过加密。






连接迁移

一条 TCP 连接 [17] 是由四元组标识的(源 IP,源端口,目的 IP,目的端口)。什么叫连接迁移呢?就是当其中任何一个元素发生变化时,这条连接依然维持着,能够保持业务逻辑不中断。当然这里面主要关注的是客户端的变化,因为客户端不可控并且网络环境经常发生变化,而服务端的 IP 和端口一般都是固定的。

比如大家使用手机在 WIFI 和 4G 移动网络切换时,客户端的 IP 肯定会发生变化,需要重新建立和服务端的 TCP 连接。

又比如大家使用公共 NAT 出口时,有些连接竞争时需要重新绑定端口,导致客户端的端口发生变化,同样需要重新建立 TCP 连接。

针对 TCP 的连接变化,MPTCP[5] 其实已经有了解决方案,但是由于 MPTCP 需要操作系统及网络协议栈支持,部署阻力非常大,目前并不适用。

所以从 TCP 连接的角度来讲,这个问题是无解的。

那 QUIC 是如何做到连接迁移呢?很简单,任何一条 QUIC 连接不再以 IP 及端口四元组标识,而是以一个 64 位的随机数作为 ID 来标识,这样就算 IP 或者端口发生变化时,只要 ID 不变,这条连接依然维持着,上层业务逻辑感知不到变化,不会中断,也就不需要重连。

由于这个 ID 是客户端随机产生的,并且长度有 64 位,所以冲突概率非常低。

其他亮点

此外,QUIC 还能实现前向冗余纠错,在重要的包比如握手消息发生丢失时,能够根据冗余信息还原出握手消息。

QUIC 还能实现证书压缩,减少证书传输量,针对包头进行验证等。

限于篇幅,本文不再详细介绍,有兴趣的可以参考文档 [23] 和文档 [4] 和文档 [26]。

参考线索

[1]. https://www.chromium.org/quic

[2]. https://docs.google.com/docume ... /edit

[3]. E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.3”, draft-ietf-tls-tls13-21, https://tools.ietf.org/html/dr ... 13-21, July 03, 2017

[4]. Adam Langley,Wan-Teh Chang, “QUIC Crypto”,https://docs.google.com/docume ... /edit, 20161206

[5]. https://www.multipath-tcp.org/

[6]. Ha, S., Rhee, I., and L. Xu, "CUBIC: A New TCP-Friendly High-Speed TCP Variant", ACM SIGOPS Operating System Review , 2008.

[7]. M. Belshe,BitGo, R. Peon, “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, May 2015

[8]. M. Mathis,J. Mahdavi,S. Floyd,A. Romanow,“TCP Selective Acknowledgment Options”, rfc2018, https://tools.ietf.org/html/rfc2018, October 1996

[9]. V. Paxson,M. Allman,J. Chu,M. Sargent,“Computing TCP's Retransmission Timer”, rfc6298, https://tools.ietf.org/html/rfc6298, June 2011

[10]. R. Peon,H. Ruellan,“HPACK: Header Compression for HTTP/2”,RFC7541,May 2015

[11]. M. Scharf, Alcatel-Lucent Bell Labs, S. Kiesel, “Quantifying Head-of-Line Blocking in TCP and SCTP”, https://tools.ietf.org/id/draf ... .html, July 15, 2013

[12]. Ilya Grigorik,“Optimizing TLS Record Size & Buffering Latency”, https://www.igvita.com/2013/10 ... ency/, October 24, 2013

[13]. J. Salowey,H. Zhou,P. Eronen,H. Tschofenig, “Transport Layer Security (TLS) Session Resumption without Server-Side State”, RFC5077, January 2008

[14]. Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008, .

[15]. Shirey, R., "Internet Security Glossary, Version 2", FYI , RFC 4949, August 2007

[16]. 罗成,“HTTPS性能优化”, http://www.infoq.com/cn/presen ... https,February.2017

[17]. Postel, J., "Transmission Control Protocol", STD 7, RFC793, September 1981.

[18]. J. Postel,“User Datagram Protocol”, RFC768,August 1980

[19]. Q. Dang, S. Santesson,K. Moriarty,D. Brown.T. Polk, “Internet X.509 Public Key Infrastructure: Additional Algorithms and Identifiers for DSA and ECDSA”,RFC5758, January 2010

[20]. Bassham, L., Polk, W., and R. Housley, "Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3279, April 2002

[21]. D.Cooper,S.Santesson, S.Farrell,S. Boeyen,R. Housley,W.Polk, “Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile”, RFC5280, May 2008

[22]. M. Allman,V. Paxson,E. Blanton, "TCP Congestion Control”,RFC5681, September 2009

[23]. Robbie Shade, “Flow control in QUIC”, https://docs.google.com/docume ... it%23, May, 2016,

[24]. ianswett , “QUIC fec v1”, https://docs.google.com/docume ... tytjt, 2016-02-19

[25]. D.Borman,B.Braden,V.Jacobson,R.Scheffenegger, Ed. “TCP Extensions for High Performance”,rfc7323, https://tools.ietf.org/html/rfc7323,September 2014

[26]. 罗成,“WEB加速,协议先行”, https://zhuanlan.zhihu.com/p/27938635,july, 2017 查看全部
作者介绍:罗成,腾讯资深研发工程师。目前主要负责腾讯 stgw(腾讯安全云网关)的相关工作,整体推进腾讯内部及腾讯公有云,混合云的七层负载均衡及全站 HTTPS 接入。对 HTTPS,SPDY,HTTP2,QUIC 等应用层协议、高性能服务器技术、云网络技术、用户访问速度、分布式文件传输等有较深的理解。

本文主要介绍 QUIC 协议产生的背景和核心特性。

写在前面

如果你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度。特别是弱网络的时候能够提升 20% 以上的访问速度。

如果你的 App,在频繁切换 4G 和 WIFI 网络的情况下,不会断线,不需要重连,用户无任何感知。如果你的 App,既需要 TLS 的安全,也想实现 HTTP2 多路复用的强大。

如果你刚刚才听说 HTTP2 是下一代互联网协议,如果你刚刚才关注到 TLS1.3 是一个革命性具有里程碑意义的协议,但是这两个协议却一直在被另一个更新兴的协议所影响和挑战。

如果这个新兴的协议,它的名字就叫做“快”,并且正在标准化为新一代的互联网传输协议。

你愿意花一点点时间了解这个协议吗?你愿意投入精力去研究这个协议吗?你愿意全力推动业务来使用这个协议吗?

QUIC 概述

Quic 全称 quick udp internet connection [1],“快速 UDP 互联网连接”,(和英文 quick 谐音,简称“快”)是由 google 提出的使用 udp 进行多路并发传输的协议。

Quic 相比现在广泛应用的 http2+tcp+tls 协议有如下优势 [2]:

减少了 TCP 三次握手及 TLS 握手时间。

改进的拥塞控制。

避免队头阻塞的多路复用。

连接迁移。

前向冗余纠错。

为什么需要 QUIC

从上个世纪 90 年代互联网开始兴起一直到现在,大部分的互联网流量传输只使用了几个网络协议。使用 IPv4 进行路由,使用 TCP 进行连接层面的流量控制,使用 SSL/TLS 协议实现传输安全,使用 DNS 进行域名解析,使用 HTTP 进行应用数据的传输。

而且近三十年来,这几个协议的发展都非常缓慢。TCP 主要是拥塞控制算法的改进,SSL/TLS 基本上停留在原地,几个小版本的改动主要是密码套件的升级,TLS1.3[3] 是一个飞跃式的变化,但截止到今天,还没有正式发布。IPv4 虽然有一个大的进步,实现了 IPv6,DNS 也增加了一个安全的 DNSSEC,但和 IPv6 一样,部署进度较慢。

随着移动互联网快速发展以及物联网的逐步兴起,网络交互的场景越来越丰富,网络传输的内容也越来越庞大,用户对网络传输效率和 WEB 响应速度的要求也越来越高。

一方面是历史悠久使用广泛的古老协议,另外一方面用户的使用场景对传输性能的要求又越来越高。如下几个由来已久的问题和矛盾就变得越来越突出。

协议历史悠久导致中间设备僵化。

依赖于操作系统的实现导致协议本身僵化。

建立连接的握手延迟大。

队头阻塞。

这里分小节简单说明一下:

中间设备的僵化

可能是 TCP 协议使用得太久,也非常可靠。所以我们很多中间设备,包括防火墙、NAT 网关,整流器等出现了一些约定俗成的动作。

比如有些防火墙只允许通过 80 和 443,不放通其他端口。NAT 网关在转换网络地址时重写传输层的头部,有可能导致双方无法使用新的传输格式。整流器和中间代理有时候出于安全的需要,会删除一些它们不认识的选项字段。

TCP 协议本来是支持端口、选项及特性的增加和修改。但是由于 TCP 协议和知名端口及选项使用的历史太悠久,中间设备已经依赖于这些潜规则,所以对这些内容的修改很容易遭到中间环节的干扰而失败。

而这些干扰,也导致很多在 TCP 协议上的优化变得小心谨慎,步履维艰。

依赖于操作系统的实现导致协议僵化

TCP 是由操作系统在内核西方栈层面实现的,应用程序只能使用,不能直接修改。虽然应用程序的更新迭代非常快速和简单。但是 TCP 的迭代却非常缓慢,原因就是操作系统升级很麻烦。

现在移动终端更加流行,但是移动端部分用户的操作系统升级依然可能滞后数年时间。PC 端的系统升级滞后得更加严重,windows xp 现在还有大量用户在使用,尽管它已经存在快 20 年。

服务端系统不依赖用户升级,但是由于操作系统升级涉及到底层软件和运行库的更新,所以也比较保守和缓慢。

这也就意味着即使 TCP 有比较好的特性更新,也很难快速推广。比如 TCP Fast Open。它虽然 2013 年就被提出了,但是 Windows 很多系统版本依然不支持它。

建立连接的握手延迟大

不管是 HTTP1.0/1.1 还是 HTTPS,HTTP2,都使用了 TCP 进行传输。HTTPS 和 HTTP2 还需要使用 TLS 协议来进行安全传输。这就出现了两个握手延迟:

1.TCP 三次握手导致的 TCP 连接建立的延迟。

2.TLS 完全握手需要至少 2 个 RTT 才能建立,简化握手需要 1 个 RTT 的握手延迟。

对于很多短连接场景,这样的握手延迟影响很大,且无法消除。

队头阻塞

队头阻塞主要是 TCP 协议的可靠性机制引入的。TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,如果前面的数据丢失,后面的数据就算到达了也不会通知应用层来处理。

另外 TLS 协议层面也有一个队头阻塞,因为 TLS 协议都是按照 record 来处理数据的,如果一个 record 中丢失了数据,也会导致整个 record 无法正确处理。

概括来讲,TCP 和 TLS1.2 之前的协议存在着结构性的问题,如果继续在现有的 TCP、TLS 协议之上实现一个全新的应用层协议,依赖于操作系统、中间设备还有用户的支持。部署成本非常高,阻力非常大。

所以 QUIC 协议选择了 UDP,因为 UDP 本身没有连接的概念,不需要三次握手,优化了连接建立的握手延迟,同时在应用程序层面实现了 TCP 的可靠性,TLS 的安全性和 HTTP2 的并发性,只需要用户端和服务端的应用程序支持 QUIC 协议,完全避开了操作系统和中间设备的限制。

QUIC 核心特性连接建立延时低

0RTT 建连可以说是 QUIC 相比 HTTP2 最大的性能优势。那什么是 0RTT 建连呢?这里面有两层含义。

传输层 0RTT 就能建立连接。
加密层 0RTT 就能建立加密连接。

1.jpg

 
图 1 HTTPS 及 QUIC 建连过程
比如上图左边是 HTTPS 的一次完全握手的建连过程,需要 3 个 RTT。就算是 Session Resumption[14],也需要至少 2 个 RTT。
而 QUIC 呢?由于建立在 UDP 的基础上,同时又实现了 0RTT 的安全握手,所以在大部分情况下,只需要 0 个 RTT 就能实现数据发送,在实现前向加密 [15] 的基础上,并且 0RTT 的成功率相比 TLS 的 Sesison Ticket[13] 要高很多。

改进的拥塞控制

TCP 的拥塞控制实际上包含了四个算法:慢启动,拥塞避免,快速重传,快速恢复 [22]。

QUIC 协议当前默认使用了 TCP 协议的 Cubic 拥塞控制算法 [6],同时也支持 CubicBytes, Reno, RenoBytes, BBR, PCC 等拥塞控制算法。

从拥塞算法本身来看,QUIC 只是按照 TCP 协议重新实现了一遍,那么 QUIC 协议到底改进在哪些方面呢?主要有如下几点:

可插拔

什么叫可插拔呢?就是能够非常灵活地生效,变更和停止。体现在如下方面:

应用程序层面就能实现不同的拥塞控制算法,不需要操作系统,不需要内核支持。这是一个飞跃,因为传统的 TCP 拥塞控制,必须要端到端的网络协议栈支持,才能实现控制效果。而内核和操作系统的部署成本非常高,升级周期很长,这在产品快速迭代,网络爆炸式增长的今天,显然有点满足不了需求。

即使是单个应用程序的不同连接也能支持配置不同的拥塞控制。就算是一台服务器,接入的用户网络环境也千差万别,结合大数据及人工智能处理,我们能为各个用户提供不同的但又更加精准更加有效的拥塞控制。比如 BBR 适合,Cubic 适合。

应用程序不需要停机和升级就能实现拥塞控制的变更,我们在服务端只需要修改一下配置,reload 一下,完全不需要停止服务就能实现拥塞控制的切换。

STGW 在配置层面进行了优化,我们可以针对不同业务,不同网络制式,甚至不同的 RTT,使用不同的拥塞控制算法。

单调递增的 Packet Number

TCP 为了保证可靠性,使用了基于字节序号的 Sequence Number 及 Ack 来确认消息的有序到达。
QUIC 同样是一个可靠的协议,它使用 Packet Number 代替了 TCP 的 sequence number,并且每个 Packet Number 都严格递增,也就是说就算 Packet N 丢失了,重传的 Packet N 的 Packet Number 已经不是 N,而是一个比 N 大的值。而 TCP 呢,重传 segment 的 sequence number 和原始的 segment 的 Sequence Number 保持不变,也正是由于这个特性,引入了 Tcp 重传的歧义问题。

2.jpg

 
图 2 Tcp 重传歧义性
如上图所示,超时事件 RTO 发生后,客户端发起重传,然后接收到了 Ack 数据。由于序列号一样,这个 Ack 数据到底是原始请求的响应还是重传请求的响应呢?不好判断。
如果算成原始请求的响应,但实际上是重传请求的响应(上图左),会导致采样 RTT 变大。如果算成重传请求的响应,但实际上是原始请求的响应,又很容易导致采样 RTT 过小。
由于 Quic 重传的 Packet 和原始 Packet 的 Pakcet Number 是严格递增的,所以很容易就解决了这个问题。

3.jpg

 
图 3 Quic 重传没有歧义性
如上图所示,RTO 发生后,根据重传的 Packet Number 就能确定精确的 RTT 计算。如果 Ack 的 Packet Number 是 N+M,就根据重传请求计算采样 RTT。如果 Ack 的 Pakcet Number 是 N,就根据原始请求的时间计算采样 RTT,没有歧义性。
但是单纯依靠严格递增的 Packet Number 肯定是无法保证数据的顺序性和可靠性。QUIC 又引入了一个 Stream Offset 的概念。

即一个 Stream 可以经过多个 Packet 传输,Packet Number 严格递增,没有依赖。但是 Packet 里的 Payload 如果是 Stream 的话,就需要依靠 Stream 的 Offset 来保证应用数据的顺序。如错误! 未找到引用源。所示,发送端先后发送了 Pakcet N 和 Pakcet N+1,Stream 的 Offset 分别是 x 和 x+y。
假设 Packet N 丢失了,发起重传,重传的 Packet Number 是 N+2,但是它的 Stream 的 Offset 依然是 x,这样就算 Packet N + 2 是后到的,依然可以将 Stream x 和 Stream x+y 按照顺序组织起来,交给应用程序处理。

4.jpg

 
图 4 Stream Offset 保证有序性
 
不允许 Reneging
什么叫 Reneging 呢?就是接收方丢弃已经接收并且上报给 SACK 选项的内容 [8]。TCP 协议不鼓励这种行为,但是协议层面允许这样的行为。主要是考虑到服务器资源有限,比如 Buffer 溢出,内存不够等情况。

Reneging 对数据重传会产生很大的干扰。因为 Sack 都已经表明接收到了,但是接收端事实上丢弃了该数据。

QUIC 在协议层面禁止 Reneging,一个 Packet 只要被 Ack,就认为它一定被正确接收,减少了这种干扰。

更多的 Ack 块

TCP 的 Sack 选项能够告诉发送方已经接收到的连续 Segment 的范围,方便发送方进行选择性重传。

由于 TCP 头部最大只有 60 个字节,标准头部占用了 20 字节,所以 Tcp Option 最大长度只有 40 字节,再加上 Tcp Timestamp option 占用了 10 个字节 [25],所以留给 Sack 选项的只有 30 个字节。

每一个 Sack Block 的长度是 8 个,加上 Sack Option 头部 2 个字节,也就意味着 Tcp Sack Option 最大只能提供 3 个 Block。

但是 Quic Ack Frame 可以同时提供 256 个 Ack Block,在丢包率比较高的网络下,更多的 Sack Block 可以提升网络的恢复速度,减少重传量。

Ack Delay 时间

Tcp 的 Timestamp 选项存在一个问题 [25],它只是回显了发送方的时间戳,但是没有计算接收端接收到 segment 到发送 Ack 该 segment 的时间。这个时间可以简称为 Ack Delay。
这样就会导致 RTT 计算误差。如下图:

5.jpg

 可以认为 TCP 的 RTT 计算:

6.jpg


而 Quic 计算如下:

7.jpg


当然 RTT 的具体计算没有这么简单,需要采样,参考历史数值进行平滑计算,参考如下公式 [9]。

8.jpg


基于 stream 和 connecton 级别的流量控制

QUIC 的流量控制 [22] 类似 HTTP2,即在 Connection 和 Stream 级别提供了两种流量控制。为什么需要两类流量控制呢?主要是因为 QUIC 支持多路复用。

Stream 可以认为就是一条 HTTP 请求。

Connection 可以类比一条 TCP 连接。多路复用意味着在一条 Connetion 上会同时存在多条 Stream。既需要对单个 Stream 进行控制,又需要针对所有 Stream 进行总体控制。

QUIC 实现流量控制的原理比较简单:

通过 window_update 帧告诉对端自己可以接收的字节数,这样发送方就不会发送超过这个数量的数据。

通过 BlockFrame 告诉对端由于流量控制被阻塞了,无法发送数据。

QUIC 的流量控制和 TCP 有点区别,TCP 为了保证可靠性,窗口左边沿向右滑动时的长度取决于已经确认的字节数。如果中间出现丢包,就算接收到了更大序号的 Segment,窗口也无法超过这个序列号。
但 QUIC 不同,就算此前有些 packet 没有接收到,它的滑动只取决于接收到的最大偏移字节数。

9.jpg

 
图 5 Quic Flow Control针对 Stream:
10.jpg


针对 Connection:

11.jpg


同样地,STGW 也在连接和 Stream 级别设置了不同的窗口数。

最重要的是,我们可以在内存不足或者上游处理性能出现问题时,通过流量控制来限制传输速率,保障服务可用性。

没有队头阻塞的多路复用

QUIC 的多路复用和 HTTP2 类似。在一条 QUIC 连接上可以并发发送多个 HTTP 请求 (stream)。但是 QUIC 的多路复用相比 HTTP2 有一个很大的优势。

QUIC 一个连接上的多个 stream 之间没有依赖。这样假如 stream2 丢了一个 udp packet,也只会影响 stream2 的处理。不会影响 stream2 之前及之后的 stream 的处理。

这也就在很大程度上缓解甚至消除了队头阻塞的影响。
多路复用是 HTTP2 最强大的特性 [7],能够将多条请求在一条 TCP 连接上同时发出去。但也恶化了 TCP 的一个问题,队头阻塞 [11],如下图示:

12.jpg

 
图 6 HTTP2 队头阻塞
HTTP2 在一个 TCP 连接上同时发送 4 个 Stream。其中 Stream1 已经正确到达,并被应用层读取。但是 Stream2 的第三个 tcp segment 丢失了,TCP 为了保证数据的可靠性,需要发送端重传第 3 个 segment 才能通知应用层读取接下去的数据,虽然这个时候 Stream3 和 Stream4 的全部数据已经到达了接收端,但都被阻塞住了。 
不仅如此,由于 HTTP2 强制使用 TLS,还存在一个 TLS 协议层面的队头阻塞 [12]。

13.jpg

 
图 7 TLS 队头阻塞
Record 是 TLS 协议处理的最小单位,最大不能超过 16K,一些服务器比如 Nginx 默认的大小就是 16K。由于一个 record 必须经过数据一致性校验才能进行加解密,所以一个 16K 的 record,就算丢了一个字节,也会导致已经接收到的 15.99K 数据无法处理,因为它不完整。
那 QUIC 多路复用为什么能避免上述问题呢?

QUIC 最基本的传输单元是 Packet,不会超过 MTU 的大小,整个加密和认证过程都是基于 Packet 的,不会跨越多个 Packet。这样就能避免 TLS 协议存在的队头阻塞。
Stream 之间相互独立,比如 Stream2 丢了一个 Pakcet,不会影响 Stream3 和 Stream4。不存在 TCP 队头阻塞。

14.jpg

 
图 8 QUIC 多路复用时没有队头阻塞的问题
当然,并不是所有的 QUIC 数据都不会受到队头阻塞的影响,比如 QUIC 当前也是使用 Hpack 压缩算法 [10],由于算法的限制,丢失一个头部数据时,可能遇到队头阻塞。
总体来说,QUIC 在传输大量数据时,比如视频,受到队头阻塞的影响很小。

加密认证的报文

TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击。

但是 QUIC 的 packet 可以说是武装到了牙齿。除了个别报文比如 PUBLIC_RESET 和 CHLO,所有报文头部都是经过认证的,报文 Body 都是经过加密的。

这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险。

如下图所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,全部经过加密。

15.jpg


连接迁移

一条 TCP 连接 [17] 是由四元组标识的(源 IP,源端口,目的 IP,目的端口)。什么叫连接迁移呢?就是当其中任何一个元素发生变化时,这条连接依然维持着,能够保持业务逻辑不中断。当然这里面主要关注的是客户端的变化,因为客户端不可控并且网络环境经常发生变化,而服务端的 IP 和端口一般都是固定的。

比如大家使用手机在 WIFI 和 4G 移动网络切换时,客户端的 IP 肯定会发生变化,需要重新建立和服务端的 TCP 连接。

又比如大家使用公共 NAT 出口时,有些连接竞争时需要重新绑定端口,导致客户端的端口发生变化,同样需要重新建立 TCP 连接。

针对 TCP 的连接变化,MPTCP[5] 其实已经有了解决方案,但是由于 MPTCP 需要操作系统及网络协议栈支持,部署阻力非常大,目前并不适用。

所以从 TCP 连接的角度来讲,这个问题是无解的。

那 QUIC 是如何做到连接迁移呢?很简单,任何一条 QUIC 连接不再以 IP 及端口四元组标识,而是以一个 64 位的随机数作为 ID 来标识,这样就算 IP 或者端口发生变化时,只要 ID 不变,这条连接依然维持着,上层业务逻辑感知不到变化,不会中断,也就不需要重连。

由于这个 ID 是客户端随机产生的,并且长度有 64 位,所以冲突概率非常低。

其他亮点

此外,QUIC 还能实现前向冗余纠错,在重要的包比如握手消息发生丢失时,能够根据冗余信息还原出握手消息。

QUIC 还能实现证书压缩,减少证书传输量,针对包头进行验证等。

限于篇幅,本文不再详细介绍,有兴趣的可以参考文档 [23] 和文档 [4] 和文档 [26]。

参考线索

[1]. https://www.chromium.org/quic

[2]. https://docs.google.com/docume ... /edit

[3]. E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.3”, draft-ietf-tls-tls13-21, https://tools.ietf.org/html/dr ... 13-21, July 03, 2017

[4]. Adam Langley,Wan-Teh Chang, “QUIC Crypto”,https://docs.google.com/docume ... /edit, 20161206

[5]. https://www.multipath-tcp.org/

[6]. Ha, S., Rhee, I., and L. Xu, "CUBIC: A New TCP-Friendly High-Speed TCP Variant", ACM SIGOPS Operating System Review , 2008.

[7]. M. Belshe,BitGo, R. Peon, “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, May 2015

[8]. M. Mathis,J. Mahdavi,S. Floyd,A. Romanow,“TCP Selective Acknowledgment Options”, rfc2018, https://tools.ietf.org/html/rfc2018, October 1996

[9]. V. Paxson,M. Allman,J. Chu,M. Sargent,“Computing TCP's Retransmission Timer”, rfc6298, https://tools.ietf.org/html/rfc6298, June 2011

[10]. R. Peon,H. Ruellan,“HPACK: Header Compression for HTTP/2”,RFC7541,May 2015

[11]. M. Scharf, Alcatel-Lucent Bell Labs, S. Kiesel, “Quantifying Head-of-Line Blocking in TCP and SCTP”, https://tools.ietf.org/id/draf ... .html, July 15, 2013

[12]. Ilya Grigorik,“Optimizing TLS Record Size & Buffering Latency”, https://www.igvita.com/2013/10 ... ency/, October 24, 2013

[13]. J. Salowey,H. Zhou,P. Eronen,H. Tschofenig, “Transport Layer Security (TLS) Session Resumption without Server-Side State”, RFC5077, January 2008

[14]. Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008, .

[15]. Shirey, R., "Internet Security Glossary, Version 2", FYI , RFC 4949, August 2007

[16]. 罗成,“HTTPS性能优化”, http://www.infoq.com/cn/presen ... https,February.2017

[17]. Postel, J., "Transmission Control Protocol", STD 7, RFC793, September 1981.

[18]. J. Postel,“User Datagram Protocol”, RFC768,August 1980

[19]. Q. Dang, S. Santesson,K. Moriarty,D. Brown.T. Polk, “Internet X.509 Public Key Infrastructure: Additional Algorithms and Identifiers for DSA and ECDSA”,RFC5758, January 2010

[20]. Bassham, L., Polk, W., and R. Housley, "Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3279, April 2002

[21]. D.Cooper,S.Santesson, S.Farrell,S. Boeyen,R. Housley,W.Polk, “Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile”, RFC5280, May 2008

[22]. M. Allman,V. Paxson,E. Blanton, "TCP Congestion Control”,RFC5681, September 2009

[23]. Robbie Shade, “Flow control in QUIC”, https://docs.google.com/docume ... it%23, May, 2016,

[24]. ianswett , “QUIC fec v1”, https://docs.google.com/docume ... tytjt, 2016-02-19

[25]. D.Borman,B.Braden,V.Jacobson,R.Scheffenegger, Ed. “TCP Extensions for High Performance”,rfc7323, https://tools.ietf.org/html/rfc7323,September 2014

[26]. 罗成,“WEB加速,协议先行”, https://zhuanlan.zhihu.com/p/27938635,july, 2017
0
评论

Netty实现长连接服务的各种难点和可优化点 Netty 长连接

开发讨论beyond 发表了文章 • 899 次浏览 • 2019-11-26 14:47 • 来自相关话题

推送服务

还记得一年半前,做的一个项目需要用到 Android 推送服务。和 iOS 不同,Android 生态中没有统一的推送服务。Google 虽然有 Google Cloud Messaging ,但是连国外都没统一,更别说国内了,直接被墙。

所以之前在 Android 上做推送大部分只能靠轮询。而我们之前在技术调研的时候,搜到了 jPush 的博客,上面介绍了一些他们的技术特点,他们主要做的其实就是移动网络下的长连接服务。单机 50W-100W 的连接的确是吓我一跳!后来我们也采用了他们的免费方案,因为是一个受众面很小的产品,所以他们的免费版够我们用了。一年多下来,运作稳定,非常不错!

时隔两年,换了部门后,竟然接到了一项任务,优化公司自己的长连接服务端。

再次搜索网上技术资料后才发现,相关的很多难点都被攻破,网上也有了很多的总结文章,单机 50W-100W 的连接完全不是梦,其实人人都可以做到。但是光有连接还不够,QPS 也要一起上去。

所以,这篇文章就是汇总一下利用 Netty 实现长连接服务过程中的各种难点和可优化点。

Netty 是什么

Netty: http://netty.io/

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

官方的解释最精准了,期中最吸引人的就是高性能了。但是很多人会有这样的疑问:直接用 NIO 实现的话,一定会更快吧?就像我直接手写 JDBC 虽然代码量大了点,但是一定比 iBatis 快!

但是,如果了解 Netty 后你才会发现,这个还真不一定!

利用 Netty 而不用 NIO 直接写的优势有这些:

高性能高扩展的架构设计,大部分情况下你只需要关注业务而不需要关注架构

Zero-Copy 技术尽量减少内存拷贝

为 Linux 实现 Native 版 Socket

写同一份代码,兼容 java 1.7 的 NIO2 和 1.7 之前版本的 NIO

Pooled Buffers 大大减轻 Buffer 和释放 Buffer 的压力

……

特性太多,大家可以去看一下《Netty in Action》这本书了解更多。

另外,Netty 源码是一本很好的教科书!大家在使用的过程中可以多看看它的源码,非常棒!

 
瓶颈是什么

想要做一个长链服务的话,最终的目标是什么?而它的瓶颈又是什么?

其实目标主要就两个:

更多的连接

更高的 QPS

所以,下面就针对这连个目标来说说他们的难点和注意点吧。

更多的连接
非阻塞 IO

其实无论是用 Java NIO 还是用 Netty,达到百万连接都没有任何难度。因为它们都是非阻塞的 IO,不需要为每个连接创建一个线程了。

欲知详情,可以搜索一下BIO,NIO,AIO的相关知识点。

Java NIO 实现百万连接ServerSocketChannel ssc = ServerSocketChannel.open(); Selector sel = Selector.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(8080)); SelectionKey key = ssc.register(sel, SelectionKey.OP_ACCEPT); while(true) {     sel.select();     Iterator it = sel.selectedKeys().iterator();     while(it.hasNext()) {         SelectionKey skey = (SelectionKey)it.next();         it.remove();         if(skey.isAcceptable()) {             ch = ssc.accept();         }     } }这段代码只会接受连过来的连接,不做任何操作,仅仅用来测试待机连接数极限。

大家可以看到这段代码是 NIO 的基本写法,没什么特别的。


Netty 实现百万连接NioEventLoopGroup bossGroup =  new NioEventLoopGroup(); NioEventLoopGroup workerGroup= new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup); bootstrap.channel( NioServerSocketChannel.class); bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {     @Override protected void initChannel(SocketChannel ch) throws Exception {         ChannelPipeline pipeline = ch.pipeline();         //todo: add handler     }}); bootstrap.bind(8080).sync();这段其实也是非常简单的 Netty 初始化代码。同样,为了实现百万连接根本没有什么特殊的地方。


瓶颈到底在哪

上面两种不同的实现都非常简单,没有任何难度,那有人肯定会问了:实现百万连接的瓶颈到底是什么?

其实只要 java 中用的是非阻塞 IO(NIO 和 AIO 都算),那么它们都可以用单线程来实现大量的 Socket 连接。 不会像 BIO 那样为每个连接创建一个线程,因为代码层面不会成为瓶颈。

其实真正的瓶颈是在 Linux 内核配置上,默认的配置会限制全局最大打开文件数(Max Open Files)还会限制进程数。 所以需要对 Linux 内核配置进行一定的修改才可以。

这个东西现在看似很简单,按照网上的配置改一下就行了,但是大家一定不知道第一个研究这个人有多难。

这里直接贴几篇文章,介绍了相关配置的修改方式:

构建C1000K的服务器

100万并发连接服务器笔记之1M并发连接目标达成

淘宝技术分享 HTTP长连接200万尝试及调优


如何验证

让服务器支持百万连接一点也不难,我们当时很快就搞定了一个测试服务端,但是最大的问题是,我怎么去验证这个服务器可以支撑百万连接呢?

我们用 Netty 写了一个测试客户端,它同样用了非阻塞 IO ,所以不用开大量的线程。 但是一台机器上的端口数是有限制的,用root权限的话,最多也就 6W 多个连接了。 所以我们这里用 Netty 写一个客户端,用尽单机所有的连接吧。NioEventLoopGroup workerGroup =  new NioEventLoopGroup(); Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel( NioSocketChannel.class); b.handler(new ChannelInitializer<SocketChannel>() {     @Override     public void initChannel(SocketChannel ch) throws Exception {         ChannelPipeline pipeline = ch.pipeline();         //todo:add handler     }     }); for (int k = 0; k < 60000; k++) {     //请自行修改成服务端的IP     b.connect(127.0.0.1, 8080); }代码同样很简单,只要连上就行了,不需要做任何其他的操作。

这样只要找到一台电脑启动这个程序即可。这里需要注意一点,客户端最好和服务端一样,修改一下 Linux 内核参数配置。


怎么去找那么多机器

按照上面的做法,单机最多可以有 6W 的连接,百万连接起码需要17台机器!

如何才能突破这个限制呢?其实这个限制来自于网卡。 我们后来通过使用虚拟机,并且把虚拟机的虚拟网卡配置成了桥接模式解决了问题。

根据物理机内存大小,单个物理机起码可以跑4-5个虚拟机,所以最终百万连接只要4台物理机就够了。


讨巧的做法

除了用虚拟机充分压榨机器资源外,还有一个非常讨巧的做法,这个做法也是我在验证过程中偶然发现的。

根据 TCP/IP 协议,任何一方发送FIN后就会启动正常的断开流程。而如果遇到网络瞬断的情况,连接并不会自动断开。

那我们是不是可以这样做?

启动服务端,千万别设置 Socket 的keep-alive属性,默认是不设置的

用虚拟机连接服务器

强制关闭虚拟机

修改虚拟机网卡的 MAC 地址,重新启动并连接服务器

服务端接受新的连接,并保持之前的连接不断

我们要验证的是服务端的极限,所以只要一直让服务端认为有那么多连接就行了,不是吗?

经过我们的试验后,这种方法和用真实的机器连接服务端的表现是一样的,因为服务端只是认为对方网络不好罢了,不会将你断开。

另外,禁用keep-alive是因为如果不禁用,Socket 连接会自动探测连接是否可用,如果不可用会强制断开。


更高的 QPS

由于 NIO 和 Netty 都是非阻塞 IO,所以无论有多少连接,都只需要少量的线程即可。而且 QPS 不会因为连接数的增长而降低(在内存足够的前提下)。

而且 Netty 本身设计得足够好了,Netty 不是高 QPS 的瓶颈。那高 QPS 的瓶颈是什么?

是数据结构的设计!


如何优化数据结构

首先要熟悉各种数据结构的特点是必需的,但是在复杂的项目中,不是用了一个集合就可以搞定的,有时候往往是各种集合的组合使用。

既要做到高性能,还要做到一致性,还不能有死锁,这里难度真的不小…

我在这里总结的经验是,不要过早优化。优先考虑一致性,保证数据的准确,然后再去想办法优化性能。

因为一致性比性能重要得多,而且很多性能问题在量小和量大的时候,瓶颈完全会在不同的地方。 所以,我觉得最佳的做法是,编写过程中以一致性为主,性能为辅;代码完成后再去找那个 TOP1,然后去解决它!


解决 CPU 瓶颈

在做这个优化前,先在测试环境中去狠狠地压你的服务器,量小量大,天壤之别。

有了压力测试后,就需要用工具来发现性能瓶颈了!

我喜欢用的是 VisualVM,打开工具后看抽样器(Sample),根据自用时间(Self Time (CPU))倒序,排名第一的就是你需要去优化的点了!
备注:Sample 和 Profiler 有什么区别?前者是抽样,数据不是最准但是不影响性能;后者是统计准确,但是非常影响性能。 如果你的程序非常耗 CPU,那么尽量用 Sample,否则开启 Profiler 后降低性能,反而会影响准确性。





 还记得我们项目第一次发现的瓶颈竟然是ConcurrentLinkedQueue这个类中的size()方法。 量小的时候没有影响,但是Queue很大的时候,它每次都是从头统计总数的,而这个size()方法我们又是非常频繁地调用的,所以对性能产生了影响。

size()的实现如下:public int size() {     int count = 0;     for (Node<E> p = first(); p != null; p = succ(p))     if (p.item != null)     // Collection.size() spec says to max out     if (++count == Integer.MAX_VALUE)     break;     return count; }后来我们通过额外使用一个AtomicInteger来计数,解决了问题。但是分离后岂不是做不到高一致性呢? 没关系,我们的这部分代码关心最终一致性,所以只要保证最终一致就可以了。

总之,具体案例要具体分析,不同的业务要用不同的实现。


解决 GC 瓶颈

GC 瓶颈也是 CPU 瓶颈的一部分,因为不合理的 GC 会大大影响 CPU 性能。

这里还是在用 VisualVM,但是你需要装一个插件:VisualGC






有了这个插件后,你就可以直观的看到 GC 活动情况了。

按照我们的理解,在压测的时候,有大量的 New GC 是很正常的,因为有大量的对象在创建和销毁。

但是一开始有很多 Old GC 就有点说不过去了!

后来发现,在我们压测环境中,因为 Netty 的 QPS 和连接数关联不大,所以我们只连接了少量的连接。内存分配得也不是很多。

而 JVM 中,默认的新生代和老生代的比例是1:2,所以大量的老生代被浪费了,新生代不够用。

通过调整 -XX:NewRatio 后,Old GC 有了显著的降低。

但是,生产环境又不一样了,生产环境不会有那么大的 QPS,但是连接会很多,连接相关的对象存活时间非常长,所以生产环境更应该分配更多的老生代。

总之,GC 优化和 CPU 优化一样,也需要不断调整,不断优化,不是一蹴而就的。


其他优化

如果你已经完成了自己的程序,那么一定要看看《Netty in Action》作者的这个网站:Netty Best Practices a.k.a Faster == Better。

相信你会受益匪浅,经过里面提到的一些小小的优化后,我们的整体 QPS 提升了很多。

最后一点就是,java 1.7 比 java 1.6 性能高很多!因为 Netty 的编写风格是事件机制的,看似是 AIO。 可 java 1.6 是没有 AIO 的,java 1.7 是支持 AIO 的,所以如果用 java 1.7 的话,性能也会有显著提升。


最后成果

经过几周的不断压测和不断优化了,我们在一台16核、120G内存(JVM只分配8G)的机器上,用 java 1.6 达到了60万的连接和20万的QPS。

其实这还不是极限,JVM 只分配了8G内存,内存配置再大一点连接数还可以上去;

QPS 看似很高,System Load Average 很低,也就是说明瓶颈不在 CPU 也不在内存,那么应该是在 IO 了! 上面的 Linux 配置是为了达到百万连接而配置的,并没有针对我们自己的业务场景去做优化。

因为目前性能完全够用,线上单机 QPS 最多才 1W,所以我们先把精力放在了其他地方。 相信后面我们还会去继续优化这块的性能,期待 QPS 能有更大的突破!

本作品由 Dozer 创作,采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。 查看全部
推送服务

还记得一年半前,做的一个项目需要用到 Android 推送服务。和 iOS 不同,Android 生态中没有统一的推送服务。Google 虽然有 Google Cloud Messaging ,但是连国外都没统一,更别说国内了,直接被墙。

所以之前在 Android 上做推送大部分只能靠轮询。而我们之前在技术调研的时候,搜到了 jPush 的博客,上面介绍了一些他们的技术特点,他们主要做的其实就是移动网络下的长连接服务。单机 50W-100W 的连接的确是吓我一跳!后来我们也采用了他们的免费方案,因为是一个受众面很小的产品,所以他们的免费版够我们用了。一年多下来,运作稳定,非常不错!

时隔两年,换了部门后,竟然接到了一项任务,优化公司自己的长连接服务端。

再次搜索网上技术资料后才发现,相关的很多难点都被攻破,网上也有了很多的总结文章,单机 50W-100W 的连接完全不是梦,其实人人都可以做到。但是光有连接还不够,QPS 也要一起上去。

所以,这篇文章就是汇总一下利用 Netty 实现长连接服务过程中的各种难点和可优化点。

Netty 是什么

Netty: http://netty.io/

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

官方的解释最精准了,期中最吸引人的就是高性能了。但是很多人会有这样的疑问:直接用 NIO 实现的话,一定会更快吧?就像我直接手写 JDBC 虽然代码量大了点,但是一定比 iBatis 快!

但是,如果了解 Netty 后你才会发现,这个还真不一定!

利用 Netty 而不用 NIO 直接写的优势有这些:

高性能高扩展的架构设计,大部分情况下你只需要关注业务而不需要关注架构

Zero-Copy 技术尽量减少内存拷贝

为 Linux 实现 Native 版 Socket

写同一份代码,兼容 java 1.7 的 NIO2 和 1.7 之前版本的 NIO

Pooled Buffers 大大减轻 Buffer 和释放 Buffer 的压力

……

特性太多,大家可以去看一下《Netty in Action》这本书了解更多。

另外,Netty 源码是一本很好的教科书!大家在使用的过程中可以多看看它的源码,非常棒!

 
瓶颈是什么

想要做一个长链服务的话,最终的目标是什么?而它的瓶颈又是什么?

其实目标主要就两个:

更多的连接

更高的 QPS

所以,下面就针对这连个目标来说说他们的难点和注意点吧。

更多的连接
非阻塞 IO


其实无论是用 Java NIO 还是用 Netty,达到百万连接都没有任何难度。因为它们都是非阻塞的 IO,不需要为每个连接创建一个线程了。

欲知详情,可以搜索一下BIO,NIO,AIO的相关知识点。

Java NIO 实现百万连接ServerSocketChannel ssc = ServerSocketChannel.open(); Selector sel = Selector.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(8080)); SelectionKey key = ssc.register(sel, SelectionKey.OP_ACCEPT); while(true) {     sel.select();     Iterator it = sel.selectedKeys().iterator();     while(it.hasNext()) {         SelectionKey skey = (SelectionKey)it.next();         it.remove();         if(skey.isAcceptable()) {             ch = ssc.accept();         }     } }这段代码只会接受连过来的连接,不做任何操作,仅仅用来测试待机连接数极限。

大家可以看到这段代码是 NIO 的基本写法,没什么特别的。


Netty 实现百万连接NioEventLoopGroup bossGroup =  new NioEventLoopGroup(); NioEventLoopGroup workerGroup= new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup); bootstrap.channel( NioServerSocketChannel.class); bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {     @Override protected void initChannel(SocketChannel ch) throws Exception {         ChannelPipeline pipeline = ch.pipeline();         //todo: add handler     }}); bootstrap.bind(8080).sync();这段其实也是非常简单的 Netty 初始化代码。同样,为了实现百万连接根本没有什么特殊的地方。


瓶颈到底在哪

上面两种不同的实现都非常简单,没有任何难度,那有人肯定会问了:实现百万连接的瓶颈到底是什么?

其实只要 java 中用的是非阻塞 IO(NIO 和 AIO 都算),那么它们都可以用单线程来实现大量的 Socket 连接。 不会像 BIO 那样为每个连接创建一个线程,因为代码层面不会成为瓶颈。

其实真正的瓶颈是在 Linux 内核配置上,默认的配置会限制全局最大打开文件数(Max Open Files)还会限制进程数。 所以需要对 Linux 内核配置进行一定的修改才可以。

这个东西现在看似很简单,按照网上的配置改一下就行了,但是大家一定不知道第一个研究这个人有多难。

这里直接贴几篇文章,介绍了相关配置的修改方式:

构建C1000K的服务器

100万并发连接服务器笔记之1M并发连接目标达成

淘宝技术分享 HTTP长连接200万尝试及调优


如何验证

让服务器支持百万连接一点也不难,我们当时很快就搞定了一个测试服务端,但是最大的问题是,我怎么去验证这个服务器可以支撑百万连接呢?

我们用 Netty 写了一个测试客户端,它同样用了非阻塞 IO ,所以不用开大量的线程。 但是一台机器上的端口数是有限制的,用root权限的话,最多也就 6W 多个连接了。 所以我们这里用 Netty 写一个客户端,用尽单机所有的连接吧。NioEventLoopGroup workerGroup =  new NioEventLoopGroup(); Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel( NioSocketChannel.class); b.handler(new ChannelInitializer<SocketChannel>() {     @Override     public void initChannel(SocketChannel ch) throws Exception {         ChannelPipeline pipeline = ch.pipeline();         //todo:add handler     }     }); for (int k = 0; k < 60000; k++) {     //请自行修改成服务端的IP     b.connect(127.0.0.1, 8080); }代码同样很简单,只要连上就行了,不需要做任何其他的操作。

这样只要找到一台电脑启动这个程序即可。这里需要注意一点,客户端最好和服务端一样,修改一下 Linux 内核参数配置。


怎么去找那么多机器

按照上面的做法,单机最多可以有 6W 的连接,百万连接起码需要17台机器!

如何才能突破这个限制呢?其实这个限制来自于网卡。 我们后来通过使用虚拟机,并且把虚拟机的虚拟网卡配置成了桥接模式解决了问题。

根据物理机内存大小,单个物理机起码可以跑4-5个虚拟机,所以最终百万连接只要4台物理机就够了。


讨巧的做法

除了用虚拟机充分压榨机器资源外,还有一个非常讨巧的做法,这个做法也是我在验证过程中偶然发现的。

根据 TCP/IP 协议,任何一方发送FIN后就会启动正常的断开流程。而如果遇到网络瞬断的情况,连接并不会自动断开。

那我们是不是可以这样做?

启动服务端,千万别设置 Socket 的keep-alive属性,默认是不设置的

用虚拟机连接服务器

强制关闭虚拟机

修改虚拟机网卡的 MAC 地址,重新启动并连接服务器

服务端接受新的连接,并保持之前的连接不断

我们要验证的是服务端的极限,所以只要一直让服务端认为有那么多连接就行了,不是吗?

经过我们的试验后,这种方法和用真实的机器连接服务端的表现是一样的,因为服务端只是认为对方网络不好罢了,不会将你断开。

另外,禁用keep-alive是因为如果不禁用,Socket 连接会自动探测连接是否可用,如果不可用会强制断开。


更高的 QPS

由于 NIO 和 Netty 都是非阻塞 IO,所以无论有多少连接,都只需要少量的线程即可。而且 QPS 不会因为连接数的增长而降低(在内存足够的前提下)。

而且 Netty 本身设计得足够好了,Netty 不是高 QPS 的瓶颈。那高 QPS 的瓶颈是什么?

是数据结构的设计!


如何优化数据结构

首先要熟悉各种数据结构的特点是必需的,但是在复杂的项目中,不是用了一个集合就可以搞定的,有时候往往是各种集合的组合使用。

既要做到高性能,还要做到一致性,还不能有死锁,这里难度真的不小…

我在这里总结的经验是,不要过早优化。优先考虑一致性,保证数据的准确,然后再去想办法优化性能。

因为一致性比性能重要得多,而且很多性能问题在量小和量大的时候,瓶颈完全会在不同的地方。 所以,我觉得最佳的做法是,编写过程中以一致性为主,性能为辅;代码完成后再去找那个 TOP1,然后去解决它!


解决 CPU 瓶颈

在做这个优化前,先在测试环境中去狠狠地压你的服务器,量小量大,天壤之别。

有了压力测试后,就需要用工具来发现性能瓶颈了!

我喜欢用的是 VisualVM,打开工具后看抽样器(Sample),根据自用时间(Self Time (CPU))倒序,排名第一的就是你需要去优化的点了!
备注:Sample 和 Profiler 有什么区别?前者是抽样,数据不是最准但是不影响性能;后者是统计准确,但是非常影响性能。 如果你的程序非常耗 CPU,那么尽量用 Sample,否则开启 Profiler 后降低性能,反而会影响准确性。

1.png

 还记得我们项目第一次发现的瓶颈竟然是ConcurrentLinkedQueue这个类中的size()方法。 量小的时候没有影响,但是Queue很大的时候,它每次都是从头统计总数的,而这个size()方法我们又是非常频繁地调用的,所以对性能产生了影响。

size()的实现如下:public int size() {     int count = 0;     for (Node<E> p = first(); p != null; p = succ(p))     if (p.item != null)     // Collection.size() spec says to max out     if (++count == Integer.MAX_VALUE)     break;     return count; }后来我们通过额外使用一个AtomicInteger来计数,解决了问题。但是分离后岂不是做不到高一致性呢? 没关系,我们的这部分代码关心最终一致性,所以只要保证最终一致就可以了。

总之,具体案例要具体分析,不同的业务要用不同的实现。


解决 GC 瓶颈

GC 瓶颈也是 CPU 瓶颈的一部分,因为不合理的 GC 会大大影响 CPU 性能。

这里还是在用 VisualVM,但是你需要装一个插件:VisualGC

2.png


有了这个插件后,你就可以直观的看到 GC 活动情况了。

按照我们的理解,在压测的时候,有大量的 New GC 是很正常的,因为有大量的对象在创建和销毁。

但是一开始有很多 Old GC 就有点说不过去了!

后来发现,在我们压测环境中,因为 Netty 的 QPS 和连接数关联不大,所以我们只连接了少量的连接。内存分配得也不是很多。

而 JVM 中,默认的新生代和老生代的比例是1:2,所以大量的老生代被浪费了,新生代不够用。

通过调整 -XX:NewRatio 后,Old GC 有了显著的降低。

但是,生产环境又不一样了,生产环境不会有那么大的 QPS,但是连接会很多,连接相关的对象存活时间非常长,所以生产环境更应该分配更多的老生代。

总之,GC 优化和 CPU 优化一样,也需要不断调整,不断优化,不是一蹴而就的。


其他优化

如果你已经完成了自己的程序,那么一定要看看《Netty in Action》作者的这个网站:Netty Best Practices a.k.a Faster == Better。

相信你会受益匪浅,经过里面提到的一些小小的优化后,我们的整体 QPS 提升了很多。

最后一点就是,java 1.7 比 java 1.6 性能高很多!因为 Netty 的编写风格是事件机制的,看似是 AIO。 可 java 1.6 是没有 AIO 的,java 1.7 是支持 AIO 的,所以如果用 java 1.7 的话,性能也会有显著提升。


最后成果

经过几周的不断压测和不断优化了,我们在一台16核、120G内存(JVM只分配8G)的机器上,用 java 1.6 达到了60万的连接和20万的QPS。

其实这还不是极限,JVM 只分配了8G内存,内存配置再大一点连接数还可以上去;

QPS 看似很高,System Load Average 很低,也就是说明瓶颈不在 CPU 也不在内存,那么应该是在 IO 了! 上面的 Linux 配置是为了达到百万连接而配置的,并没有针对我们自己的业务场景去做优化。

因为目前性能完全够用,线上单机 QPS 最多才 1W,所以我们先把精力放在了其他地方。 相信后面我们还会去继续优化这块的性能,期待 QPS 能有更大的突破!

本作品由 Dozer 创作,采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
0
评论

【源码下载】一款使用环信SDK实现的开源--社交demo webIM demo webim demo 项目示例

开发讨论QWK 发表了文章 • 888 次浏览 • 2019-11-25 16:58 • 来自相关话题

React webIm demo简介   --(集成环信SDK)

webIm demo 是基于环信sdk开发的一款具有单聊、群聊、聊天室、音视频等功能的应用,为了react用户能够快速集成环信 im sdk和音视频sdk,我们特使用了react全家桶,为大家提供参考。

同时我们也提供了[Vue版demo]  (https://github.com/easemob/webim-vue-demo)。

项目截图:































项目地址:https://github.com/easemob/webim


开发环境

完全基于React + Redux的单向数据流,引入ant-design组件库。 

响应式布局, 一套Demo同时支持PC和H5,自适应不同终端屏幕尺寸

支持所有的现代浏览器(不支持IE6-11)




初始化安装
- 在/demo目录下执行  npm i
- 运行demo
- cd demo && npm start (requires node@>=6)

http://localhost:3001
- cd demo && HTTPS=true npm start (webrtc supports HTTPS only)

https://localhost:3001

注意:只有在https的情况才支持语音视频功能
 

打包发布demo
cd demo && npm run build /demo/build 目录下的就是可以运行和部署的版本


可能遇见的问题:

1. 如果在npm i的过程中遇到
> phantomjs-prebuilt@2.1.14 install /Users/will/work/my-project/node_modules/phantomjs-prebuilt> node install.jsPhantomJS not found on PATHDownloading https://github.com/Medium/phan ... aving to /var/folders/mh/2ptfthxj2qb49jscj1b0gjsm0000gn/T/phantomjs/phantomjs-2.1.1-macosx.zipReceiving...Error making request.Error: connect ETIMEDOUT 54.231.113.227:443 at Object.exports._errnoException (util.js:1018:11) at exports._exceptionWithHostPort (util.js:1041:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)

FIX: 这个问题,可以尝试 PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs/ npm install --save-dev phantomjs-prebuilt 来解决
2. 执行npm start时如果出现
> node scripts/start.js/Users/wenke/www/web-im/demo/scripts/start.js:23const { ^SyntaxError: Unexpected token { at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) at startup (node.js:139:18) at node.js:974:3

FIX: 请检查node版本是否是v6.0+ 
项目模块

本项目包含两部分:
一部分是项目主模块,这部分主要包含了项目的业务逻辑,比如增,删好友、音视频聊天、信息修改、群设置等

另一部分是 环信sdk集成(包含音视频sdk)







src项目结构







更多关于环信sdk[集成文档]
http://docs-im.easemob.com/im/web/intro/start




参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge


最后的最后如果你有更好的建议,或者你的疑惑,请随时给我留言。
  查看全部
React webIm demo简介   --(集成环信SDK)

webIm demo 是基于环信sdk开发的一款具有单聊、群聊、聊天室、音视频等功能的应用,为了react用户能够快速集成环信 im sdk和音视频sdk,我们特使用了react全家桶,为大家提供参考。

同时我们也提供了[Vue版demo]  (https://github.com/easemob/webim-vue-demo)。

项目截图:

16df69ea7a91facd.jpg


16df6a2287ccb151.jpg


16df6a550a6bd226.jpg


16df6a87eaa8c068.jpg


16df6aef07a80553.jpg


16df6b33eaa4edfd.jpg


项目地址:https://github.com/easemob/webim


开发环境

完全基于React + Redux的单向数据流,引入ant-design组件库。 

响应式布局, 一套Demo同时支持PC和H5,自适应不同终端屏幕尺寸

支持所有的现代浏览器(不支持IE6-11)




初始化安装
- 在/demo目录下执行  
npm i

- 运行demo
- cd demo && npm start (requires node@>=6)

http://localhost:3001
- cd demo && HTTPS=true npm start (webrtc supports HTTPS only)

https://localhost:3001

注意:只有在https的情况才支持语音视频功能
 

打包发布demo
cd demo && npm run build 
/demo/build 目录下的就是可以运行和部署的版本


可能遇见的问题:

1. 如果在npm i的过程中遇到
> phantomjs-prebuilt@2.1.14 install /Users/will/work/my-project/node_modules/phantomjs-prebuilt> node install.jsPhantomJS not found on PATHDownloading https://github.com/Medium/phan ... aving to /var/folders/mh/2ptfthxj2qb49jscj1b0gjsm0000gn/T/phantomjs/phantomjs-2.1.1-macosx.zipReceiving...Error making request.Error: connect ETIMEDOUT 54.231.113.227:443    at Object.exports._errnoException (util.js:1018:11) at exports._exceptionWithHostPort (util.js:1041:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)

FIX: 这个问题,可以尝试 PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs/ npm install --save-dev phantomjs-prebuilt 来解决

2. 执行npm start时如果出现
> node scripts/start.js/Users/wenke/www/web-im/demo/scripts/start.js:23const { ^SyntaxError: Unexpected token { at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10)    at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) at startup (node.js:139:18) at node.js:974:3

FIX: 请检查node版本是否是v6.0+ 

项目模块

本项目包含两部分:
一部分是项目主模块,这部分主要包含了项目的业务逻辑,比如增,删好友、音视频聊天、信息修改、群设置等

另一部分是 环信sdk集成(包含音视频sdk)


16e1ba1c27a529fe.jpg


src项目结构

16e1bd9c61944e5f.jpg



更多关于环信sdk[集成文档]
http://docs-im.easemob.com/im/web/intro/start




参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge


最后的最后如果你有更好的建议,或者你的疑惑,请随时给我留言。

 
0
评论

【源码下载】一款使用环信SDK实现的开源--社交demo webim demo 项目示例

开发讨论QWK 发表了文章 • 670 次浏览 • 2019-11-25 16:58 • 来自相关话题

React webIm demo简介   --(集成环信SDK)

webIm demo 是基于环信sdk开发的一款具有单聊、群聊、聊天室、音视频等功能的应用,为了react用户能够快速集成环信 im sdk和音视频sdk,我们特使用了react全家桶,为大家提供参考。
同时我们也提供了[Vue版demo]  https://github.com/easemob/webim-vue-demo

项目截图:

































项目地址:https://github.com/easemob/webim 

开发环境:
完全基于React + Redux的单向数据流,引入ant-design组件库。 

响应式布局, 一套Demo同时支持PC和H5,自适应不同终端屏幕尺寸

支持所有的现代浏览器(不支持IE6-11)

初始化安装:
- 在/demo目录下执行  
npm i
- 运行demo
- cd demo && npm start (requires node@>=6) http://localhost:3001注意:只有在https的情况才支持语音视频功能
- 打包发布demo
cd demo && npm run build /demo/build 目录下的就是可以运行和部署的版本
可能遇见的问题:
1. 如果在npm i的过程中遇到
> phantomjs-prebuilt@2.1.14 install /Users/will/work/my-project/node_modules/phantomjs-prebuilt> node install.jsPhantomJS not found on PATHDownloading https://github.com/Medium/phan ... aving to /var/folders/mh/2ptfthxj2qb49jscj1b0gjsm0000gn/T/phantomjs/phantomjs-2.1.1-macosx.zipReceiving...Error making request.Error: connect ETIMEDOUT 54.231.113.227:443 at Object.exports._errnoException (util.js:1018:11) at exports._exceptionWithHostPort (util.js:1041:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)FIX:
这个问题,可以尝试 PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs/ npm install --save-dev phantomjs-prebuilt 来解决
2. 执行npm start时如果出现
> node scripts/start.js/Users/wenke/www/web-im/demo/scripts/start.js:23const { ^SyntaxError: Unexpected token { at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) at startup (node.js:139:18) at node.js:974:3 FIX: 请检查node版本是否是v6.0+ 
项目模块
本项目包含两部分:一部分是项目主模块,这部分主要包含了项目的业务逻辑,比如增,删好友、音视频聊天、信息修改、群设置等
另一部分是 环信sdk集成(包含音视频sdk)








src项目结构








更多关于环信sdk[集成文档]
http://docs-im.easemob.com/im/web/intro/start 


参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge 查看全部
React webIm demo简介   --(集成环信SDK)

webIm demo 是基于环信sdk开发的一款具有单聊、群聊、聊天室、音视频等功能的应用,为了react用户能够快速集成环信 im sdk和音视频sdk,我们特使用了react全家桶,为大家提供参考。


项目截图:


16df69ea7a91facd.jpg


16df6a2287ccb151.jpg


16df6a550a6bd226.jpg


16df6a87eaa8c068.jpg


16df6aef07a80553.jpg


16df6b33eaa4edfd.jpg



项目地址:https://github.com/easemob/webim 

开发环境:
完全基于React + Redux的单向数据流,引入ant-design组件库。 

响应式布局, 一套Demo同时支持PC和H5,自适应不同终端屏幕尺寸

支持所有的现代浏览器(不支持IE6-11)

初始化安装:
- 在/demo目录下执行  
npm i
- 运行demo
- cd demo && npm start (requires node@>=6) http://localhost:3001注意:只有在https的情况才支持语音视频功能
- 打包发布demo
cd demo && npm run build /demo/build 目录下的就是可以运行和部署的版本
可能遇见的问题:
1. 如果在npm i的过程中遇到
> phantomjs-prebuilt@2.1.14 install /Users/will/work/my-project/node_modules/phantomjs-prebuilt> node install.jsPhantomJS not found on PATHDownloading https://github.com/Medium/phan ... aving to /var/folders/mh/2ptfthxj2qb49jscj1b0gjsm0000gn/T/phantomjs/phantomjs-2.1.1-macosx.zipReceiving...Error making request.Error: connect ETIMEDOUT 54.231.113.227:443 at Object.exports._errnoException (util.js:1018:11) at exports._exceptionWithHostPort (util.js:1041:20) at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)FIX:
这个问题,可以尝试 PHANTOMJS_CDNURL=https://npm.taobao.org/mirrors/phantomjs/ npm install --save-dev phantomjs-prebuilt 来解决
2. 执行npm start时如果出现
> node scripts/start.js/Users/wenke/www/web-im/demo/scripts/start.js:23const { ^SyntaxError: Unexpected token { at exports.runInThisContext (vm.js:53:16) at Module._compile (module.js:373:25) at Object.Module._extensions..js (module.js:416:10) at Module.load (module.js:343:32) at Function.Module._load (module.js:300:12) at Function.Module.runMain (module.js:441:10) at startup (node.js:139:18) at node.js:974:3 FIX: 请检查node版本是否是v6.0+ 
项目模块
本项目包含两部分:一部分是项目主模块,这部分主要包含了项目的业务逻辑,比如增,删好友、音视频聊天、信息修改、群设置等
另一部分是 环信sdk集成(包含音视频sdk)


16e1ba1c27a529fe.jpg



src项目结构


16e1bd9c61944e5f.jpg



更多关于环信sdk[集成文档]
http://docs-im.easemob.com/im/web/intro/start 


参与贡献
如果你有什么好的想法,或者好的实现,可以通过下边的步骤参与进来,让我们一起把这个项目做得更好,欢迎参与
1.Fork本仓库
2.新建feature_xxx分支 (单独创建一个实现你自己想法的分支)
3.提交代码
4.新建Pull Request
5.等待我们的Review & Merge
0
评论

客服云 查看IM用户上传推送证书 客服云 查看IM用户上传推送证书

开发讨论coinci 发表了文章 • 730 次浏览 • 2019-10-22 15:17 • 来自相关话题

                                                进入appkey console后台查看已注册用户 上传推送证书
****1.快速创建的关联
切换到管理员模式--渠道管理---手机APP 
APP信息页面点击 蓝色字体  直接登录IM关联后台,可以进入快速创建的关联后台,点击appkey后可查看IM用户和证书信息














****2.手动绑定的管理 需要单独登录IMconsole后台查看
IMconsole后台登录地址:
https://console.easemob.com/user/login  查看全部
                                                进入appkey console后台查看已注册用户 上传推送证书
****1.快速创建的关联
切换到管理员模式--渠道管理---手机APP 
APP信息页面点击 蓝色字体  直接登录IM关联后台,可以进入快速创建的关联后台,点击appkey后可查看IM用户和证书信息
29-1进入关联后台.png


29-2进入关联后台.png


29-3进入关联后台.png

****2.手动绑定的管理 需要单独登录IMconsole后台查看
IMconsole后台登录地址:
https://console.easemob.com/user/login 
0
评论

客服云 查看有哪些会话在待接入排队过 客服云 查看有哪些会话在待接入排队过

开发讨论coinci 发表了文章 • 754 次浏览 • 2019-10-22 15:17 • 来自相关话题

                                                        查看有哪些会话在待接入排队过 
 (管理员模式--会话统计--排队统计)可以查看该报表,此报表为增值功能,标准版坐席没有,需要单独联系商务经理开通
文档:
http://docs.easemob.com/cs/200 ... %25A1
另外该 报表中的排队次数,可以点击该数量之后弹窗显示相关会话数据










相关会话可以导出后查看具体信息
弹窗列表显示的 数据:
客服一列(如果排队的会话被客服接起这里会显示接待的客服,如果没有任何一个客服接入过直接被关闭的显示为空)
开始时间(表示客服接入或者转入会话的时间,如果没有被客服接入过,显示为空)
会话标签(如果没有打过标签,此处也为空) 查看全部
                                                        查看有哪些会话在待接入排队过 
 (管理员模式--会话统计--排队统计)可以查看该报表,此报表为增值功能,标准版坐席没有,需要单独联系商务经理开通
文档:
http://docs.easemob.com/cs/200 ... %25A1
另外该 报表中的排队次数,可以点击该数量之后弹窗显示相关会话数据

排队报表5-1.png


排队报表5-2.png

相关会话可以导出后查看具体信息
弹窗列表显示的 数据:
客服一列(如果排队的会话被客服接起这里会显示接待的客服,如果没有任何一个客服接入过直接被关闭的显示为空)
开始时间(表示客服接入或者转入会话的时间,如果没有被客服接入过,显示为空)
会话标签(如果没有打过标签,此处也为空)
0
评论

IM 和 客服 并存开发指南—iOS篇 客服和IM同时集成

开发讨论kijieoeew 发表了文章 • 1269 次浏览 • 2019-10-18 17:13 • 来自相关话题

 如果觉得哪里描述的不清晰,可评论内指出,会不定期更新。

 一、SDK 介绍
      HelpDesk.framework 为 客服SDK(带实时音视频)
      HelpDeskLite.framework 为 客服SDK(不带实时音视频)
      Hyphenate.framework 为 IM SDK(带实时音视频)
      HyphenateLite.framework 为 IM SDK(不带实时音视频)
      环信客服SDK 基于 IM SDK 3.x , 如果同时集成 客服 和 IM,只需要在初始化、登录、登出操作时使用客服SDK 提供的相应API,IM 的其他API均不受影响。
      UI 部分集成需要分别导入 HelpDeskUI 和 IM demo 中的UI文件(也可以自定义UI)。 下面详细介绍IM 和 客服共存的开发步骤。

二、注意事项
      1、开发过程中,初始化、登录和登出,务必只使用客服访客端SDK的API。
      2、需要联系商务开通客服长连接。
           不开通长连接,会出现用户长时间(一天或几天)不使用app,再打开app会无法正常使用im相关功能的问题,报错信息一般是User is not login。
      3、IM SDK 和客服SDK 都包括了模拟器的CPU 架构,在上传到app store时需要剔除模拟器的CPU 架构,保留  armv7、arm64,参考文档:上传appstore以及打包ipa注意事项。 

三、资源准备
      到环信官网下载客服访客端的开源的商城Demo源码 + SDK,下载链接:http://www.easemob.com/download/cs  选  择“iOS SDK”下载(如下图)。
      



      到环信官网下载IM的开源的Demo源码 + SDK ,下载链接:http://www.easemob.com/download/im 选择 iOS SDK(如下图)。
      




下载的 IM SDK+Demo 和 客服SDK+Demo 中都有 IM 的 Hyphenate.framework 或 HyphenateLite.framework,为了保持版本的匹配,我们只使用 IM Demo 中的 UI, 而不使用 IM SDK 中 的 Hyphenate.framework 或 HyphenateLite.framework 文件。

四、集成步骤
      1、阅读客服访客端SDK集成文档,集成客服,地址:http://docs.easemob.com/cs/300visitoraccess/iossdk。 
      2、阅读 IM 的集成文档,地址:http://docs-im.easemob.com/im/ios/sdk/prepare 
      3、将 IM Demo 中的 UI 文件按照自己的需求分模块导入到工程中
      4、将 IM 的 UI 所依赖的第三方库集成到项目中(IM集成文档内有说明)
      5、在pch文件中引入 EMHeaders.h 
          #ifdef __OBJC__ 
            //包含实时音视频功能 
            #import <HelpDesk/HelpDesk.h> 
            // 若不包含实时音视频,则替换为 
            // #import <HelpDeskLite/HelpDeskLite.h> 
            #import "HelpDeskUI.h" 
            #import "EMHeaders.h" 
         #endif
      6、由于HelpDeskUI 和 IM UI 中都使用了 第三方库,如果工程中出现三方库重复的问题,可将重复文件删除,如果部分接口已经升级或弃用可自行升级、调整。

提供的兼容Demo介绍:
     1、Demo集成了初始化sdk、登录、退出登录、IM单聊、联系客服的简单功能,处理了第三方库冲突的问题。
     2、pch文件中的appkey等信息需要换成开发者自己的。
     3、Demo源码下载地址: https://pan.baidu.com/s/1v1TUl-fqJNLQrtsJfWYGzw 
         提取码: kukb  查看全部
 如果觉得哪里描述的不清晰,可评论内指出,会不定期更新。

 一、SDK 介绍
      HelpDesk.framework 为 客服SDK(带实时音视频)
      HelpDeskLite.framework 为 客服SDK(不带实时音视频)
      Hyphenate.framework 为 IM SDK(带实时音视频)
      HyphenateLite.framework 为 IM SDK(不带实时音视频)
      环信客服SDK 基于 IM SDK 3.x , 如果同时集成 客服 和 IM,只需要在初始化、登录、登出操作时使用客服SDK 提供的相应API,IM 的其他API均不受影响。
      UI 部分集成需要分别导入 HelpDeskUI 和 IM demo 中的UI文件(也可以自定义UI)。 下面详细介绍IM 和 客服共存的开发步骤。

二、注意事项
      1、开发过程中,初始化、登录和登出,务必只使用客服访客端SDK的API。
      2、需要联系商务开通客服长连接。
           不开通长连接,会出现用户长时间(一天或几天)不使用app,再打开app会无法正常使用im相关功能的问题,报错信息一般是User is not login。
      3、IM SDK 和客服SDK 都包括了模拟器的CPU 架构,在上传到app store时需要剔除模拟器的CPU 架构,保留  armv7、arm64,参考文档:上传appstore以及打包ipa注意事项。 

三、资源准备
      到环信官网下载客服访客端的开源的商城Demo源码 + SDK,下载链接:http://www.easemob.com/download/cs  选  择“iOS SDK”下载(如下图)。
      
下载客服.png

      到环信官网下载IM的开源的Demo源码 + SDK ,下载链接:http://www.easemob.com/download/im 选择 iOS SDK(如下图)。
      
下载IM.png


下载的 IM SDK+Demo 和 客服SDK+Demo 中都有 IM 的 Hyphenate.framework 或 HyphenateLite.framework,为了保持版本的匹配,我们只使用 IM Demo 中的 UI, 而不使用 IM SDK 中 的 Hyphenate.framework 或 HyphenateLite.framework 文件。

四、集成步骤
      1、阅读客服访客端SDK集成文档,集成客服,地址:http://docs.easemob.com/cs/300visitoraccess/iossdk。 
      2、阅读 IM 的集成文档,地址:http://docs-im.easemob.com/im/ios/sdk/prepare 
      3、将 IM Demo 中的 UI 文件按照自己的需求分模块导入到工程中
      4、将 IM 的 UI 所依赖的第三方库集成到项目中(IM集成文档内有说明)
      5、在pch文件中引入 EMHeaders.h 
          #ifdef __OBJC__ 
            //包含实时音视频功能 
            #import <HelpDesk/HelpDesk.h> 
            // 若不包含实时音视频,则替换为 
            // #import <HelpDeskLite/HelpDeskLite.h> 
            #import "HelpDeskUI.h" 
            #import "EMHeaders.h" 
         #endif
      6、由于HelpDeskUI 和 IM UI 中都使用了 第三方库,如果工程中出现三方库重复的问题,可将重复文件删除,如果部分接口已经升级或弃用可自行升级、调整。

提供的兼容Demo介绍:
     1、Demo集成了初始化sdk、登录、退出登录、IM单聊、联系客服的简单功能,处理了第三方库冲突的问题。
     2、pch文件中的appkey等信息需要换成开发者自己的。
     3、Demo源码下载地址: https://pan.baidu.com/s/1v1TUl-fqJNLQrtsJfWYGzw 
         提取码: kukb 
0
评论

客服云配置机器人自定义菜单 客服云配置机器人自定义菜单

开发讨论coinci 发表了文章 • 916 次浏览 • 2019-10-18 16:32 • 来自相关话题

                                                                   设置机器人自定义菜单
1》管理员模式---智能机器人 新建机器人




2》管理员模式----设置----会话分配规则  渠道指定,添加访客发起会话的渠道(例如APP和网页),全天指定机器人




 
     修改路由规则后,需要在管理员模式--当前会话  手动关闭旧会话,新会话才能重新调度
3》 企业版机器人:管理员模式---智能机器人  点击【机器人管理】,新页面跳转到企业版机器人管理平台  
     知识管理模块----菜单管理
    旧版机器人:管理员模式--智能机器人  点击自定义菜单页签
























 
4》机器人的自定义菜单需要设置为默认回复或者欢迎语才能触发
以下是设置为默认回复:点击蓝色 添加默认回复按钮,选择类型为菜单














 
以下是配置为机器人的欢迎语





 
点击蓝色添加按钮,同样选择为菜单类型,选择刚创建的自定义菜单,最后保存(注意设置为机器人欢迎语后:只有网页会生效显示,APP需要单独代码集成,微信和微博不支持机器人欢迎语)









 
注意:如果新建自定义菜单的时候只新建了菜单名,没有设置菜单项,上图界面是无法点击保存按钮的。需到自定义菜单页面给菜单添加菜单项。









 
以上是配置好的截图,就可以发起新会话测试了
5》测试:以下是网页测试截图 
h5链接在:管理员模式--渠道管理-网站 接入方式  页面 ,点击直接打开h5链接按钮即可




 
 附:企业版机器人基础配置文档:http://docs-ai.easemob.com/cs/preliminary    
        客服系统旧版机器人文档:http://docs.easemob.com/cs/200 ... %25BA
  查看全部
                                                                   设置机器人自定义菜单
1》管理员模式---智能机器人 新建机器人
1-1设置机器人自定义菜单.png

2》管理员模式----设置----会话分配规则  渠道指定,添加访客发起会话的渠道(例如APP和网页),全天指定机器人
1-2设置机器人自定义菜单.png

 
     修改路由规则后,需要在管理员模式--当前会话  手动关闭旧会话,新会话才能重新调度
3》 企业版机器人:管理员模式---智能机器人  点击【机器人管理】,新页面跳转到企业版机器人管理平台  
     知识管理模块----菜单管理
    旧版机器人:管理员模式--智能机器人  点击自定义菜单页签
1-3设置机器人自定义菜单.png


1-4设置机器人自定义菜单.png


1-5设置机器人自定义菜单.png


1-6设置机器人自定义菜单.png


1-7设置机器人自定义菜单.png

 
4》机器人的自定义菜单需要设置为默认回复或者欢迎语才能触发
以下是设置为默认回复:点击蓝色 添加默认回复按钮,选择类型为菜单
1-8设置机器人自定义菜单.png


1-9设置机器人自定义菜单.png


1-10设置机器人自定义菜单.png

 
以下是配置为机器人的欢迎语
1-11设置机器人自定义菜单.png


 
点击蓝色添加按钮,同样选择为菜单类型,选择刚创建的自定义菜单,最后保存(注意设置为机器人欢迎语后:只有网页会生效显示,APP需要单独代码集成,微信和微博不支持机器人欢迎语)
1-12设置机器人自定义菜单.png


1-13设置机器人自定义菜单.png

 
注意:如果新建自定义菜单的时候只新建了菜单名,没有设置菜单项,上图界面是无法点击保存按钮的。需到自定义菜单页面给菜单添加菜单项。
1-14设置机器人自定义菜单.png


1-15设置机器人自定义菜单.png

 
以上是配置好的截图,就可以发起新会话测试了
5》测试:以下是网页测试截图 
h5链接在:管理员模式--渠道管理-网站 接入方式  页面 ,点击直接打开h5链接按钮即可
1-16设置机器人自定义菜单.png

 
 附:企业版机器人基础配置文档:http://docs-ai.easemob.com/cs/preliminary    
        客服系统旧版机器人文档:http://docs.easemob.com/cs/200 ... %25BA
 
0
评论

客服云访客发送订单或者轨迹消息后不展示 客服云访客发送订单或者轨迹消息后不展示

开发讨论coinci 发表了文章 • 728 次浏览 • 2019-10-18 11:58 • 来自相关话题

                                                  访客端发送订单或者轨迹消息后不显示
默认是发送后访客端删除本条消息,可以修改 
Android
ChatrowOrder 查找removeMessage





网页修改   
管理员模式--设置--系统开关 访客端同步展示轨迹消息 开关打开




  查看全部
                                                  访客端发送订单或者轨迹消息后不显示
默认是发送后访客端删除本条消息,可以修改 
Android
ChatrowOrder 查找removeMessage
24-1访客端发送订单轨迹后不显示.png


网页修改   
管理员模式--设置--系统开关 访客端同步展示轨迹消息 开关打开
24-2访客端发送订单轨迹后不显示.png

 
0
评论

客服云自定义角色权限 客服云自定义角色权限

开发讨论coinci 发表了文章 • 898 次浏览 • 2019-10-17 14:56 • 来自相关话题

****1.新建自定义角色
管理员模式----设置---权限管理 页面右上角 添加角色





需要填写角色名称,角色权限 分为两大类:管理员模式 和客服模式
这两种模式的展开项分别对应两种模式下的所有功能模块(按需勾选)
 以下操作以新建一个角色权限为:客服模式下所有功能,管理员模式下只有质检功能 为例:
   **第一:客服模式根目录直接勾选




   **第二:管理员模式  点击 展示所有功能模块,只需要勾选 质检功能的3个复选框




       同时可以规则新角色的数据权限:租户或者客服





 
   **第三:最后操作保存(tips:创建的自定义角色不能超过20个)
****2.给客服修改权限
管理员模式---成员管理--客服 
进入客服列表页面,选择要修改的客服,选项 一列点击编辑按钮




 
弹出客服信息修改对话框,滑动到底部
修改角色,最后保存




 
客服如果是登录状态,会自动给客服发送通知,客服需重新登录系统,新角色权限可以生效。 查看全部
****1.新建自定义角色
管理员模式----设置---权限管理 页面右上角 添加角色
30-1自定义角色权限.png


需要填写角色名称,角色权限 分为两大类:管理员模式客服模式
这两种模式的展开项分别对应两种模式下的所有功能模块(按需勾选)
 以下操作以新建一个角色权限为:客服模式下所有功能,管理员模式下只有质检功能 为例:
   **第一:客服模式根目录直接勾选
30-2自定义角色权限.png

   **第二:管理员模式  点击 展示所有功能模块,只需要勾选 质检功能的3个复选框
30-3自定义角色权限.png

       同时可以规则新角色的数据权限:租户或者客服
30-6自定义角色权限(改数据权限).png


 
   **第三:最后操作保存(tips:创建的自定义角色不能超过20个)
****2.给客服修改权限
管理员模式---成员管理--客服 
进入客服列表页面,选择要修改的客服,选项 一列点击编辑按钮
30-4自定义角色权限.png

 
弹出客服信息修改对话框,滑动到底部
修改角色,最后保存
30-5自定义角色权限.png

 
客服如果是登录状态,会自动给客服发送通知,客服需重新登录系统,新角色权限可以生效。
0
评论

客服云启用坐席 客服云启用坐席

开发讨论coinci 发表了文章 • 819 次浏览 • 2019-10-17 14:36 • 来自相关话题

                                                                                         启用坐席
1》管理员可以启用或禁用其他管理员和客服账户。一个租户下,在同一时间,最大启用数即为该租户的“购买坐席数”。
注:可以进入“管理员模式 > 设置 > 企业信息”页面,查看您的租户的“购买坐席数”和“账户到期日”。 
2》如果您的租户只购买了一个坐席,就只能使用当前管理员账号,不能操作禁用当前启用其他账号,一个租户至少 得有一个管理员权限的账号
3》管理员账号也占用一个坐席,可以切换到客服模式接会话
管理员模式--成员管理--客服列表 账户启用一列 可以启用或者禁用坐席账号(见下图)




  查看全部
                                                                                         启用坐席
1》管理员可以启用或禁用其他管理员和客服账户。一个租户下,在同一时间,最大启用数即为该租户的“购买坐席数”。
注:可以进入“管理员模式 > 设置 > 企业信息”页面,查看您的租户的“购买坐席数”和“账户到期日”。 
2》如果您的租户只购买了一个坐席,就只能使用当前管理员账号,不能操作禁用当前启用其他账号,一个租户至少 得有一个管理员权限的账号
3》管理员账号也占用一个坐席,可以切换到客服模式接会话
管理员模式--成员管理--客服列表 账户启用一列 可以启用或者禁用坐席账号(见下图)
9-1启用坐席.png

 
0
评论

客服云 配置机器人接会话 客服云 配置机器人接会话

开发讨论coinci 发表了文章 • 819 次浏览 • 2019-10-17 10:46 • 来自相关话题

****管理员模式--智能机器人 新建机器人,从机器人信息页面,点击蓝色字体:机器人管理,可跳转到机器人操作平台





****管理员模式----设置----会话分配规则  渠道:添加访客发起会话的渠道,可修改为全天机器人接入




****跳转到机器人平台添加知识规则或自定义菜单
1》添加知识规则





2》添加自定义菜单




 
注意:添加自定义菜单后,需要将该自定义菜单设置为机器人 的默认回复才可能触发(添加默认回复,选择为菜单类型,之后选择刚新建的自定义菜单,最后保存)






     更多机器人配置文档参见:
http://docs-ai.easemob.com/cs/ ... %259C
****发起会话测试
修改路由规则的配置后,新会话才能生效。可以先到管理员模式--当前会话手动关闭旧会话, 新会话测试




  查看全部
****管理员模式--智能机器人 新建机器人,从机器人信息页面,点击蓝色字体:机器人管理,可跳转到机器人操作平台
28-1配置机器人接会话.png


****管理员模式----设置----会话分配规则  渠道:添加访客发起会话的渠道,可修改为全天机器人接入
28-2配置机器人接会话.png

****跳转到机器人平台添加知识规则或自定义菜单
1》添加知识规则
28-3配置机器人接会话.png


2》添加自定义菜单
28-4配置机器人接会话.png

 
注意:添加自定义菜单后,需要将该自定义菜单设置为机器人 的默认回复才可能触发(添加默认回复,选择为菜单类型,之后选择刚新建的自定义菜单,最后保存)
28-5配置机器人_接会话.png



     更多机器人配置文档参见
http://docs-ai.easemob.com/cs/ ... %259C
****发起会话测试
修改路由规则的配置后,新会话才能生效。可以先到管理员模式--当前会话手动关闭旧会话, 新会话测试
28-6配置机器人接会话.png

 
0
评论

客服云 修改语言 客服云修改语言

开发讨论coinci 发表了文章 • 723 次浏览 • 2019-10-17 10:39 • 来自相关话题

*****修改客服系统语言********
  客服系统切换语言(支持中英文切换)

1.登录的时候
浏览器打开 https://kefu.easemob.com/
界面右上角可以切换语言





2.如果是已登录状态,切换到客服模式
客服模式--客服信息 语言一栏可以切换,最后需点击右下角保存




*********************************************************************
************网页集成切换到英文**************
webim 后面添加/en-US/





切换后界面如下




  查看全部
*****修改客服系统语言********
  客服系统切换语言(支持中英文切换)

1.登录的时候
浏览器打开 https://kefu.easemob.com/
界面右上角可以切换语言
27-1修改语言.png


2.如果是已登录状态,切换到客服模式
客服模式--客服信息 语言一栏可以切换,最后需点击右下角保存
27-2修改语言.png

*********************************************************************
************网页集成切换到英文**************
webim 后面添加/en-US/
27-3修改语言.png


切换后界面如下
27-4修改语言.png

 
0
评论

客服云网页下班留言配置 客服云网页下班留言配置

开发讨论coinci 发表了文章 • 736 次浏览 • 2019-10-17 10:35 • 来自相关话题

                                                                              网页下班留言配置
网页渠道:如果下班时间的路由规则是指定的技能组,可以从网页插件页面配置 下班时间让访客直接进入留言界面,这样下班时间访客无法发起会话,只能提交留言(注意:网页端访客暂时无法收到客服和管理员对留言的评论,需要通过电话或邮箱联系访客。 )
如需修改,客服系统 切换到管理员模式--渠道管理--网站 --- 功能设置页签,找到 下班留言配置:可修改为 展示默认消息或进入聊天窗,最后保存。访客端需重新加载页面





  查看全部
                                                                              网页下班留言配置
网页渠道:如果下班时间的路由规则是指定的技能组,可以从网页插件页面配置 下班时间让访客直接进入留言界面,这样下班时间访客无法发起会话,只能提交留言(注意:网页端访客暂时无法收到客服和管理员对留言的评论,需要通过电话或邮箱联系访客。 )
如需修改,客服系统 切换到管理员模式--渠道管理--网站 --- 功能设置页签,找到 下班留言配置:可修改为 展示默认消息或进入聊天窗,最后保存。访客端需重新加载页面

26-1网页下班留言配置.png

 
0
评论

客服云 访客发送的消息客服系统看不到排查 客服云 访客发送的消息客服系统看不到排查

开发讨论coinci 发表了文章 • 720 次浏览 • 2019-10-17 10:27 • 来自相关话题

                              访客发送的消息客服系统看不到
1. 先到 管理员模式--搜索  点击消息按钮,输入访客发送的消息内容 查询看下,默认是搜索的近7天的消息,如果时间不在7天内,可以重新点击筛选排序,放大时间范围筛选 。若可以查询到,点击会话后查看是哪一个客服接入的




如果直接无法看到是哪一个客服接入的,复制会话ID 到历史会话 ID一栏,查询出具体会话,点击进入会话详情页,看右侧记录一栏的数据,可以看出是哪一个客服接入的没有回复造成的





注:如果是该客服没有上线造成的没有回复消息。需要客服前一天退出登录前手动关闭自己进行中所有会话,这样才能保证新会话能自动调度给上线的客服
也可以通过配置 不活跃会话超时结束 或 访客超时未回复结束会话实现关闭会话(管理员模式--设置--系统开关 页面)
2.排查访客是否被加入黑名单
管理员模式---客户中心--客户信息 黑名单列表可以查看。
黑名单中的客户可以再次发送消息,但系统不会为其创建会话;客户被移除黑名单后,再次发送消息时可以成功创建会话。 
如果用户是在黑名单中,可以先移除黑名单后再测试。





3.如果搜索模块无法查询到,黑名单中也没有任何数据。可以工作时间发起会话咨询在线客服解决,感谢配合 查看全部
                              访客发送的消息客服系统看不到
1. 先到 管理员模式--搜索  点击消息按钮,输入访客发送的消息内容 查询看下,默认是搜索的近7天的消息,如果时间不在7天内,可以重新点击筛选排序,放大时间范围筛选 。若可以查询到,点击会话后查看是哪一个客服接入的
22-1访客发送的消息客服系统看不到.png

如果直接无法看到是哪一个客服接入的,复制会话ID 到历史会话 ID一栏,查询出具体会话,点击进入会话详情页,看右侧记录一栏的数据,可以看出是哪一个客服接入的没有回复造成的
22-2访客发送的消息客服系统看不到.png


注:如果是该客服没有上线造成的没有回复消息。需要客服前一天退出登录前手动关闭自己进行中所有会话,这样才能保证新会话能自动调度给上线的客服
也可以通过配置 不活跃会话超时结束 或 访客超时未回复结束会话实现关闭会话(管理员模式--设置--系统开关 页面
2.排查访客是否被加入黑名单
管理员模式---客户中心--客户信息 黑名单列表可以查看。
黑名单中的客户可以再次发送消息,但系统不会为其创建会话;客户被移除黑名单后,再次发送消息时可以成功创建会话。 
如果用户是在黑名单中,可以先移除黑名单后再测试。
22-3访客发送的消息客服系统看不到.png


3.如果搜索模块无法查询到,黑名单中也没有任何数据。可以工作时间发起会话咨询在线客服解决,感谢配合
0
评论

客服云查看会话满意度评价 客服云查看会话满意度评价

开发讨论coinci 发表了文章 • 762 次浏览 • 2019-10-17 10:02 • 来自相关话题

                                                                          查看会话的满意度评价
两种情况:查看具体某一个会话的评分或者是查看系统对所有会话评分的统计结果
1》查看具体某一个会话的评分
结束的会话才能到历史会话看评分。先把会话关闭掉,之后可以到管理员模式---历史会话模块,列表直接有评分一列的数据。如果列表不显示关闭的会话,可以点击右上角筛选排序,重新指定条件筛选出会话(可选择按会话结束时间筛选)




或者点击一个会话,进入会话详情页,看右侧指标一栏(如下图)





2》查看系统对会话的评价总统计结果
管理员模式--会话统计--工作质量 页面,页面顶部的满意度评分是系统的会话评价统计,页面底部是对每一个客服服务的评分统计(见下图)









  查看全部
                                                                          查看会话的满意度评价
两种情况:查看具体某一个会话的评分或者是查看系统对所有会话评分的统计结果
1》查看具体某一个会话的评分
结束的会话才能到历史会话看评分。先把会话关闭掉,之后可以到管理员模式---历史会话模块,列表直接有评分一列的数据。如果列表不显示关闭的会话,可以点击右上角筛选排序,重新指定条件筛选出会话(可选择按会话结束时间筛选)
查看评价19-1.png

或者点击一个会话,进入会话详情页,看右侧指标一栏(如下图)
查看评价19-2.png


2》查看系统对会话的评价总统计结果
管理员模式--会话统计--工作质量 页面,页面顶部的满意度评分是系统的会话评价统计,页面底部是对每一个客服服务的评分统计(见下图)
查看评价19-3.png


查看评价19-4.png

 
0
评论

客服云 客服管理操作 客服云客服操作

开发讨论coinci 发表了文章 • 664 次浏览 • 2019-10-17 09:58 • 来自相关话题

1》添加客服
管理员模式--成员管理--客服 右上角 添加客服按钮
添加时可以设置 客服账号邮箱密码、昵称、最大接待人数、权限等信息。如果需要重置坐席密码也可在此页面操作。




2》修改客服状态
管理员可以修改客服或其他管理员的在线状态,支持在空闲、忙碌、隐身、离开状态之间切换。在客服列表中点击“在线状态”一列的下拉按钮,修改客服的在线状态。
注:若客服离线,则不可强行修改其状态为在线。暂不支持自定义角色修改管理员或客服的在线状态。




 
3》设置客服最大接待人数
最大接待人数可以由管理员统一操作也可以由每一个客服自行调整自己的数量(二者只能选其一)
 ----1---统一由管理员调整
管理员模式--设置--系统开关 客服自定义最大接待人数 需要关闭。之后管理员在 成员管理--客服 页面点击编辑按钮,弹窗后可以修改客服的最大接待人数 ,最后保存





----2---每一个客服自行修改自己的最大接待人数
管理员模式--设置--系统开关 客服自定义最大接待人数 需要开启。修改后客服模式 最大接待人数为可调状态




 
客服更多配置操作参见以下文档:
http://docs.easemob.com/cs/200 ... %2586 查看全部
1》添加客服
管理员模式--成员管理--客服 右上角 添加客服按钮
添加时可以设置 客服账号邮箱密码、昵称、最大接待人数、权限等信息。如果需要重置坐席密码也可在此页面操作。
客服操作17-1.png

2》修改客服状态
管理员可以修改客服或其他管理员的在线状态,支持在空闲、忙碌、隐身、离开状态之间切换。在客服列表中点击“在线状态”一列的下拉按钮,修改客服的在线状态。
注:若客服离线,则不可强行修改其状态为在线。暂不支持自定义角色修改管理员或客服的在线状态。
客服操作17-2.png

 
3》设置客服最大接待人数
最大接待人数可以由管理员统一操作也可以由每一个客服自行调整自己的数量(二者只能选其一)
 ----1---统一由管理员调整
管理员模式--设置--系统开关 客服自定义最大接待人数 需要关闭。之后管理员在 成员管理--客服 页面点击编辑按钮,弹窗后可以修改客服的最大接待人数 ,最后保存
设置客服最大接待人数18-1.png


----2---每一个客服自行修改自己的最大接待人数
管理员模式--设置--系统开关 客服自定义最大接待人数 需要开启。修改后客服模式 最大接待人数为可调状态
设置客服最大接待人数18-2.png

 
客服更多配置操作参见以下文档:
http://docs.easemob.com/cs/200 ... %2586
0
评论

客服云配置系统自动结束会话 客服云配置系统自动结束会话

开发讨论coinci 发表了文章 • 774 次浏览 • 2019-10-16 17:30 • 来自相关话题

                                                                   配置系统自动结束会话
注意:修改配置后针对新创建的会话生效,旧会话还是需要手动关闭
1》机器人名下的会话自动结束配置:
        管理员模式---智能机器人 会话超时设置页签 
可以设置超时时间和超时提示语
可以设置超时时间(1~30分钟)和1~5条超时回复。当访客超过设定时间仍没有回复消息时,机器人将随机从超时回复中选择1条回复访客,1分钟后访客仍没有回复,会话将被自动结束。 




 
2》人工客服名下的会话自动结束配置
        i. 会话在待接入排队的情况 
            管理员模式--设置--系统开关 待接入超时结束会话




 
       ii.会话由人工客服接入的情况(在人工客服的进行中会话列表)
           管理员模式--设置--系统开关 访客超时未回复自动结束会话                不活跃会话超时自动结束 两个配置项










注意:如果同时打开了“访客超时未回复自动结束会话”和“不活跃会话超时自动结束”开关,当满足任意开关的超时条件时,会话将会被自动结束。
配置文档可参考以下链接
http://docs.easemob.com/cs/200 ... %259D
注意:修改配置后针对新创建的会话生效,旧会话还是需要手动关闭
 
 
  查看全部
                                                                   配置系统自动结束会话
注意:修改配置后针对新创建的会话生效,旧会话还是需要手动关闭
1》机器人名下的会话自动结束配置:
        管理员模式---智能机器人 会话超时设置页签 
可以设置超时时间和超时提示语
可以设置超时时间(1~30分钟)和1~5条超时回复。当访客超过设定时间仍没有回复消息时,机器人将随机从超时回复中选择1条回复访客,1分钟后访客仍没有回复,会话将被自动结束。 
系统自动结束会话15-1.png

 
2》人工客服名下的会话自动结束配置
        i. 会话在待接入排队的情况 
            管理员模式--设置--系统开关 待接入超时结束会话
系统自动结束会话15-2.png

 
       ii.会话由人工客服接入的情况(在人工客服的进行中会话列表)
           管理员模式--设置--系统开关 访客超时未回复自动结束会话                不活跃会话超时自动结束 两个配置项
系统自动结束会话15-3.png


系统自动结束会话15-4.png


注意:如果同时打开了“访客超时未回复自动结束会话”和“不活跃会话超时自动结束”开关,当满足任意开关的超时条件时,会话将会被自动结束。
配置文档可参考以下链接
http://docs.easemob.com/cs/200 ... %259D
注意:修改配置后针对新创建的会话生效,旧会话还是需要手动关闭
 
 
 
0
评论

客服云问候语配置 客服云问候语配置

开发讨论coinci 发表了文章 • 814 次浏览 • 2019-10-16 17:06 • 来自相关话题

                                                             问候语的配置
(注意:问候语只有上班时间才会 自动发送,下班时间不会触发,上班时间是走的时间计划页面的配置)
客服系统可以同时配置三种问候语:企业问候语 技能组问候语 客服问候语三种,触发条件不同

1.  企业问候语(管理员模式--设置--系统开关 企业问候语):当访客发送首条消息后,收到系统自动发送的企业问候语。





2.技能组问候语(管理员模式--成员管理--在线技能组 基础设置 技能组问候语):会话调度给某个技能组后会触发该技能组的问候语




3.客服问候语(客服模式--客服信息 客服问候语 每一个客服配置自己的问候语):会话成功分配或转接给当前客服/管理员时,访客会收到系统自动发送的客服问候语




如果同时配置三个,可能都会触发。根据需求配置即可,一般情况只需要配置企业问候语。其他的不使用可以把对应开关关闭 查看全部
                                                             问候语的配置
(注意:问候语只有上班时间才会 自动发送,下班时间不会触发,上班时间是走的时间计划页面的配置)
客服系统可以同时配置三种问候语:企业问候语 技能组问候语 客服问候语三种,触发条件不同

1.  企业问候语(管理员模式--设置--系统开关 企业问候语):当访客发送首条消息后,收到系统自动发送的企业问候语。
问候语配置14-1.png


2.技能组问候语(管理员模式--成员管理--在线技能组 基础设置 技能组问候语):会话调度给某个技能组后会触发该技能组的问候语
问候语配置14-2.png

3.客服问候语(客服模式--客服信息 客服问候语 每一个客服配置自己的问候语):会话成功分配或转接给当前客服/管理员时,访客会收到系统自动发送的客服问候语
问候语配置14-3.png

如果同时配置三个,可能都会触发。根据需求配置即可,一般情况只需要配置企业问候语。其他的不使用可以把对应开关关闭
0
评论

客服云机器人转人工配置 客服云机器人转人工配置

开发讨论coinci 发表了文章 • 666 次浏览 • 2019-10-16 16:59 • 来自相关话题

                                       机器人转人工配置 
1》旧版机器人:
     管理员模式--智能机器人 自动回复--转人工设置。
     可以规定转人工时间(全时间段允许 全时间段禁止 自定义时间<仅上班 或者仅下班允许转接>)
     配置限制转接提示语
指定转人工技能组(如果是不指定,会话是转接到未分组。如果要实现机器人转接不同的技能组,此处选择为不指定,之后配合 会话分配规则页面的 关联指定 来实现机器人转接到不同技能组)












2》企业版机器人转人工配置
    1)管理员模式--智能机器人 点击机器人信息页面的蓝色字体 机器人管理 进入到机器人平台






    2)




上图是配置转人工时间段和指定技能组的
机器人设置模块--转人工设置 
默认情况可以把转人工指令和转人工意图开启即可





转人工指令可以自定义修改,默认的指令有:
中文:转人工、转坐席、转人工客服、转人工坐席、转人工服务;英文:chat with agent
   企业版机器人的转人工更多配置可以参见以下文档:
http://docs-ai.easemob.com/cs/ ... %25A5 查看全部
                                       机器人转人工配置 
1》旧版机器人
     管理员模式--智能机器人 自动回复--转人工设置。
     可以规定转人工时间(全时间段允许 全时间段禁止 自定义时间<仅上班 或者仅下班允许转接>)
     配置限制转接提示语
指定转人工技能组(如果是不指定,会话是转接到未分组。如果要实现机器人转接不同的技能组,此处选择为不指定,之后配合 会话分配规则页面的 关联指定 来实现机器人转接到不同技能组)

机器人转人工配置11-1.png


机器人转人工配置11-2.png



2》企业版机器人转人工配置
    1)管理员模式--智能机器人 点击机器人信息页面的蓝色字体 机器人管理 进入到机器人平台

机器人转人工配置11-3.png


    2)
机器人转人工配置11-4.png

上图是配置转人工时间段和指定技能组的
机器人设置模块--转人工设置 
默认情况可以把转人工指令和转人工意图开启即可

机器人转人工配置11-5.png

转人工指令可以自定义修改,默认的指令有:
中文:转人工、转坐席、转人工客服、转人工坐席、转人工服务;英文:chat with agent
   企业版机器人的转人工更多配置可以参见以下文档:
http://docs-ai.easemob.com/cs/ ... %25A5