加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程

发布时间:2021-05-20 09:39:07 所属栏目:大数据 来源: https://www.cnblogs.com/szw
导读:本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket。关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料,例如参考 SignalR 的官方教程:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introdu

  本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket。关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料,例如参考 SignalR 的官方教程:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-2.1

  我们先看一下完成本教程内容后,在小程序内实现的 WebSocket 效果:

私有及群发消息

?

小程序模板消息

?

  上图中包含了只有发送者本人可以收到的消息,以及群发的消息,还有一条发送者本人收到的模板消息。

  所有代码都已开源,可以在? https://github.com/JeffreySu/WeiXinMPSDK?中找到,其中服务器端代码位于 /Samples/Senparc.Weixin.MP.Sample.vs2017/Senparc.Weixin.MP.Sample.vs2017.sln 解决方案中,小程序客户端代码位于 /src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen.AppDemo 中。

  下面让我们开始吧!

  

服务器端

  首先,我们需要通过 nuget 安装 Separc.WebSocket 包:https://www.nuget.org/packages/Senparc.WebSocket。Senparc.WebSocket 包提供了可供小程序使用的 WebScoket 的基础功能封装(当然,它也可以被很好地使用在小程序以外的场景,只不过在其他场景中我们通常有更多的选择,以及更多的复杂的业务需求)。

?????? 注意:Senparc.WebSocket 提供了针对 .NET Framework 4.5 和 .NET Standard 2.0(支持 .NET Core)的两个版本。其中,前者使用了相对比较底层的 WebSocket 构建方式,而后者我们直接使用了 SignalR,因为 .NET Core 下的 SignalR 官方摆脱了对 jQuery 的依赖,而 jQuery 在微信小程序中是不被支持的,这也是为什么我们没有在 .NET Framework 4.5 中没有使用 SignalR 这个优秀组件的原因。

?????? 安装完毕 Senparc.WebSocket 之后,我们还需要在 startup.cs 中对其进行启用,如在 ConfigureServices() 方法中添加代码:

services.AddSenparcWebSocket<CustomNetCoreWebSocketMessageHandler>();//Senparc.WebSocket 注册(按需)

  注意:上述过程会附带执行 services.AddSignalR(); 指令,因此如果你在系统的其他地方也需要使用 SIgnalR,那么可以忽略对其注册过程。

  关于上述方法中的泛型 CustomNetCoreWebSocketMessageHandler,其逻辑类似于公众号的 CustomMessageHandler,用于对消息进行同一的处理。让我们来看一下 CustomNetCoreWebSocketMessageHandler.cs的样子:

 1 using System;
 2  System.Linq;
 3  System.Threading.Tasks;
 4  Senparc.WebSocket;
 5  Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
 6  Senparc.Weixin.WxOpen.Containers;
 7 
 8 namespace Senparc.Weixin.MP.Sample.CommonService.MessageHandlers.WebSocket
 9 {
10     /// <summary>
11     /// .NET Core 自定义 WebSocket 处理类
12     </summary>
13     public class CustomNetCoreWebSocketMessageHandler : WebSocketMessageHandler
14     {
15         override Task OnConnecting(WebSocketHelper webSocketHandler)
16         {
17             TODO:处理连接时的逻辑
18             return base.OnConnecting(webSocketHandler);
19         }
20 
21          Task OnDisConnected(WebSocketHelper webSocketHandler)
22 23             TODO:处理断开连接时的逻辑
24             .OnDisConnected(webSocketHandler);
25 26 
27 
28         override async Task OnMessageReceiced(WebSocketHelper webSocketHandler,ReceivedMessage receivedMessage,string originalData)
29 30             if (receivedMessage == null || .IsNullOrEmpty(receivedMessage.Message))
31             {
32                 return;
33             }
34 
35             var message = receivedMessage.Message;
36 
37             await webSocketHandler.SendMessage("originalData:" + originalData,webSocketHandler.WebSocket.Clients.Caller);
38             您发送了文字: message,1)">39             正在处理中(反转文字)...",1)">40 
41             await Task.Delay(1000);
42 
43             处理文字
44             var result = .Concat(message.Reverse());
45             await webSocketHandler.SendMessage(result,1)">46 
47             var appId = Config.SenparcWeixinSetting.WxOpenAppId;与微信小程序账号后台的AppId设置保持一致,区分大小写。
48 
49             try
50 51             
52                 var sessionBag = SessionContainer.GetSession(receivedMessage.SessionId);
53 
54                 临时演示使用固定openId
55                 var openId = sessionBag != null ? sessionBag.OpenId : onh7q0DGM1dctSDbdByIHvX4imxA"; "用户未正确登陆";
56 
57                 await webSocketHandler.SendMessage("OpenId:" + openId,1)">58                 await webSocketHandler.SendMessage("FormId:" + formId);
59 
60                 群发
61                 await webSocketHandler.SendMessage($[群发消息] [来自 OpenId:***{openId.Substring(openId.Length - 10,10)},昵称:{sessionBag.DecodedUserInfo?.nickName}]:{message}62 
63                 发送模板消息
64 
65                 var data = new WxOpenTemplateMessage_PaySuccessNotice(
66                     "在线购买",SystemTime.Now,"图书众筹","1234567890",67                     100,"400-9939-858","http://sdk.senparc.weixin.com");
68 
69                 var formId = receivedMessage.FormId;发送模板消息使用,需要在wxml中设置<form report-submit="true">
70 
71                 var data = new
72                 {
73                     keyword1 = new TemplateDataItem(来自小程序WebSocket的模板消息(测试数据)),1)">74                     keyword2 = new TemplateDataItem(SystemTime.Now.LocalDateTime.ToString()),1)">75                     keyword3 = new TemplateDataItem($来自 Senparc.Weixin SDK 小程序 .Net Core WebSocket 触发rn您刚才发送了文字:{message}76                     keyword4 =  TemplateDataItem(SystemTime.NowTicks.ToString()),1)">77                     keyword5 = 100.ToString(C)),1)">78                     keyword6 = 400-031-881679                 };
80 
81                 var tmResult = Senparc.Weixin.WxOpen.AdvancedAPIs.Template.TemplateApi.SendTemplateMessage(appId,openId,Ap1S3tRvsB8BXsWkiILLz93nhe7S8IgAipZDfygy9Bg",data,receivedMessage.FormId,1)">pages/websocket/websocketwebsocket82                          null83 84             catch (Exception ex)
85 86                 var msg = ex.Message + rnrn" + originalData + rnrnAPPID: appId;
87 
88                 await webSocketHandler.SendMessage(msg,webSocketHandler.WebSocket.Clients.Caller); VS2017以下如果编译不通过,可以注释掉这一行
89 
90                 WeixinTrace.SendCustomLog(WebSocket OnMessageReceiced()过程出错91 92 93     }
94 }
View Code

  从上述代码啊可以看到,CustomNetCoreWebSocketMessageHandler 继承了来自 Senparc.WebSocket 的 WebSocketMessageHandler 抽象类,实现了 3 个重要的方法:

  • ??? OnConnecting()
  • ??? OnDisConnected()
  • ??? OnMessageReceiced()

?

  其中最重要的就是 OnMessageReceiced() 方法,用于处理来自于小程序的 WebSocket 消息(注意:这条消息在小程序中经过了特殊约定的处理,才能到达此处,并被正确读取,在本文后面将会介绍)。

  上述方法中,执行了如下逻辑:

  1. 读取消息
  2. 向用户的客户端即时发送三条消息(originalData……、您发送了文字……、正在处理中(反转文字)...),本条消息只有发送者可以收到(注意使用了webSocketHandler.WebSocket.Clients.Caller)
  3. 对用户发送的消息字符串进行处理,使其反转
  4. 将处理结果发送给操作人的客户端(Caller)
  5. 线程休眠 1 秒钟(模拟长时间的系统执行)
  6. 向所有已经连接的客户端群发消息(包括发送者本人在内):[群发消息] [来自 OpenId:***…… (注意使用了webSocketHandler.WebSocket.Clients.All)
  7. 获取 formId,并使用获取到的 formId 发送模板消息

?

  上述过程中,一共发送了 5 条 WebSocket 消息,其中 4 条只有发送者本人可以收到,1 条所有人(包括发送者本人)可以收到,除此之外,还发送了一条模板消息。

  我们可以使用 SignalR 的优秀特性,有针对性地进行定向发送或分组发送,相关知识点可以参考官方教程,这里不再展开。

??

  接下来,我们需要在 Startup.cs 对 SignalR 添加一个 Hub 的路由规则,在 ?Configure() 方法中添加:

            使用 SignalR
            app.UseSignalR(routes =>
            {
                routes.MapHub<SenparcHub>(/senparcHub);
            });

  根据 SignalR 的定义,"/senparcHub" 是我们自定义的 Hub 的连接地址,和类的命名没有关联。泛型 SenparcHub 是我们自定义的 SignalR 类,代码如下:

 Senparc.WebSocket.SignalR;

 Senparc.Weixin.MP.CoreSample.WebSocket.Hubs
{
     SenparcHub : SenparcWebSocketHubBase
    {

    }
}

  注意:和常规的 SignalR 的 Hub 自定义类直接继承 Microsoft.AspNetCore.SignalR.Hub 类不同,这里继承了 SenparcWebSocketHubBase,由 SenparcWebSocketHubBase 继承了 Microsoft.AspNetCore.SignalR.Hub 类,SenparcWebSocketHubBase 为自动处理小程序消息进行了一系列的逻辑处理。因此,SenparcHub 也具备了所有??Microsoft.AspNetCore.SignalR.Hub 的能力,我们也可以用于常规的网页 WebSocket 通讯。

  下面我们来丰富一下这个类:

 Microsoft.AspNetCore.SignalR;
 Senparc.WebSocket.SignalR;
 System.Threading.Tasks;

 SenparcHub : SenparcWebSocketHubBase
    {
        <summary>
         给普通网页用的自定义扩展方法 /WebScoket
        </summary>
        <param name="user"></param>
        <param name="message"></param>
        <returns></returns>
        async Task SendCustomMessage(string user,1)"> message)
        {
            await Clients.All.SendAsync(ReceiveCustomMessage

?

  关于 Web 端的 WebSocket 不是本文的重点,这里不再展开,下面看小程序的客户端中如何处理。

?

小程序客户端

  第一步,创建或打开小程序客户端项目,如图:

  第二步:在 utils 文件夹中加入加入两个文件:

  1. signalr.1.0.js 文件(https://github.com/JeffreySu/WeiXinMPSDK/blob/Developer/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen.AppDemo/utils/signalr.1.0.js)
  2. senparc.websocket.js 文件(https://github.com/JeffreySu/WeiXinMPSDK/blob/Developer/src/Senparc.Weixin.WxOpen/src/Senparc.Weixin.WxOpen.AppDemo/utils/senparc.websocket.js)

  注意:signalr.js 文件还在测试中,目前请勿使用!虽然这里的 signalr.1.0.js 使用的并非最新的版本的 js 客户端文件,不过至今为止仍然支持最新的 SignalR nuget 包,可以放心使用。

  特别感谢?LcFireRabbit 提供的修改后的 signalr.js 文件!如果对于新版本 js 您有更好的解决方案,也欢迎留言交流!

?

?

  第三步:创建测试页面,见 websocket_signalr 文件夹:

?

  由于源代码都已经提供,这里不再展开,介绍一下和 WebSocket 通讯相关的核心代码,在 websocket_signalr.js 中:

var signalR = require(../../utils/signalr.1.0.js)
var senparcWebsocket = require(../../utils/senparc.websocket.js 3 
var connection; Signalr 连接
var app = getApp()
var socketOpen = false;WebSocket 打开状态
 7 Page({
  data: {
 9     messageTip: '正在连接中,请等待...'10     messageTextArr: [],1)">11     messageContent: TEST12     userinfo: {}
13   },1)">14   sendMessage
15   formSubmit: function (e) {
16     var that = this17     console.log(formSubmit18     if (socketOpen) {
19       var text = e.detail.value.messageContent;必填,获得输入文字
20       var sessionId = wx.getStorageSync(sessionId");选填,不需要可输入''
21       var formId = e.detail.formId选填formId用于发送模板消息,不需要可输入''
22       senparcWebsocket.sendMessage(text,sessionId,formId);发送 websocket 请求
23 
24       that.setData({
25         messageContent: ''
26       })
27     } else {
28 29         messageTip: WebSocket 链接失败,请重新连接!'
30 32   onLoad: function () {
34     console.log(onLoad35 36   onShow:function(){
37     console.log(onShow38 
39     40     var hubUrl = wx.getStorageSync(wssDomainName') + /SenparcHubHub Url
41     var onStart = function () {
42       console.log(ws started43       socketOpen = true44 45         messageTip: WebSocket 连接成功!46 47     };
48     connection = senparcWebsocket.buildConnectionAndStart(hubUrl,signalR,onStart);
49 
50     定义收到消息后触发的事件
51     var onReceive = function (res) {
52       console.log(收到服务器内容:' + res)
53       var jsonResult = JSON.parse(res);
54       var currentIndex = that.data.messageTextArr.length + 155       var newArr = that.data.messageTextArr;
56       newArr.unshift(
57 58           index: currentIndex,1)">59           content: jsonResult.content,1)">60           time: jsonResult.time
61         });
62       console.log(that);
63 64         messageTextArr: newArr
65       });
66 67     senparcWebsocket.onReceiveMessage(onReceive);
69     WebSocket 连接成功
70     wx.onSocketOpen(function (res) {
71       console.log(72       
73     })
74     WebSocket 已关闭
75     wx.onSocketClose(function (res) {
76       console.log(WebSocket 已关闭!77       socketOpen = false78 79     WebSocket 打开失败
80     wx.onSocketError(function (res) {
81       console.log(WebSocket连接打开失败,请检查!82   }
84 })
View Code

  其中:

  • 第 1 行引入之前创建的 signalr.1.0.js 文件。
  • 第 2 行引入之前创建的 senparc.websocket.js 文件。
  • 第 15 行由点击了界面上的【发送】按钮之后,触发提交form表单的事件(不使用form也可以,只是无法获取到formId,并用于发送模板消息)。
  • 第 19-21行准备了 3 个参数:text、sessionId、formId
  • 第 22 行使用封装好的 senparcWebsocket 进行 WebSocket 消息发送,?Senparc.WebScoket 的方法内部能够自动处理的格式,必须严格按照此格式设置,可以通过修改 senparc.websocket.js 增加属性,但是目前已经提供的属性不能减少(FormId 如果没有可以留空)。
  • 第 36 行开始,我们把 websocket 的连接和设置代码放在了 onShow() 事件中,而不是 onLoad(),这样可以确保用户每次回到此页面都能够正确获得连接。当然为了节省开销,我们也可以在 onLoad() 中启动连接,并在 onShow() 中对连接状态进行判断,这里是简化的做法。
  • 第 40 行,设置 SenparcHub 的连接地址。
  • 第 41-47 行,设置连接成功后的事件代码。
  • 第 48 行,正式启动 WebSocket 连接。
  • 第 51-67 行,设置收到 WebSocket 消息后的触发事件代码。
  • 第?69-82 行,使用微信官方的接口进行连接状态的监控。

?

  以上效果可以扫描下方二维码,授权登录后,点击【WebSocket】按钮进行体验(可开多个手机微信进行测试,但建议不要在一台上多开,微信的 websocket 限制比较多)。

?

  微信小程序开发QQ群:108830388?

?

列教程索引

地址:http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html

  1. Senparc.Weixin.MP SDK?微信公众平台开发教程(一):微信公众平台注册
  2. Senparc.Weixin.MP SDK?微信公众平台开发教程(二):成为开发者
  3. Senparc.Weixin.MP SDK?微信公众平台开发教程(三):微信公众平台开发验证
  4. Senparc.Weixin.MP SDK?微信公众平台开发教程(四):Hello World
  5. Senparc.Weixin.MP SDK?微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK
  6. Senparc.Weixin.MP SDK?微信公众平台开发教程(六):了解MessageHandler
  7. Senparc.Weixin.MP SDK?微信公众平台开发教程(七):解决用户上下文(Session)问题
  8. Senparc.Weixin.MP SDK?微信公众平台开发教程(八):通用接口说明
  9. Senparc.Weixin.MP SDK?微信公众平台开发教程(九):自定义菜单接口说明
  10. Senparc.Weixin.MP SDK?微信公众平台开发教程(十):多客服接口说明
  11. Senparc.Weixin.MP SDK?微信公众平台开发教程(十一):高级接口说明
  12. Senparc.Weixin.MP SDK?微信公众平台开发教程(十二):OAuth2.0说明
  13. Senparc.Weixin.MP SDK?微信公众平台开发教程(十三):地图相关接口说明
  14. Senparc.Weixin.MP SDK 微信公众平台开发教程(十四):请求消息去重
  15. Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密
  16. Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制
  17. Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明
  18. Senparc.Weixin.MP SDK 微信公众平台开发教程(十八):Web代理功能
  19. Senparc.Weixin.MP SDK 微信公众平台开发教程(十九):MessageHandler 的未知类型消息处理
  20. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十):使用菜单消息功能
  21. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)
  22. Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):如何安装 Nuget(dll) 后使用项目源代码调试

?

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读