精华内容
下载资源
问答
  • 求大神来帮帮嘛啊。 开始看了文档但是还有些不明白的,想做一个东西 但是要用到云信来进行聊天的
  • 导读:数据在很多业务中都至关重要,对于网易云信,我们通过数据来提升服务并促进业务持续增长。借助于服务监控平台的能力,我们可以很直观的感受到线上服务的运行状况,本文将详细分析网易云信服务监...

     

     

    导读:数据在很多业务中都至关重要,对于网易云信,我们通过数据来提升服务并促进业务持续增长。借助于服务监控平台的能力,我们可以很直观的感受到线上服务的运行状况,本文将详细分析网易云信的服务监控平台具体是如何实现的。

    文|戴强 网易云信资深数据平台开发工程师

     

    通常人类的恐惧都来源于对现实世界的未知。

    现实生活中存在很多的不确定性,恐惧是因为我们当前的认知无法对其作出合理解释。例如这次的疫情的突然爆发,人们对死亡的恐惧不断蔓延。世界存在很多的不确定性,什么是不确定性。假设我们对于明天的股票指数是涨是跌作出判断,在没有任何数据作支撑的情况下,我们只能像抛硬币一样都是百分之50的概率。我们所有作出的判断都是不可信的,我们会对自己的决定感到不安。

    假如人们了解了所有涉及某种即将发生的事件的因素,那么他们就可以精确地预测到这一事件;或者相反,如果发生了某个事件,那么就可以认为,它的发生是不可避免的,这便是拉普拉斯的信条(又名决定论)。

    正如以上的理论所表达的意思,数据可以帮助我们指引方向,并且验证我们的方向是否正确。同样,数据对于网易云信的发展来说也至关重要,我们需要通过数据来提升我们的服务,并促进业务持续增长。

    网易云信是集网易21年 IM 以及音视频技术打造的 PaaS 服务产品,我们一直致力于提供稳定可靠的通信服务,而如何保证稳定可靠呢?

    服务监控平台就是其中重要的一环,其就相当于布加迪威龙上的仪表盘,汽车的时速是多少,油量是否足够,当前的转速是多少,这些在仪表盘上一目了然,可以帮助我们做出判断:是不是还可以踩一点油门,必要的时候是不是该刹一下车。服务监控平台的目标和价值就在这里,它也就相当于网易云信这辆布加迪威龙的仪表盘,可以告诉我们当前的服务质量怎么样,是不是需要多加点“油”,是不是需要踩一下“油门”或者“刹车”,给我们和客户提供更多的信息,帮助我们提供最优质的、最可靠、最稳定的服务。

    本文就来详细分析网易云信的服务监控平台具体是如何实现的,将从整体架构出发,简单介绍网易云信服务监控平台的框架,再仔细分析包括数据采集、数据预处理、监控告警、数据应用四个模块的实现。

     

    1 系统架构

    现在网易云信的音视频数据基本都来源于客户端和服务端日志,所以整个数据的采集链路是其中非常重要的一环,决定了数据的有效性和时效性。

    首先,我们来看一下网易云信采集监控平台的整体架构,如下图:

    采集监控平台整体架构主要分为数据采集、数据处理、数据应用、监控告警四部分,整个处理流程如下:

    • 数据采集:

      • 我们主要的数据来源为业务 SDK 和应用服务器,这些数据可以通过 HTTP Api、Kafka 两种方式接入采集服务。

      • 采集服务对数据进行简单校验和拆分,然后通过 Kafka 传输到数据清洗服务。

    • 数据处理:数据处理服务主要负责对接收到的数据进行处理然后发给下游服务使用。其中我们提供了 JOSN 等简单的数据格式化能力,另外也提供了脚本处理模块,以支持更灵活更强大的数据处理能力,该能力也使得我们监控平台的数据处理能力更富多样性。

    • 监控告警:监控告警模块对于我们一开始提到的服务监控能力来说,是最重要的一环。我们对于采集到的数据进行分维度聚合统计和分析,使用丰富的聚合算法、灵活多变的规则引擎来最终达到服务预警和问题定位的目的。

    • 数据应用:清洗后的数据可以直接写入时序数据库供问题排查平台使用,也可以通过 Kafka 接入 es、HDFS、流处理平台,最终供应用层使用。例如:质量服务平台、通用查询服务、问题排查平台等。

    接下来我们会对上述四个模块进行详细的分析。

     

     

    2 数据采集

    数据采集是服务监控平台的入口,也是整个流程的第一步,下图是数据采集模块的架构图。

    上文也有提到,为了便于用户接入,我们提供了 HTTP API 和 Kafka 两个通道给业务方。

    • HTTP API 多用于端侧或服务器中偏实时的数据上报场景,用以支持秒级的数据接入。

    • Kafka 多用于高吞吐量、数据实时性要求不太高的场景。

    • 数据过滤预处理模块,提前将一些非法数据进行过滤,并预先数据拆分等处理。

    最后通过 Kafka 传输到数据处理服务,接下来就是数据处理阶段的介绍了。

     

     

    3 数据处理

    完成数据采集阶段后,即进入数据处理阶段,具体流程如下:

    • 任务调度,主要负责数据处理线程的生命周期管理,从启动到关闭。

    • 消费者,在获取数据后使用内部的队列进行解耦,从而达到横向扩展的能力以提高数据处理线程的并行度。

    • 处理单元,可以根据需要设置并行度:

      • 数据处理能力分成两种,通用规则和自定义脚本。通用规则就是简单的 JSON 转换、字段提取等,这些基本可以满足80%的需求,但是为了支撑类似多字段关联计算、正则表达式、多流关联处理等复杂业务,我们也提供了自定义脚本进行数据处理的能力。

      • 维度表的使用主要是针对多数据流关联处理的场景,为了解决数据量和并发高的问题使用了本地+第三方缓存的方案。

      • 时序数据库输出:时序数据库我们使用的是NTSDB,NTSDB 是网易数帆基于influxdb做的集群化方案,有高可用、高压缩比、高并发等特点。

    数据处理完之后,接下来一个比较重要的阶段就是监控告警。

     

    监控告警

    下面这张图简单展示了监控告警的流程:

    监控告警阶段分为指标聚合模块以及告警模块。

    指标聚合模块支持指定字段分组统计、灵活的聚合窗口时间、数据过滤、细粒度的算子级别的数据过滤、数据延迟最大时间。最重要的是我们支持了非常丰富的聚合算子:累加、最小/最大值、firstValue/lastValue、平均数、记录数、去重计数、TP系列(TP90/TP95/TP99)、环比、标准差等,同时还支持在第一次指标聚合后进行复合计算的能力(复合指标)。这些丰富的算子为我们实现更多灵活的监控规则提供了保证。

    另外我们将原有的一阶段聚合改成了两阶段聚合,为什么呢?因为在数据处理的过程中我们经常会遇到的一个问题:数据热点问题导致的倾斜。所以这里我们增加了预处理阶段,在这一阶段利用随机数进行打散,保证数据的均衡,然后预聚合的数据在第二阶段进行总的聚合处理。

    告警模块和指标聚合模块从原有的一个模块拆分为两个,指标模块更多的关注如何做数据聚合,而不是和告警模块耦合在一起作为告警模块的一部分。而告警作为一个附加的功能,只需要根据接收到的数据,做一些告警的规则校验、频控校验、告警信息封装、对接消息平台发送告警消息,同时支持了内部 IM 平台、短信、电话等消息通道,多样的消息通道是为了可以第一时间感知到问题的出现。

     

     

    5 数据应用

    数据应用现有的平台:数据可视化、质量服务平台、ELK日志平台、在线离线分析等。下面,我们针对每个平台简单介绍一下。

     数据可视化 

    数据可视化这部分,我们和大部分公司一样使用 Grafana 来实现。需要做可视化的数据可以先同步到NTSDB中,然后再使用 NTSDB 作为数据制作图表和大盘。另外对于不支持的图表,我们针对Grafana 做了二次开发以支持更多的可视化需求。

    下图皆是针对音视频问题排查场景做的一些仪表盘:

     质量服务平台 

    该平台旨在为客户提供直观、高效、全面、实时的问题定位排查工具,客户在收到问题反馈之时,可以第一时间发现、定位问题,并最终反馈用户和进行优化。

     ELK 日志平台 

    ELK 技术栈包含 Logstash、ES、Kibana 三个组件,是一整套日志采集、存储、查询及可视化的解决方案。当前在我们的体系中,更多的用于详细日志的查询。

     在线离线分析 

    这里我们使用 Kafka 作为数据管道,借助 Flink 平台对日志数据进行切分和归档。将这部分数据同步到离线数仓后,可以进行后续的数据挖掘分析工作,同样这里也不扩展讨论。

     

     

    6 总结

    以上就是本文的全部介绍,分析了网易云信服务监控平台的设计和实践,其中主要介绍了整个服务监控平台的系统架构,并且针对数据采集、数据处理、监控告警、数据应用四个点做了一些阐述。

    网易云信的整个数据采集监控体系从2020年初上线至今,从原有的十几个采集任务增长到了300多个,100+的关键用户行为和系统事件、300+的核心音视频指标,每日处理百万行的数据、T级的数据量。整个平台的并发量、吞吐量都在不断地上升,这都得益于云信业务的不断增长,但也使得我们对平台的稳定性和扩展性提出了更高的要求。未来,我们将借助于平台的能力为客户们提供更加优质的服务。

    作者介绍 

    戴强,网易云信数据平台资深开发工程师,一直从事数据平台相关工作,从0到1搭建了网易云信的实时和离线数仓体系,同时负责服务监控平台、数据应用平台、质量服务平台的设计开发工作。

     

     更多阅读 

    展开全文
  • 网易云信IM讲解

    千次阅读 2019-04-08 08:55:58
    网易云信H5地址下载 1 demo下载 首先下载当前当前demo,并本地运行,由于网易云信提供的是采用的是node中间件的模式,所以你如果直接运行 npm run dev 是运行的打包命令,你需要运行 npm run server,来运行他当前...

    本按钮只针对H5版本讲解,前端部分

    网易云信H5地址下载

    1 demo下载

    • 首先下载当前当前demo,并本地运行,由于网易云信提供的是采用的是node中间件的模式,所以你如果直接运行 npm run dev 是运行的打包命令,你需要运行 npm run server,来运行他当前的demo

    • 首先去网易云信控制端注册 注册完成之后,进入控制台,获取APPkey,因为这个是需要进行唯一通信的标识,把你当前的下载下来的demo,appkey 换成你申请的APPkey
      替换appkey

    • 由于你不能直接引用他的代码,所以你需要先创建一下你自己的项目 注意,vue版本不限制,vuecli 的版本需要是2.x 由于该demo引入的ui组件目前不支持vue cli3 所以你只能安装vue cli2,webpack版本不限制,vux文档地址
      ##2 创建自己项目

    • 然后创建你的项目,vue2.x 的创建项目的方式是

    npm install --global vue-cli
    /*
    *全局安装脚手架
    */
    vue init webpack my-project
    /*
    *创建基于webpack的项目,vuecli3 不是此方式注意
    *后面就是npm run dev 跑起你的项目
    */
    
    • 然后最简单的方式就是把当前云信项目下面的 Src目录下的所有复制到你的项目中,当然你直接运行肯定会出问题,所以你可以先复制过去但是别加路由,先走你自己的登陆流程
      • 你自己的请求登陆的流程无非就是,根据用户名,密码,进行与后端交互,然后后端 返回你一些需要的东西,
      login () {
         /*
    	 * 这里就是你需要做的一系列的登陆逻辑
    	 * 然后下面的代码是需要成功的时候去执行的东西
    	 * 他的demo 是用了md5加密了,你真实的逻辑就不用去进行加密
    	  /
          let sdktoken = md5(this.password)
          cookie.setCookie('uid', this.account.toLowerCase())
          cookie.setCookie('sdktoken', sdktoken)
          location.href = config.homeUrl
    	  /*
    	  *注意Cookie在浏览器端是ok 的,但是如果你需要打包成app 你需要替换成 localStorage,不然你
    	  *后面的所有操作都无法进行,你只需要全局替换 几个地方,第一就是所有的
    	  */
    	   cookie.setCookie('uid') cookie.setCookie('sdktoken')包含这2个地方全部替换成
    	   localStorage
    	   /*
    	   *接下来你就去走你的逻辑,你可以console.log()打印一下你console.log(this.account.toLowerCase())里面的
    	   *值,这些就是触发sdk里面的方法
        },
    

    3 引入项目修改配置

    • 然后接下来可以直接复制他的代码入你的项目中,但是需要注意几个事情
    1. 注意vux 的编码格式,需要在webpac里面配置
    • 打开webpack.base.conf.js 修改配置,可以参考vux配置地址,具体根据文档参考,以下是我配置修改的代码,可参考
    'use strict'
    const path = require('path')
    const utils = require('./utils')
    const config = require('../config')
    const vueLoaderConfig = require('./vue-loader.conf')
    // vux 必需品
    // 原来的 webpack.base.js 配置
    const vuxLoader = require('vux-loader')
    const webpackConfig = {
      context: path.resolve(__dirname, '../'),
      entry: {
      	app: './src/main.js'
      },
      output: {
      	path: config.build.assetsRoot,
      	filename: '[name].js',
      	publicPath: process.env.NODE_ENV === 'production' ?
      		config.build.assetsPublicPath : config.dev.assetsPublicPath
      },
      resolve: {
      	extensions: ['.js', '.vue', '.json', '.less'],
      	modules: [
      		resolve('src'),
      		resolve('node_modules')
      	],
      	alias: {
      		'vue$': 'vue/dist/vue.esm.js',
      		'@': resolve('src'),
      	}
      },
      module: {
      	rules: [{
      			test: /\.vue$/,
      			loader: 'vue-loader',
      			options: vueLoaderConfig,
      		},
      		{
      			test: /\.js$/,
      			loader: 'babel-loader?cacheDirectory=true',
      			include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')],
      		},
      		{
      			test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
      			loader: 'url-loader',
      			options: {
      				limit: 10000,
      				name: utils.assetsPath('img/[name].[hash:7].[ext]')
      			}
      		},
      		{
      			test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
      			loader: 'url-loader',
      			options: {
      				limit: 10000,
      				name: utils.assetsPath('media/[name].[hash:7].[ext]')
      			}
      		},
      		{
      			test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
      			loader: 'url-loader',
      			options: {
      				limit: 10000,
      				name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
      			}
      		},
      		{
      			test: /\.css$/,
      			loader: 'style!css!postcss!postcss-cssnext',
      			include: [resolve('src/themes'), resolve('node_modules/vux/src')]
      		},
      		{
      			test: /\.less$/,
      			loader: 'style!css!less',
      			include: [resolve('src/themes')]
      		},
      	]
      },
      node: {
      	// prevent webpack from injecting useless setImmediate polyfill because Vue
      	// source contains it (although only uses it if it's native).
      	setImmediate: false,
      	// prevent webpack from injecting mocks to Node native modules
      	// that does not make sense for the client
      	dgram: 'empty',
      	fs: 'empty',
      	net: 'empty',
      	tls: 'empty',
      	child_process: 'empty'
      },
    
    }
    
    module.exports = vuxLoader.merge(webpackConfig, {
      options: {},
      plugins: [{
      	name: 'vux-ui'
      }],
      externals: {
      	'vue': 'Vue',
      	'vuex': 'Vuex',
      }
    })
    
    function resolve(dir) {
      return path.join(__dirname, '..', dir)
    }
    
    • 修改**.babelrc**编码格式,也就是es6转es5的,还有就是es6中的引入代码的方式的编码,修改一下就可以,以下是修改的代码,可参考
    {
    "presets": [
     ["env", {
       "modules": "commonjs",
       "targets": {
         "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
       },
     		"loose": true,
     }],
     "stage-2"
    ],
    "plugins": ["add-module-exports","transform-vue-jsx", ["transform-runtime", {polyfill: true}]],
    "comments": false
    }
    

    4 手动触发SDK请求

    • 如果你第二次登陆之后,获取的还是你的第一次的数据,那么请你不要慌,手动触发一下他的方法就好,不知道怎么去触发?很简单打开vue中的APP.vue页面下面有一句注释可以看看

         // 提交sdk连接请求
         this.$store.dispatch('connect')
         this.$store.dispatch('updateRefreshState')
      
    • 你只需要在登录的时候,也去触发一下这个方法,那么你就可以动态更新到你的数据了

    5 跨域解决办法

    • 如果遇到跨域问题,别着急,你有三套解决办法,第一套 webpack 代理,第二套 node 中间件代理,第三套 nigix
    • webpack

      • 打开vue项目路径下的 config 地址下面的 index.js 中的 proxyTable
         '/api/**': {
         target: 'http://******',
         changeOrigin: true,
         pathRewrite: {
         '^/api': '' 
         }
         /*
         *此处的api 的名字就是代表http://47.110.146.12
         *比如如果你需要去请求数据的时候就是
         */
         	axios.get(api+ '/api/code/img')
         			.then(function(response) {
         			})
         			.catch(function(error) {
         				console.log(error);
              });
         	 /*此方法的唯一缺陷就是必须后端与前端端口一致,否则还是会报跨域错误
        }
      },
      
    • node.js

    mkdir -p myproject  
    //创建一个项目
    npm install --save-dev http-proxy-middleware
    npm install --save express
    //安装一下依赖
    const express = require('express');
    const app = express();
    var proxy = require('http-proxy-middleware');
    
    var onProxyReq = function(proxyReq, req, res) {
     // add new header to request
     // proxyReq.setHeader('x-added', 'foobar')
    }
    
    var onError = function(err, req, res) {
     console.log('Something went wrong.')
     console.log('And we are reporting a custom error message.')
    }
    
    // proxy middleware options
    var options = {
       target: 'https://api.server.domain',
       rejectUnauthorized:false,
       changeOrigin: true,
       onProxyReq: onProxyReq, 
       onError: onError,
       logLevel: "debug"
    };
    
    // create the proxy (without context)
    var exampleProxy = proxy('/api/**',options);
    app.use(exampleProxy);
    
    // create the listening
    app.listen('3000', function() {
       console.log('[DEMO] Server: listening on port 3000')
    });
    /*
    *解释:
    *从前端访问localhost:3000,地址以/api/开始的所有请求转发到https://api.server.domain后端服务
    *例如:
    *localhost:3000/api/common/info  =>   https://api.server.domain/api/common/info
    */
    
    
    • nigix 这个我不是很会,哈哈哈,知道一点
      ##6 路由强制验证
    • 如果这些基本都已经ok,但是你突然发现,他路由做了一个强制跳转,就是没有 cookie 的时候,直接跳转到你的登录页面去了,但是如果你第一次进入,肯定是需要进行,注册的,但是你点击注册还是会跳转登录,这个怎么办了,很简单,你在点击注册的时候,传递一个值
      这个值得类型,那些都由你自己定义,这个验证强制登录跳转的地方是在 src 目录下面的 store下面的 actions下面的index
      以下演示一个列子,肯定有其他办法,这个仅供参考
    function connectNim({state,commit,dispatch}, obj) {
    	  let {
    		force
    	  } = Object.assign({}, obj)
    	// 操作为内容页刷新页面,此时无nim实例
    	   if(!state.nim || force) {
    		let loginInfo = {
    			uid: localStorage.getItem('uid'),
    			sdktoken:localStorage.getItem('sdktoken'),
    		}
    		if(!loginInfo.uid) {
    			// 无cookie,直接跳转登录页
    		let regist=sessionStorage.getItem('registred')
    			if(regist==99){
    			/*
    			*这里这个就是如果当你点击了注册,或者找回密码的时候,会传递一个名为 99 的参数
    			*如果点击了,这里就会接收到 值,就不会强制跳转登录,会走你需要的流程,
    			*但是你记得登录之后,必须要清除当前的 值,否则会出问题的,不然你下次没有cookie 他也不会跳转
    			*到你的登录页面了,
    			*此方法仅供参考
    			}else{
    				location.href = '#/login'
    			}
    		} else {
    			console.log("有空")
    			// 有cookie,重新登录
    			dispatch('initNimSDK', loginInfo)
    		}
    	}
    }
    

    7 图片地址

    • 如果你后端返回的图片地址是一个完整的地址那么你可以忽略此处,如果只是返回了一个IP 地址后半段的地址,那么你就可以看看

      • 如果你后端返回了的是 /upload_pic/29e10cb1b3de0497b84424c9379a025d?imageView&thumbnail=40z40 这样一串,然后
        你通过云信返回的时候,会前面 多加一个 **HTTP//**我也不知道为啥,云信的客服也不知道为啥,好吧,那就替换Ip 地址, ES6中出了一个判断字符串是否含有另一个字符串的方法 includes 该方法的使用如下
      <img v-if="session.avatar.includes('http:///upload_pic')" :src="http_api+session.avatar.slice(7)">
      /*
      *此处就是替换图片地址方法,由于这个是 vue 循环出来的了,不需要你在外面new 一个对象
      *来进行,替换,直接采用,http_api dai 代表正确的ip 地址
      *但是如果采用此方式,你必须多写2个判断,
      *因为会存在 3种情况, 1返回的没有 http:///upload_pic   
      *2 会返回一个正确的图片地址
      *3 会只返回一个 /upload_pic/29e10cb1b3d  这样的地址,前面没有http
      *所以如果采用此方式你必须要写三个判断
      *或者就是采用另一个方式,获取当前的ip 在进行循环之前进行改变当前的值,来显示当前的图片地址,写一个案例地址
      */
             let conter = [{
        				a: "http:192.168.2.158/img/12",
        				b: 'kkk1',
        				c: 'test1'
        			},
        			{
        				a: "http:195.168.2.158/img/34",
        				b: 'kkk2',
        				c: 'test'
        			},
        			{
        				a: "http:192.168.2.158/img/56",
        				b: 'kkk3',
        				c: 'test'
        			}
        		]
        		/*
        		*这个模拟后端返回的数据
        		*先获取当前的ip 地址   window.location.host;  
        		*然后再去循环当前的哪个数据 for foreach都可以
        		*/
        		var contera = conter.forEach((r) => {
        			var cen=new URL(r.a)
        			console.log(cen)
        			var imgadd=cen.pathname
        			r.a=window.location.host+imgadd
                    newcenter.push(r);
        			return r;     
        		})
        	     console.log(newcenter)
        		 /*
        		 *你可以打印看看 conter.a 的ip 地址都被换成一样的了,然后你此时再去循环,就可以
        		 *完美的解决这个问题,2种方式,你都可以选择
        		 *具体第二种关于一个new URL 之后会出现什么请访问以下网址
        		 * http://nodejs.cn/api/url.html#url_url_strings_and_url_objects
        		 */
        		
        		
      

    8 打包

    • 手机端webpack 打包的代码,多看看webpack就可以了,主要是讲一下桌面应用打包 打包桌面应用程序的软件可以看看
      electronjs 如果你只是需要打包 一个小项目不需要定制开发的话,可以忽略文档,看这里也行
    • 首先你在你的vue项目中引入
     npm install electron --save-dev
     npm install electron-builder  --save-dev
     /* 
     *  这个代码的意思是引入这个打包的js 
     *  第二句的意思是进行打包命令
     */
    
    • 引入完成之后,打开 package.json 文件在 script 中加入下面这2句代码
      "scripts": {
        "electron_dev": "npm run build && electron build/electron.js",
        "electron_build": "electron-packager ./dist/ IM  --platform=win32 --arch=x64  --   icon=./src/assets/yizhu.ico  --overwrite"
    	/*第一句代码就相当于 npm run dev 一个意思
    	*进行预览查看
    	*第二句代码意思是进行打包命令
    	*语法:electron-packager <sourcedir> <appname> –platform=<platform> –arch=<arch> [optional flags…]
    
        *1. sourcedir 资源路径,在本例中既是./dist/
        *2. appname 打包出的exe名称
        *3. platform 平台名称(windows是win32)
        *4. arch 版本,本例为x64
        *5. [optional flags…] 配置项选填,可以设置二进制打包等,默认没有这些
    
      },
    

    ##9 发布桌面安装包

    • 首先你得去下载 打包工具,然后傻瓜式安装
    • 然后打开左上角的 File 跟着下面图片走
      第一步
      第二步
      第三步
      第四步
      第五步
      第六步
      第七步
      第八步
      第九步
    • 然后你去找到你对应安装的目录,就可以发送给别人进行安装了
    展开全文
  • 在项目开始的时候,聊天第三方sdk选择了网易云信,原因很简单,我们的竞争对手用的就是云信,所以老板要求也用这个sdk,在接入云信sdk后,遇到了一些问题,现在记录一下。1 根据我们项目的需求,我们创建了一个活动...

    在项目开始的时候,聊天第三方sdk选择了网易云信,原因很简单,我们的竞争对手用的就是云信,所以老板要求也用这个sdk,在接入云信sdk后,遇到了一些问题,现在记录一下。

    1 根据我们项目的需求,我们创建了一个活动小组(同时也会创建一个云信的群组),创建者可以取消这个活动,取消这个活动的时候,服务器要解散群组,这个时候,我们客户端依然会显示这个解散的群组,我们理解的是解散了就应该自己删除掉,进入app的时候,加载最近会话的聊天页面的时候,就不显示了,但是云信没有删除,我们问了他们的技术,最后的解决方式是解散群组会有一条通知:NotificationType.DismissTeam,我们在加载会话列表的时候,根据这个通知类型进行判断,然后手动删除这个群组。

     NIMClient.getService(MsgService.class).queryRecentContacts().setCallback(new RequestCallbackWrapper<List<RecentContact>>() {
    
                            @Override
                            public void onResult(int code, List<RecentContact> recents, Throwable exception) {
                                if (code != ResponseCode.RES_SUCCESS || recents == null) {
                                    return;
                                }
                                loadedRecents.clear();
                                Log.e("recents ==>","聊天列表长度:"+recents.size());
                                for(RecentContact recentContact:recents){
                                    MsgAttachment attachment = recentContact.getAttachment();
                                    if(attachment instanceof NotificationAttachment){
                                        NotificationAttachment notificationAttachment = (NotificationAttachment) attachment;
                                        String teamNotificationText = TeamNotificationHelper
                                                .getTeamNotificationText(recentContact.getContactId(),
                                                        recentContact.getFromAccount(),
                                                        (NotificationAttachment) recentContact.getAttachment());
                                        if(notificationAttachment.getType() == NotificationType.DismissTeam){
                                            NIMClient.getService(MsgService.class).deleteRecentContact(recentContact);
                                            NIMClient.getService(MsgService.class).clearChattingHistory(recentContact.getContactId(), recentContact.getSessionType());
                                        }else{
                                                loadedRecents.add(recentContact);
                                        }
                                    }else{
                                        loadedRecents.add(recentContact);
                                    }
    
                                }
                                // 初次加载,更新离线的消息中是否有@我的消息
                                for (RecentContact loadedRecent : loadedRecents) {
                                    if (loadedRecent.getSessionType() == SessionTypeEnum.Team) {
                                        updateOfflineContactAited(loadedRecent);
                                    }
                                }
                                // 此处如果是界面刚初始化,为了防止界面卡顿,可先在后台把需要显示的用户资料和群组资料在后台加载好,然后再刷新界面
                                //
                                msgLoaded = true;
                                if (isAdded()) {
                                    onRecentContactsLoaded();
                                }
                            }
                        });

    这样就把解散的群组给删除掉了。

    2 app卸载重新安装后,原来在最近会话的群组,现在不显示了,除非有人在群组发消息才会再次显示,解决方式就是去云信的后台,把漫游功能打开,默认是关闭的,问了云信客服,漫游是不收费的。


    3 我们创建了两个应用key,一个是正式环境的,另一个用作测试的,使用测试的key的时候,发现登录有问题

    https://api.netease.im/nimserver/user/create.action 时出现错误,返回信息:{"desc":"CurTime is illegal","code":414}

    后来发现这个curTIme是秒数不是毫秒数,然后云信技术让我们把测试的appkey和secret给他,然后完了刷新一下秘钥就行了。

    再遇到问题的话,会再补充。


    展开全文
  • 网易云信新春公告

    2019-01-31 20:30:00
    尊敬的网易云信用户:新年在即,网易云信提前祝大家:新年快乐!网易云信春节假期为:2019年2月2日-2月11日暖心提醒:为确保您的业务不受节假日影响,建议提前核实账户可用余额...

    尊敬的网易云信用户:

     新年在即,网易云信提前祝大家:新年快乐!
     网易云信春节假期为:2019年2月2日-2月11日
     
     
    暖心提醒:

     
     
    为确保您的业务不受节假日影响,建议提前核实账户可用余额,如果可用额度较低,建议在春节前完成充值,以防服务欠费关停。
     若您19年1月份有消费,为便于您核对账单,1月扣款将于2月14日完成。

     
     
    上班虽停,服务不打烊:

    • 2月2日、2月3日、2月11日 的9:30-18:00,为正式客户的服务QQ群提供技术支持服务。

    • 2月1日-2月11日, 可提交工单,将在2月12日开始按照工单提交顺序为您处理。

    • 2月2日-2月11日,如遇到紧急故障,可拨打电话:0571-8985-2634,为您处理紧急故障。

    • 2月2日-2月11日,可拨打VIP客服专线:4009-000-123,咨询服务。

    恭祝大家新年快乐!

    点击“阅读原文”,了解网易云信。
    展开全文
  • 1、看到这个问题,第一想法是可能组件导入有问题,于是查看了avchatkit版本,发现从官网上只能下载到7.6.0的组件包,但是我之前导入的uikit是7.2.0的,当时感觉可能是版本不一致导致的,于是找到网易云信客服,要到...
  • 网易云信9月大事记

    2019-09-30 14:01:21
    9月大事记网易云信MAJOR EVENTS动态速览网易云信携手海信S7,新社交开拓电视领域新未来;网易云信携手网信为吴江区政府打造政务通讯新场景;深入场景服务客户,网易云信构筑企业融...
  • 导读:网易云信作为音视频服务提供商的领导者,一直致力于提供顶级的音视频通话服务体验,为用户在各种恶劣环境下提供可靠的音视频服务。文|纪松网易云信资深音视频服务端开发工程师如何在极端弱网条件...
  • 网易云信2月大事记

    2020-02-28 09:00:00
    2月大事记网易云信MAJOR EVENTS动态速览网易云信为湖北疫区各金融机构免费提供线上远程视频坐席;网易云信联合壹点灵发起对抗疫情免费心理援助公益活动;网易云信等网易智慧企业多产...
  • 网易云信7月大事记

    2019-07-31 12:00:00
    7月大事记网易云信MAJOR EVENTS动态速览网易云信携手小天才Z6手表,用技术守护儿童安全;互联网招聘有温度,网易云信携手智联招聘打造沟通新场景;网易云信副总经理沈青松先生接受...
  • 网易云信8月大事记

    2019-08-30 11:30:00
    8月大事记网易云信MAJOR EVENTS动态速览网易云信携手嘉虹健康打造互联网医院新场景;网易云信亮相LiveVideoStackCon 2019,分享BBR在实时音视频领域的应用...
  • 阙杭宁如何带领团队打造云信云信稳定背后有着怎样的秘密?下文选自猿团对云信CTO阙杭宁的专访稿原文来源中国网,内容排版有删改“网易出品,必属精品”,开发界流传的这句话对于大多数开发者并不...
  • 网易云信11月大事记

    2019-11-29 11:30:00
    11月大事记网易云信MAJOR EVENTS动态速览网易云信携手无忧行与途家让旅行一路惊喜;网易(杭州)副总裁、网易智慧企业部总经理阮良受邀参加第八届中国创新创业大赛互联网行业总决赛...
  • 自网易云信发布以来已有超过12332个产品接入,全面覆盖各个行业。我们的客户太优秀,忍不住给大家安利一下。出场接入网易云信客服功能的秀品,圣诞开始果断发力,日活biubiu上涨!下面的图...
  • 阙杭宁如何带领团队打造云信云信稳定背后有着怎样的秘密?下文选自猿团对云信CTO阙杭宁的专访稿原文来源中国网,内容排版有删改“网易出品,必属精品”,开发界流传的这句话对于大多数开发者并不...
  • iOS使用网易云信在线视频聊天

    千次阅读 热门讨论 2016-02-01 14:05:05
    最近公司的项目需要在线视频的功能,用的网易云信的sdk。给大家分享一下(。◕ˇ∀ˇ◕)
  • 日前,网易云信视频云架构师席智勇在第七届GFIC全球家庭互联网大会进行了题为《网易云信融合CDN方案及实践》的分享,以下是演讲内容回顾。 想要阅读更多技术干货文章,欢迎关注网易云信博客。了解网易云信,来自...
  • 8月1日,网易云信全面启动技术服务体系“T服务”,在保证高并发服务下的稳定性之外,将增值服务和技术支持作为自身最大的附加优势进行升级,以让开发者获得更佳的用户体验,为开发加速。当前,云通...
  • 近日,网易云信客户共同发现有仿冒网站假冒网易云信官网,以网易云信或网易公司的名义骗取用户的服务费用,行为性质恶劣,致使网易云信客户遭受严重损失。针对上述假冒行为,网易云信将采取法律途经...
  • 网易云信短信验证码验证php实现

    千次阅读 2016-09-11 16:29:32
    网易云信5分一条,阿里大于4分5一条,但是网易云信自带验证系统,阿里大于需要自己指定验证码,自己做验证,但是,,,,阿里大于可以自己定义签名,而网易云信只能使用默认的【云短信】,而且阿里大于的短信模板...
  • 网易云信12月大事记

    2019-12-31 11:29:00
    12月大事记网易云信MAJOR EVENTS动态速览白驹过隙,岁月如梭,转眼我们将跨入21世纪第三个十年。回首2019,我们的关键词是“成长”。在过去的一年里,我们从未停止成长的脚步...
  • 微信小程序接入云信

    2019-12-16 14:41:45
    1,在云信的后台申请好对应的appkey之后,打开项目,如图所示,进入config/envConfig.js配置文件 2,envir = ‘online’ 是选择线上环境还是测试环境,改变对应的appkey,这里需要特别注意的就是,如果在后台没有...
  • 如果不是子弹短信的突然逆袭,可能很多人都不会知道网易云信这个名字,这个在背后默默支撑子弹短信的“神秘产品”到底是何方神圣,相信很多开发者朋友都和老孙一样,对此充满了好奇。恰逢网易云信三周年之际,老孙...
  • 2015年10月,网易云信作为网易云计算服务的先锋兵推出,开发者通过SDK和API即可获得稳定可靠的即时通讯、音视频通话、直播、点播等技术能力。 2018年10月,网易云信迎来了三周年里程碑。三年里,网易云信依靠网易18...
  • 网易云信短信对接-php

    2018-06-07 10:58:44
    1,发送短信片段代码   $p = new ServerAPI(self::KEY,self::SECRET);...$res=$p->sendSmsCode($... * @param $templateid [模板编号(由客服配置之后告知开发者)] * @param $mobile [目标手机号] * @param ...
  • 在“互联网+”背景下,网易云信致力于帮助合作伙伴,一起构建基于网易云信的成功业务实践和解决方案。网易云信可为合作伙伴提供产品的培训认证、销售咨询、技术对接和解决方案服务。具体而言,在产品...
  • Android项目中接入网易云信聊天

    千次阅读 2018-10-25 15:23:22
    由于项目中原有的聊天出现收发消息不及时以及其他的问题,导致客服那边损失了不少的订单,遂接入新的第三方即时聊天sdk。有人可能会说,为什么不自己写呢?技术人员不够,时间长,开发成本高,最主要的是,有几个小...
  • 集成云信SDK-web版-vue客服(伸手党)

    千次阅读 2019-11-15 17:28:52
    transfer: false // 是否转客服 } }, computed: { }, watch: {}, async created() { await this.initSDK() }, mounted() { }, destroyed() { }, methods: { initSDK() { this.nim = SDK.NIM....
  • 公司业务需要,PC端,移动端都用到了第三方网易云信 IM来实现在线客服咨询。在这当中难免遇到一些需求是网易云信没有提供,需要自行编码进行扩展的。写此篇文章的目的正是因业务需要,需要在网易云信的基础上进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 780
精华内容 312
关键字:

云信客服