微信开发系列----04:消息机制,了解自定义文本响应
放暑假了,生活基本稳定下来,项目的剩余部分也要开始慢慢的研究了。
项目GitHub地址: https://github.com/Andyahui/xgyxsh_WeiXin
SDK的GitHub地址:https://github.com/JeffreySu/WeiXinMPSDK/
SDK官方介绍博客:http://www.cnblogs.com/szw/archive/2013/05/14/weixin-course-index.html
一:关于SDK中的消息处理机制说明
之前的一篇博文中有两个关于消息的方法,现在就让我们真正的了解它,因为微信服务器是转发客户端的消息继而发送给网站服务器,那这就存在弊端,它每一次只能发送一个,而且是每一个用户发送一个。这样服务器端的session就没有办法保存使用,这样我们就没有办法取到用户的个人信息。
1:了解Session和Cookie
SDK帮我们封装了所有用户的上下文实体的容器(全局上下文)WeixinContext<TM>,保存的是所以请求对象的信息,这样我们就可以在同一个应用中创建多个上下文实体。既然都有全局上下文信息了,那么想必单个用户的信息也就可以创建了,MessageContext就是用于保存单个用户的上下文信息(Wike),可以在这里获取用户的个人信息。保存在WeixinContent的MessageCollection及MessageQueus对象中。
二:xx学院官方微信的分析
我们学校的官方微信是白老大(博客)开发的,当时参加了市里面的比赛还得了奖,我们在老大的带领下也做了很多关于微信的项目,这几天就想好好的学习下微信,就一直在分析里面的代码,有了自己的一些想法。
现在服务器端可以进行简单的响应了,其实老大的微信开发前期也就是实现了用户在客户端发送消息,服务端响应等功能,只是他在后台管理里面添加文本素材,图文素材,功能管理,这些功能,其实意思就是想通过我们管理人员将我们自己需要响应的东西手动进行添加,明确需要回复哪些东西。
这里的这些管理就是我们经常做的CRUD的功能,主要是想让管理员在后台中可以进行配置,也方便管理。其实这里主要的内容是在功能设置里面,比如现有功能有查询成绩,查询课表,查询图书信息等,很是实用,他在这里面是将我们的各种外部的东西都进行的封装,比如查询成绩,是利用爬虫将学生管理系统中的成绩拉下来的,之后只要用户在客户端发送任何有关于成绩的字符就进行一次爬取;这样保证了数据的实时性,其实我觉得这里可以利用时间来将成绩保存在数据库中,这样我们不用每次接收到请求就去爬取数据,因为成绩的更新是有时间的,主要是在期末等几个时间段来添加成绩,其余时间的成绩是不变的。很多都是这样的,对于老大当时的技术做到这样已经很牛逼了;之后我们在一起开发别的项目的时候基本上在SDK的帮助下把微信80%的功能都实现了,也不得不说SDK的强大。
三:本地存储一些回复内容
--->想法是将回复给用户的内容可以在我们的管理系统中实现后台可配置,这样就方便编辑人员发布内容。
其实就是按照微信官方的文档内容来编写我们的实体。这样做的好处就是我们要是需要回复直接取数据库中的内容就OK。
就拿一个文本回复看就好了。这里有请求和响应两个类(请求只有一个,响应很多,对应微信的响应)
- 请求RequestMessage
/// <summary> /// 请求消息基类 /// </summary> public class RequestMessage : BaseEntity { /// <summary> /// 用户发来的关键字 /// </summary> public virtual string KeyWord { get; set; } /// <summary> /// 消息类型 /// </summary> public virtual RequestMsgType MsgType { get; set; } /// <summary> /// 响应消息的类型 /// </summary> public virtual ResponseMsgType ResponseMsgType { get; set; } /// <summary> /// 响应文本消息的ID /// </summary> public virtual Guid ResponseTextMessageId { get; set; } /// <summary> /// 响应文本消息 /// </summary> public virtual ResponseTextMessage ResponseTextMessage { get; set; } /// <summary> /// 响应图文消息ID /// </summary> public virtual Guid ResponseNewsMessageId { get; set; } /// <summary> /// 响应图文消息 /// </summary> public virtual ResponseNewsMessage ResponseNewsMessage { get; set; } /// <summary> /// 响应方法消息ID /// </summary> public virtual Guid ResponseMethodId { get; set; } /// <summary> /// 响应方法消息 /// </summary> public virtual ResponseMethodMessage ResponseMethodMessage { get; set; } }
- 响应ResponseTextMessage
/// <summary> /// 响应的文本消息 /// </summary> public class ResponseTextMessage : BaseEntity { public ResponseTextMessage() { // this.RequestMessage = new Collection<RequestMessage>(); } /// <summary> /// 文本内容 /// </summary> public virtual string Content { get; set; } /// <summary> /// 响应消息分类 /// </summary> public virtual ResponseMsgType ResponseMsgType { get; set; } /// <summary> /// 一对多属性配置----相当于导航属性 /// </summary> public virtual ICollection<RequestMessage> RequestMessage { get; set; } }
- 一些公用的枚举值
/// <summary> /// 用户的Request类型 /// </summary> public enum RequestMsgType : int { /// <summary> /// 用户发来文字时 /// </summary> Text = 0,//文本 Voice = 1,//语音 Image = 2,//图片 Menu = 3,//点击菜单 Subscription = 4,//订阅 NoMatch = 5,//没有匹配时 } /// <summary> /// 响应消息类型 /// </summary> public enum ResponseMsgType : int { Text = 0, News = 1, Music = 2, Image = 3, Method = 4 }
通过上面的代码可以发现RequestMessage和ResponseTextMessage之间存在着一对多的关系,也就是一个响应对应于多个请求。这只是里面的一个,还有图文消息,图片消息,地址位置消息,Music消息等,都可以进行这样的设置,只要我们将其保存到数据库中就OK了。
此时应该设置其Text的CRUD了,这样就可以保存到数据库中了。最终实现这样的效果就可以进行下一步自定义响应了。
四:自定义文本响应
我们现在已经在数据库中添加了文本的内容,但是要实现自定义回复,就需要考虑一些逻辑,我们试想一下:用户为什么需要自定义回复,肯定是想要知道一些内容,方便,快捷,比如我们假设用户发送你好,那么我们就回复你好,这样就行了。还有就是对于学生成绩,课表的查询,也是通过这样的方式来实现的,用户发送特定的文字,我们在后端得到用户发送的文字查看里面的内容,要是含有成绩或者课表那么就调用相应的方法,将其得到的成绩或者课表打包成html发送给微信服务器,接着发送给用户客户端。那么这里的逻辑在哪里写呢,之前我们重写了很多sdk中的基类,就在那里面。
/// <summary> ///1: 处理用户发送过来的文字消息。重写OnTextRequest方法。 /// </summary> /// <param name="requestMessage">请求消息</param> /// <returns></returns> public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) { //CreateResponseMessage<类型>根据当前的RequestMessage创建指定类型的ResponseMessage;创建相应消息. var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); if (requestMessage.Content=="客服") { //多客服功能。 return this.CreateResponseMessage<ResponseMessageTransfer_Customer_Service>(); } else { //普通文本功能。 responseMessage.Content = "您的OpenID是:" + requestMessage.FromUserName + "。\r\t您发送了文字信息:" + requestMessage.Content + "注意了,我是张辉"; return responseMessage; } }
这里只是简单的利用if…else来实现两种识别。和前面说的原理一样,先是查看请求中内容是否包含需要辨别的文字,接着调用对应的方法,从数据库中取出对应的数据,这样就可以实现我们的可配置。要是之后我们需要回复的内容多,那就需要使用switch语句来进行分支的多选择,这样就很方便了。
---------------------------期待之后的完整版自定义回复吧------------------------
![关注公众号,获取最新更新](https://images.cnblogs.com/cnblogs_com/netxiaohui/1894145/o_210419003737zaishuoahui.jpg)
但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.