微信小程序客服音讯使用

一、前言

客服音信使用

为抬高级小学程序的劳务能力,提升劳动品质,微信为小程序提供客服音讯能力,以便小程序用户可以方便火速地与小程序服务提供方开始展览关联。

    
 
前段时间一向在折磨基于Socket的产品在线升级模块。以前小编曾写过基于.Net
Remoting的、基于WCF的在线升级功能,由于并发量较小及当时期码经验的不足间接尚未实际运用。这一次下定狠心撰写基于Socket的在线更新效用,一方面是觉得Socket的并发量较高,另一方面也是祥和工作了一年多,积攒了迟早的经验,应该能hold住。本文将体现的是Protype本子,Release版本已在长途测试服务器上运转,并发数过万没有何难题,文件更新都很健康。代码的Github地址将在本文最终提供。本文将显示的在线更新作用模块涉及Devexpress
WPF、Webapi、Windows
Service,笔者会从最基础的开首说起,很是适合初入的新手,大牌只怕老车手可平昔略过。

作用介绍

用户可利用小程序客服新闻功效,与小程序的客服职员展开联络。

客服音讯会话入口有多个:

① 、小程序内:开发者在小程序内添加客服消息按钮组件,用户可在小程序内唤起客服会话页面,给小程序发新闻;

② 、已利用过的小程序客服音讯会汇聚突显在微信对话“小程序客服信息”内,用户能够在小程序外查看历史客服音信,并给小程序客服发音信。

图片 1

客服消息发出条件:小程序用户在小程序内唤起客服会话或用户给小程序客服发送音信,具体下发时间有效期及新闻条数限制见客服音讯行文条件申明

客服音信类型:方今支撑文件及图片类型音信

为尽量满意小程序开发者的必要,小程序可透过以下二种艺术发出客服音信:一 、调用发送客服音信接口;② 、使用公众平台网页版客服工具

 

行文条件注解

当用户和小程序客服发生一定动作的竞相时(具体动作列表请见下方表达),小程序可向用户下发客服音讯。

如今允许的动作列表如下,不一致动作触发后,允许下发音信条数和行文限期不一致。下发条数达到上限后,会回来错误码。

用户动作 允许下发条数限制 下发时限
用户通过客服消息按钮进入会话 1条 1分钟
用户发送信息 3条 48小时

可发送客服新闻条数不丰裕,上述用户动作会触发可下发条数及可发出限期的创新,可发出消息条数更新为当下可发出条数限制的最大值,有效下发时间范围也更新为最长有效时间。

二、方案

调用客服音讯接口发送客服音讯

当用户在小程序内开辟客服会话,或是给小程序客服发新闻,微信服务器会将音信(或事件)的数据包(JSON只怕XML格式)POST到开发者填写的U本田UR-VL。开发者收到请求后得以调用接口举办异步回复。

        商厦的成品是运作在某一BIM软件上的插件,要想做在线更新,有以下几种方案:

填写信息推送配置

登录小程序,在“设置-开发设置-音信推送”启用新闻推送效率并做到有关消息配置(包罗服务器地址、Token、及加密方法等)。

图片 2

图片 3

启用并设置服务器配置后,用户发送的新闻以及开发者需求的事件推送,都将被微信转载至开发者UPRADOL中。

图片 4

       
方案一:

接口调用

小程序客服新闻API文书档案

       
插件安装后会在客户桌面上生成三个飞速格局,双击急迅格局会运维多少个LaunchProduct.exe,在那里面举办翻新操作,更新完之后再开发银行BIM软件。

网页版客服工具

小程序也能够一贯运用微信公众平台网页版客服工具拓展客服新闻回复。

若小程序没有启用音信推送,则用户发送的消息将会被转载至网页版客服工具,客服人士可在网页版客服工具中连着并还原用户。

瞩目:“用户通过客服新闻按钮进入会话”事件将不会转化至网页版客服工具。

       
方案二:

绑定客服人士

运用网页版客服工具前,小程序管理员需在小程序后台完毕客服职员的绑定。方今小程序帮助绑定不多于玖拾捌个客服人士。

图片 5

       
用户率先运维BIM软件,点击插件里的翻新按钮,然后经过Socket下载文件。进度中Kill掉该BIM软件,执行文书替换,再自行运维该BIM软件。(不kill掉的话程序平素被占据是心有余而力不足创新文件的)

客服工具使用表明

 

报到并对接

已被绑定的小程序客服职员可扫码登录微信公众平台网页版客服工具,并精选相应的小程序帐号,登录后即可看出与小程序对话的用户,可选择联网对话。

图片 6

叁 、步骤详解

切换客服状态

点击在线状态,能够选取在线状态、离开状态或退出登录

图片 7

       无论方案一,照旧方案二,有个别大旨步骤是不变的。下边详细演说:

吸收消息

手动接入:客服人士上线后,点击“待接入”,即可在“待接入”列表中,手动接入待回复的对话

机关衔接:当待接入的对话太多时,能够在装置/接入设置中,开启自动联网

再一次接入:退出登录,或对话抢先半小时,需求再行接入,激活对话

图片 8

Step1:
从注册表中读取当前产品的版本、安装地方等新闻。注册表是在做产品安装包时就活该要做的一件业务。产品设置完就会在客户机生成对应的注册表音信。小编正好也是做产品安装包的,卓殊理解产品注册表里有何内容。那么那里,小编封装了八个读注册表的class,能够在Github项目里找到:RegistryUtils (UpdaterClient工程中)在此间要提醒的3个地点是:有时候注册证明明有内容,C#代码调节和测试却是null,那么消除的艺术如下:

出殡消息

早就接入的对话,客服职员能够在48刻钟内和用户实行对话,近年来支持发送文书、图片类型的新闻。

图片 9

var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? RegistryView.Registry64 : RegistryView.Registry32);

//用这个localMachineRegistry去OpenSubKey()
//而不是直接用Registry.LocalMachine去OpenSubKey()

选用正规

小程序客服消息使用除必须信守微信小程序平台运转规范外,还不可能违反以下规则,包罗但不防止:

  1. 不一样意恶意诱导用户展开或许接触客服新闻发出的操作,以达成可向用户下发客服音信目标
  2. 不容许恶意干扰,下发与用户发送的信息并未关联的、对用户造成扰乱的新闻
  3. 差别意恶意经营销售,下发内容涉及虚假夸大、违规类经营销售音讯
  4. 不允许行使客服消息向用户下发虚假、色情、暴力等违反国家法规规定的新闻

其它小程序客服,还足以用来设置教导用户关心公众号。

图片 10

 

后台平昔配置,想打开这一个网页就打开哪个网页,直接指点用户关切群众号  http://xiaokefu.hotapp.cn

图片 11

 

 


 

Step2:从注册表里读取完本土地资金财产品的连锁音讯后,小编把那些数据封装成二个指标,去哀求产品服务器上的有些Webapi。假设有更新文件,会回来给本人更新文件的大小及MD5值。更新文件的轻重缓急决定了自己各类分包的大大小小,更新文件的MD5值用于本身下载完分包举办统一后开始展览MD5比对,验证下载的包是还是不是完好。Md5Utils(UpdaterShare工程中)**

        /// <summary>
        /// Get Download File Info 
        /// </summary>
        /// <param name="basicInfo"></param>
        /// <param name="serverAddress"></param>
        /// <param name="controllerName"></param>
        /// <param name="actionName"></param>
        /// <param name="serverResult"></param>
        /// <returns></returns>
        public static bool RequestDownloadFileInfo(ClientBasicInfo basicInfo,
                                                   string serverAddress, 
                                                   string controllerName,
                                                   string actionName,
                                                   ref DownloadFileInfo serverResult)
        {
            var packageInfo = JsonConvert.SerializeObject(basicInfo);

            try
            {
                HttpClient httpClient = new HttpClient
                {
                    BaseAddress = new Uri(serverAddress),
                    Timeout = TimeSpan.FromMinutes(20)
                };

                if (ConnectionTest(serverAddress))
                {
                    StringContent strData = new StringContent(packageInfo, Encoding.UTF8, "application/json");
                    string postUrl = httpClient.BaseAddress + $"api/{controllerName}/{actionName}";
                    Uri address = new Uri(postUrl);
                    Task<HttpResponseMessage> task = httpClient.PostAsync(address, strData);
                    try
                    {
                        task.Wait();
                    }
                    catch
                    {
                        return false;
                    }
                    HttpResponseMessage response = task.Result;
                    if (!response.IsSuccessStatusCode)
                        return false;

                    try
                    {
                        string jsonResult = response.Content.ReadAsStringAsync().Result;
                        serverResult = JsonConvert.DeserializeObject<DownloadFileInfo>(jsonResult);
                        if (serverResult != null)
                        {
                            return true;
                        }                     
                    }
                    catch(Exception ex)
                    {
                        return false;
                    }                
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

 

 


 

Step3: 获得创新文件的大大小小及MD5值后,大家就足以开头本地通过Socket去哀求服务器下载更新文件了。那里的Socket小编利用的是APM写法,也便是异步编程模型。

APM是微软比较早的提供用于Socket通信的格局。其最普遍的写法便是BeginAction(byte[] buffer, int offset, int size, SocketFlags
socketFlags, AsyncCallback callback, object state),在callback回调函数里EndAction。

本人在Client里是经过转变四个Task,各个Task各有二个Socket去下载五分一文本,最后合并。

图片 12

           var tasks = new Task[packetCount];
           for (int index = 0; index < packetCount; index++)
           {
               int packetNumber = index;
               var task = new Task(() =>
               {                  
                  Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  ComObject state = new ComObject { WorkSocket = client, PacketNumber = packetNumber };
                  client.BeginConnect(remoteEp, ConnectCallback, state);
               });                  
               tasks[packetNumber] = task;
               task.Start();
           }
           Task.WaitAll(tasks);

 

那么部分线程接收文件快,有的吸收接纳文件慢。因为最终还要分别生成五个一时文件进行联合。所以须要3个线程同步,让快的或慢的都在终点线等着。那里即将用到
ManualResetEvent,其继承于EventWaitHandleEventWaitHandle又持续于WaitHandleManualResetEvent是怎么利用的吗?因为代码都在Github上,那里提炼一下,总括就是:
ManualResetEvent
早先为false的时候,只有在有些线程中使用ManualResetEvent.Set()艺术,才能让另一线程中写在ManualResetEvent.WaitOne()事后的代码运维。假诺主线程里调用了WaitOne(),那么主线程写在WaitOne自此的代码要想实行,就亟须等待子线程中调用Set()办法,不然主线程会向来不通在WaitOne()处。

 

在Socket里一定要定义三个谈得来产品的多少包格式,因为Socket里传的都是byte[],你一定要让客户端/服务器知道您发的byte[]是什么样看头啊,所以要定义数据包格式:

A Packet = start_tag + version_tag + request/response_tag + length_tag + data + crc16_tag        
  1. 秦皇岛标识,一般用 {
    0xAA, 0x55 }

  2. 格式版本,一时定为 {
    0x01 }

3.
出殡和埋葬标识,是客户端发的呢?如故服务器发的呢?

4.
尺寸标识,用于记录整个数据包的尺寸,此标识占1个字节

5.
数量,要传输的数额

6.
crc16校验码。用于判断传输的byte[]是否完整,相对于MD5,crc16校验码的字节数更短,不会占太多传输字节,非凡适合用于字节数组的比较。MD5平时用于文书相比。

那么,有了尺寸标识与crc16校验码的双保障,大家就足以了然传输的byte[]是或不是完整了。

当一方发送byte[]后,另一方接受后得以拿出长度标识,判断byte[]长度是不是正确;当长度正确后,使用
Crc16Utils 计算收取的byte[]的crc16码并与byte[]中的crc16码实行比对。

 


 

Step4:劳务器端的Socket是写在Windows
瑟维斯里的。更新文件就位于该Windows Service同路线下,因为Windows
Service在起步运作之后会在注册表写下相应音信,通过注册表就能知道该Windows
Service的进行路径,继而得到更新文件的门道。

图片 13

 

        /// <summary>
        /// Get Latest File From Windows Service by Registry
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static string GetFilePathFromService(string serviceName)
        {
            try
            {
                ServiceController[] services = ServiceController.GetServices();
                var socketService = services.FirstOrDefault(x => String.Equals(x.ServiceName, "SocketService"));
                if (socketService != null)
                {
                    var localMachineRegistry = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, Environment.Is64BitOperatingSystem ? 
                                                                       RegistryView.Registry64 : RegistryView.Registry32); 

                    var key = localMachineRegistry.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\" + serviceName);
                    if (key != null)
                    {
                        var serviceExePath = GetString(key.GetValue("ImagePath").ToString());
                        var folderPath = Path.GetDirectoryName(serviceExePath);
                        if (!String.IsNullOrEmpty(folderPath) && Directory.Exists(folderPath))
                        {
                            return folderPath;
                        }                    
                    }
                }
            }
            catch(Exception ex)
            {
                return null;
            }
            return null;
        }

 


 

 Step5: 当下载完文件,其实早就成功了9/10的办事了,剩下的独自正是回顾的交替文件,更新注册表信息等等。

最终附上完整的流程图:

图片 14

、其它**

自个儿在写Socket代码的时候参考了微软的示范,照旧不行有帮衬的,提出先看微软的以身作则再看Github的代码会更有益驾驭,在此提供下:

Microsoft官方示例:

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example

当前微软早已提供了更类似Socket底层的SocketAsync伊夫ntArgs(SAEA)写法,该方法差别于APM的是:

1.
APM多次Send\Receive会发生多个IAsyncResult对象,扩展消耗。

2.
SAEA十一分BufferManager以及池化能很好的调配服务器财富,有多少坑就蹲多少人,再多了就能够设想更换至其余服务器做平衡了。

3.
SAEA的面世能力比APM略高,可是坑也不少,比如APM中,通过EndReceive是不是为0笔者就能明白还有没有多少要收取,可是SAEA中的Available等于0时还大概有数据没接受完,这几个题材的化解措施网上各样种种,各位能够自身搜搜。SAEA的服务器写法作者看看之后有没有时间写写。

 

GitHub地址:https://github.com/airforce094/SocketUpdater

 

、最后**

    
此Github里关系Devexpress WPF、Webapi、Windows
Service,不求Star,您的翻阅正是对自身最大的帮助。有如何难题可留言相互研讨。二零一九年是因为企管层变动,人员及工作会有较大调整,突然觉得小店铺有时候也挺折腾的。小编继续淡定学车,坐看其变。

 

《原创,转发请注解来源》

来自:airforce094