搜尋
首頁微信小程式微信開發微信開發之接收文字訊息
微信開發之接收文字訊息May 09, 2017 am 09:43 AM

微信中的消息類型有:文本,圖片,語音,視頻,地理位置,連結和事件訊息。除了事件訊息外,其他的統稱為普通訊息。微信中訊息的推送與回應都是以xml資料包傳輸的。當使用者傳送訊息給公眾號碼時,微信伺服器在五秒鐘內收不到回應會斷掉連接,並且重新發起請求,總共重試三次。普通訊息可以使用msgid排重,以避免重複的訊息對業務邏輯的影響。

假如伺服器無法保證在五秒內處理並回复,可以直接回复空串,微信伺服器不會對此座任何處理,並且不會發起重試。要注意的是:這裡說的回覆空串並不是回覆空的文字訊息,而是直接Response.Write(“”)即可。

下面簡單對各普通訊息說明一下。

文字訊息:
<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName> 
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[text]]></MsgType>
 <Content><![CDATA[this is a test]]></Content>
 <MsgId>1234567890123456</MsgId>
 </xml>
圖片訊息:
<xml>
 <ToUserName><![CDATA[toUser]]></ToUserName>
 <FromUserName><![CDATA[fromUser]]></FromUserName>
 <CreateTime>1348831860</CreateTime>
 <MsgType><![CDATA[image]]></MsgType>
 <PicUrl><![CDATA[this is a url]]></PicUrl>
 <MediaId><![CDATA[media_id]]></MediaId>
 <MsgId>1234567890123456</MsgId>
 </xml>
語音訊息:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[voice]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><Format><![CDATA[Format]]></Format><MsgId>1234567890123456</MsgId></xml>
影片訊息:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1357290913</CreateTime><MsgType><![CDATA[video]]></MsgType><MediaId><![CDATA[media_id]]></MediaId><ThumbMediaId><![CDATA[thumb_media_id]]></ThumbMediaId><MsgId>1234567890123456</MsgId></xml>
地理位置訊息:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[location]]></MsgType><Location_X>23.134521</Location_X><Location_Y>113.358803</Location_Y><Scale>20</Scale><Label><![CDATA[位置信息]]></Label><MsgId>1234567890123456</MsgId></xml>
連結訊息:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1351776360</CreateTime><MsgType><![CDATA[link]]></MsgType><Title><![CDATA[公众平台官网链接]]></Title><Description><![CDATA[公众平台官网链接]]></Description><Url><![CDATA[url]]></Url><MsgId>1234567890123456</MsgId></xml>

細心的程式猿應該發現了,所有的訊息中(包括事件訊息),都包含下面幾個欄位

參數 #描述
ToUserName 接收方微訊號
#FromUserName 發送方微訊號,若為普通用戶,則是一個OpenID
CreateTime 訊息建立時間
MsgType 訊息類型

而訊息的類型在文章開頭已經講了,分別是:文字(text),圖片(image),語音(voice),視訊(video),地理位置(location),連結(link),事件(event)

為了方便管理和程式碼編寫,我們可以把這些訊息類型寫一個枚舉。如下:

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

這裡說明下,C#中event是關鍵字,所以event在列舉中就不能使用了,所以為了統一,我這裡的枚舉全部使用大寫的。

既然所有的消息體都有上面的幾個字段,那就可以寫一個基類,然後不同的消息實體繼承這個基類。 (一直在糾結一個問題,以前我都是將所有的消息體中的字段寫在一個類中,調用起來也很方便,只是類中的字段越來越多,看著都不爽。再加上本人才疏淺,物件導向也使用的不熟練,所以一直都是在一個類別中羅列所有的欄位

呼叫的時候直接   var ss = WeiXinRequest.RequestHelper(token, EncodingAESKey, appid );

返回一個WeiXinRequest,然後再對訊息類型和事件類型判斷,做出回應。讀性提高了,呼叫起來卻沒有之前方便了,各位朋友給點建議唄。

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

基類中定義了訊息體的公共字段,以及用於回應使用者請求的虛擬方法(回應訊息不是本文重點,所以方法體就沒有貼出來,請關注後續文章) 。

基底類別中方法的參數有個是EnterParam類型的,這個類別是用戶存取時和驗證訊息真實性需要使用的參數,包括token,加密金鑰,appid等。定義如下:

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

文字實體:

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

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

     
    }

語音實體:

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

    
    }

視訊實體:

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

    
    }

連結實體:

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

     
    }

訊息實體定義好了,下一步就是根據微信伺服器推送的訊息體解析成對應的實體。本打算用C#自帶的xml序列化發序列化的元件,結果試了一下總是報什麼xmls的錯,索性用反射寫了個處理方法:

public static T ConvertObj<T>(string xmlstr)
        {
            XElement xdoc = XElement.Parse(xmlstr);            var type = typeof(T);            var t = Activator.CreateInstance<T>();            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<TextMessage>(xml);                case MsgType.IMAGE: return Utils.ConvertObj<ImgMessage>(xml);                case MsgType.VIDEO: return Utils.ConvertObj<VideoMessage>(xml);                case MsgType.VOICE: return Utils.ConvertObj<VoiceMessage>(xml);                case MsgType.LINK:                    return Utils.ConvertObj<LinkMessage>(xml);                case MsgType.LOCATION:                    return Utils.ConvertObj<LocationMessage>(xml);                case MsgType.EVENT://事件类型                {
                    
                } break;                default:                    return Utils.ConvertObj<BaseMessage>(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解密開源版微信魔術方塊原始碼

#

以上是微信開發之接收文字訊息的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
PHP微信开发:如何实现消息加密解密PHP微信开发:如何实现消息加密解密May 13, 2023 am 11:40 AM

PHP是一种开源的脚本语言,广泛应用于Web开发和服务器端编程,尤其在微信开发中得到了广泛的应用。如今,越来越多的企业和开发者开始使用PHP进行微信开发,因为它成为了一款真正的易学易用的开发语言。在微信开发中,消息的加密和解密是一个非常重要的问题,因为它们涉及到数据的安全性。对于没有加密和解密方式的消息,黑客可以轻松获取到其中的数据,对用户造成威胁

PHP微信开发:如何实现客服聊天窗口管理PHP微信开发:如何实现客服聊天窗口管理May 13, 2023 pm 05:51 PM

微信是目前全球用户规模最大的社交平台之一,随着移动互联网的普及,越来越多的企业开始意识到微信营销的重要性。在进行微信营销时,客服服务是至关重要的一环。为了更好地管理客服聊天窗口,我们可以借助PHP语言进行微信开发。一、PHP微信开发简介PHP是一种开源的服务器端脚本语言,广泛运用于Web开发领域。结合微信公众平台提供的开发接口,我们可以使用PHP语言进行微信

PHP微信开发:如何实现用户标签管理PHP微信开发:如何实现用户标签管理May 13, 2023 pm 04:31 PM

在微信公众号开发中,用户标签管理是一个非常重要的功能,可以让开发者更好地了解和管理自己的用户。本篇文章将介绍如何使用PHP实现微信用户标签管理功能。一、获取微信用户openid在使用微信用户标签管理功能之前,我们首先需要获取用户的openid。在微信公众号开发中,通过用户授权的方式获取openid是比较常见的做法。在用户授权完成后,我们可以通过以下代码获取用

用PHP开发微信群发工具用PHP开发微信群发工具May 13, 2023 pm 05:00 PM

随着微信的普及,越来越多的企业开始将其作为营销工具。而微信群发功能,则是企业进行微信营销的重要手段之一。但是,如果只依靠手动发送,对于营销人员来说是一件极为费时费力的工作。所以,开发一款微信群发工具就显得尤为重要。本文将介绍如何使用PHP开发微信群发工具。一、准备工作开发微信群发工具,我们需要掌握以下几个技术点:PHP基础知识微信公众平台开发开发工具:Sub

如何使用PHP进行微信开发?如何使用PHP进行微信开发?May 21, 2023 am 08:37 AM

随着互联网和移动智能设备的发展,微信成为了社交和营销领域不可或缺的一部分。在这个越来越数字化的时代,如何使用PHP进行微信开发已经成为了很多开发者的关注点。本文主要介绍如何使用PHP进行微信开发的相关知识点,以及其中的一些技巧和注意事项。一、开发环境准备在进行微信开发之前,首先需要准备好相应的开发环境。具体来说,需要安装PHP的运行环境,以及微信公众平台提

PHP微信开发:如何实现群发消息发送记录PHP微信开发:如何实现群发消息发送记录May 13, 2023 pm 04:31 PM

随着微信成为了人们生活中越来越重要的一个通讯工具,其敏捷的消息传递功能迅速受到广大企业和个人的青睐。对于企业而言,将微信发展为一个营销平台已经成为趋势,而微信开发的重要性也逐渐凸显。在其中,群发功能更是被广泛使用,那么,作为PHP程序员,如何实现群发消息发送记录呢?下面将为大家简单介绍一下。1.了解微信公众号相关开发知识在了解如何实现群发消息发送记录之前,我

ThinkPHP6微信开发指南:快速搭建微信公众号应用ThinkPHP6微信开发指南:快速搭建微信公众号应用Aug 26, 2023 pm 11:55 PM

ThinkPHP6微信开发指南:快速搭建微信公众号应用引言:微信公众号作为一种重要的社交媒体平台,为个人和企业在市场推广、信息传播等方面提供了很大的机会。在这篇文章中,我们将介绍如何使用ThinkPHP6快速搭建一个微信公众号应用,并且提供一些常用的代码示例。环境准备在开始开发之前,我们首先需要准备好以下环境:PHP7以上版本ThinkPHP6框架微信公众号

PHP微信开发:如何实现语音识别PHP微信开发:如何实现语音识别May 13, 2023 pm 09:31 PM

随着移动互联网的普及,微信作为一款社交软件,越来越多的人开始使用,并且微信开放平台也给开发者带来了众多的机会。近年来,随着人工智能技术的发展,语音识别技术逐渐成为了移动端开发的热门技术之一。在微信开发中,如何实现语音识别成为很多开发者关注的问题。本文将介绍如何利用PHP开发微信应用实现语音识别功能。一、语音识别原理在介绍如何实现语音识别之前,我们先了解一下语

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版