0

0

微信开发之接收文本消息

Y2J

Y2J

发布时间:2017-05-09 09:43:21

|

2794人浏览过

|

来源于php中文网

原创

微信中的消息类型有:文本,图片,语音,视频,地理位置,链接和事件消息。除了事件消息外,其他的统称为普通消息。微信中消息的推送与响应都是以xml数据包传输的。在用户发送消息给公众号时,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。普通消息可以使用msgid排重,以避免重复的消息对业务逻辑的影响。

假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此座任何处理,并且不会发起重试。需要注意的是:这里说的回复空串并不是回复空的文本消息,而是直接Response.Write(“”)即可。

下面简要对各普通消息说明一下。

文本消息:

 
  
 1348831860
 
 
 1234567890123456
 
图片消息:

 
 
 1348831860
 
 
 
 1234567890123456
 
语音消息:
13572909131234567890123456
视频消息:
13572909131234567890123456
地理位置消息:
135177636023.134521113.358803201234567890123456
链接消息:
1351776360<![CDATA[公众平台官网链接]]>1234567890123456

细心的程序猿应该发现了,所有的消息中(包括事件消息),都包含下面几个字段

参数 描述
ToUserName 接收方微信号
FromUserName 发送方微信号,若为普通用户,则是一个OpenID
CreateTime 消息创建时间
MsgType 消息类型

而消息的类型在文章开头已经讲了,分别是:文本(text),图片(image),语音(voice),视频(video),地理位置(location),链接(link),事件(event)

为了方便管理和代码编写,我们可以把这些消息类型写一个枚举。如下:

/// 
    /// 消息类型枚举    /// 
    public enum MsgType
    {        /// 
        ///文本类型        ///         TEXT,        /// 
        /// 图片类型        ///         IMAGE,        /// 
        /// 语音类型        ///         VOICE,        /// 
        /// 视频类型        ///         VIDEO,        /// 
        /// 地理位置类型        ///         LOCATION,        /// 
        /// 链接类型        ///         LINK,        /// 
        /// 事件类型        ///         EVENT
    }

这里说明下,C#中event是关键字,所以event在枚举中就不能使用了,所以为了统一,我这里的枚举全部使用大写的。

既然所有的消息体都有上面的几个字段,那就可以写一个基类,然后不同的消息实体继承这个基类。(一直在纠结一个问题,以前我都是将所有的消息体中的字段写在一个类中,调用起来也很方便,只是类中的字段越来越多,看着都不爽。再加上本人才疏学浅,面向对象也使用的不熟练,所以一直都是在一个类中罗列所有的字段

调用的时候直接   var ss = WeiXinRequest.RequestHelper(token, EncodingAESKey, appid);

返回一个WeiXinRequest,然后再对消息类型和事件类型判断,做出响应。

今天重新做了下调整,也就是分了子类基类,代码可读性提高了,调用起来却没有之前方便了,各位朋友给点建议呗。

下面是各消息实体

基类:

public abstract class BaseMessage
    {        /// 
        /// 开发者微信号        /// 
        public string ToUserName { get; set; }       /// 
        /// 发送方帐号(一个OpenID)       /// 
        public string FromUserName { get; set; }        /// 
        /// 消息创建时间 (整型)        /// 
        public string CreateTime { get; set; }        /// 
        /// 消息类型        /// 
        public MsgType MsgType { get; set; }        public virtual void ResponseNull()
        {
            Utils.ResponseWrite("");
        }        public virtual void ResText(EnterParam param, string content)
        {            
        }        /// 
        /// 回复消息(音乐)        /// 
        public  void ResMusic(EnterParam param, Music mu)
        {
        }        public  void ResVideo(EnterParam param, Video v)
        {        }        /// 
        /// 回复消息(图片)        /// 
        public  void ResPicture(EnterParam param, Picture pic, string domain)
        {
}        /// 
        /// 回复消息(图文列表)        /// 
        /// 
        /// 
        public  void ResArticles(EnterParam param, List art)
        {        }        /// 
        /// 多客服转发        /// 
        /// 
        public  void ResDKF(EnterParam param)
        {
}        /// 
        /// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。        /// 
        /// 用户发送的消息体
        /// 多客服账号
        public  void ResDKF(EnterParam param, string KfAccount)
        {        }        private  void Response(EnterParam param, string data)
        {            
        }
    }

基类中定义了消息体的公共字段,以及用于响应用户请求的虚方法(响应消息不是本文重点,所以方法体就没有贴出来,请关注后续文章)。

LHT蓝海豚团购导航
LHT蓝海豚团购导航

Lht蓝海豚(大维)团购导航系统是一套开源程序,采用PHP+MySql平台开发,具有强大的多规则API采集功能、精确化引导消费功能,卓越的负载能力和访问速度,全面支持第三方整合(微博、短信等)前台功能团购名站:显示分类下的所有团购网站,点击团购站,可直接进行查看、推荐、收藏精品商城:为网民推荐展示非团购网站的网上商城今日团购:显示各团购网站正在进行的团购团购排行:今日团购商品可按价格、行业、折扣、

下载

基类中方法的参数有个是EnterParam类型的,这个类是用户接入时和验证消息真实性需要使用的参数,包括token,加密密钥,appid等。定义如下:

/// 
    /// 微信接入参数    /// 
    public class EnterParam
    {        /// 
        /// 是否加密        /// 
        public bool IsAes { get; set; }        /// 
        /// 接入token        /// 
        public string token { get; set; }        /// 
        ///微信appid        /// 
        public string appid { get; set; }        /// 
        /// 加密密钥        /// 
        public string EncodingAESKey { get; set; }
    }

文本实体:

public class TextMessage:BaseMessage
    {       /// 
       /// 消息内容       /// 
        public string Content { get; set; }       /// 
        /// 消息id,64位整型       /// 
        public string MsgId { get; set; }

    
    }

图片实体:

public class ImgMessage : BaseMessage
    {       /// 
       /// 图片路径       /// 
        public string PicUrl { get; set; }       /// 
        /// 消息id,64位整型       /// 
        public string MsgId { get; set; }        /// 
        /// 媒体ID        /// 
        public string MediaId { get; set; }

     
    }

语音实体:

public class VoiceMessage : BaseMessage
    {       /// 
       /// 缩略图ID       /// 
        public string MsgId { get; set; }       /// 
        /// 格式       /// 
        public string Format { get; set; }        /// 
        /// 媒体ID        /// 
        public string MediaId { get; set; }        /// 
        /// 语音识别结果        /// 
        public string Recognition { get; set; }

    
    }

视频实体:

public class VideoMessage : BaseMessage
    {       /// 
       /// 缩略图ID       /// 
        public string ThumbMediaId { get; set; }       /// 
        /// 消息id,64位整型       /// 
        public string MsgId { get; set; }        /// 
        /// 媒体ID        /// 
        public string MediaId { get; set; }

    
    }

链接实体:

public class LinkMessage : BaseMessage
    {       /// 
       /// 缩略图ID       /// 
        public string MsgId { get; set; }       /// 
        /// 标题       /// 
        public string Title { get; set; }        /// 
        /// 描述        /// 
        public string Description { get; set; }        /// 
        /// 链接地址        /// 
        public string Url { get; set; }

     
    }

消息实体定义好了,下一步就是根据微信服务器推送的消息体解析成对应的实体。本打算用C#自带的xml序列化发序列化的组件,结果试了下总是报什么xmls的错,索性用反射写了个处理方法:

public static T ConvertObj(string xmlstr)
        {
            XElement xdoc = XElement.Parse(xmlstr);            var type = typeof(T);            var t = Activator.CreateInstance();            foreach (XElement element in xdoc.Elements())
            {                var pr = type.GetProperty(element.Name.ToString());                if (element.HasElements)
                {//这里主要是兼容微信新添加的菜单类型。nnd,竟然有子属性,所以这里就做了个子属性的处理                    foreach (var ele in element.Elements())
                    {
                        pr = type.GetProperty(ele.Name.ToString());
                        pr.SetValue(t, Convert.ChangeType(ele.Value, pr.PropertyType), null);
                    }                    continue;
                }                if (pr.PropertyType.Name == "MsgType")//获取消息模型
                {
                    pr.SetValue(t, (MsgType)Enum.Parse(typeof(MsgType), element.Value.ToUpper()), null);                    continue;
                }                if (pr.PropertyType.Name == "Event")//获取事件类型。
                {
                    pr.SetValue(t, (Event)Enum.Parse(typeof(Event), element.Value.ToUpper()), null);                    continue;
                }
                pr.SetValue(t, Convert.ChangeType(element.Value, pr.PropertyType), null);
            }            return t;
        }

处理xml的方法定义好后,下面就是讲根据不同的消息类型来解析对应的实体了:

public class MessageFactory
    {        public static BaseMessage CreateMessage(string xml)
        {
            XElement xdoc = XElement.Parse(xml);            var msgtype = xdoc.Element("MsgType").Value.ToUpper();
            MsgType type = (MsgType)Enum.Parse(typeof(MsgType), msgtype);            switch (type)
            {                case MsgType.TEXT: return Utils.ConvertObj(xml);                case MsgType.IMAGE: return Utils.ConvertObj(xml);                case MsgType.VIDEO: return Utils.ConvertObj(xml);                case MsgType.VOICE: return Utils.ConvertObj(xml);                case MsgType.LINK:                    return Utils.ConvertObj(xml);                case MsgType.LOCATION:                    return Utils.ConvertObj(xml);                case MsgType.EVENT://事件类型                {
                    
                } break;                default:                    return Utils.ConvertObj(xml);
            }
        }
    }

CreateMessage方法传入数据包(如加密,需解密后传入),以基类的形式返回对应的实体。

讲到这里普通消息的接收就差不多讲完了,结合上一篇博文,现在把修改后的接入代码贴出来如下:

public class WxRequest
    {       public static BaseMessage Load(EnterParam param, bool bug = true)
       {           string postStr = "";
           Stream s = VqiRequest.GetInputStream();//此方法是对System.Web.HttpContext.Current.Request.InputStream的封装,可直接代码
           byte[] b = new byte[s.Length];
           s.Read(b, 0, (int)s.Length);
           postStr = Encoding.UTF8.GetString(b);//获取微信服务器推送过来的字符串
           var timestamp = VqiRequest.GetQueryString("timestamp");           var nonce = VqiRequest.GetQueryString("nonce");           var msg_signature = VqiRequest.GetQueryString("msg_signature");           var encrypt_type = VqiRequest.GetQueryString("encrypt_type");           string data = "";           if (encrypt_type=="aes")//加密模式处理           {
               param.IsAes = true;               var ret = new MsgCrypt(param.token, param.EncodingAESKey, param.appid);               int r = ret.DecryptMsg(msg_signature, timestamp, nonce, postStr, ref data);               if (r != 0)
               {
                   WxApi.Base.WriteBug("消息解密失败");                   return null;

               }
           }           else
           {
               param.IsAes = false;
               data = postStr;
           }           if (bug)
           {
               Utils.WriteTxt(data);
           }           return MessageFactory.CreateMessage(data);
       }
    }

【相关推荐】

1.微信公众号平台源码下载

2.微信啦啦外卖2.2.4解密开源版 微信魔方源码

相关文章

微信app下载
微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

76

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

73

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

67

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

19

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.9万人学习

Rust 教程
Rust 教程

共28课时 | 5.2万人学习

Vue 教程
Vue 教程

共42课时 | 7.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号