문자 메시지 수신을 위한 WeChat 개발

Y2J
풀어 주다: 2017-05-09 09:43:21
원래의
2451명이 탐색했습니다.

WeChat의 메시지 유형은 텍스트, 사진, 음성, 비디오, 지리적 위치, 링크 및 이벤트 메시지입니다. 이벤트 메시지를 제외한 나머지 메시지를 통칭하여 일반 메시지라고 합니다. WeChat의 메시지 푸시 및 응답은 xml 데이터 패킷으로 전송됩니다. 사용자가 공식 계정으로 메시지를 보낼 때 WeChat 서버가 5초 이내에 응답을 받지 못하면 연결이 끊어지고 요청이 다시 시작되며 총 3번의 재시도를 거칩니다. 중복 메시지가 비즈니스 로직에 미치는 영향을 피하기 위해 msgid를 사용하여 일반 메시지를 중복 제거할 수 있습니다.

서버가 5초 이내에 처리 및 응답을 보장할 수 없는 경우, WeChat 서버는 이 요청을 처리하지 않으며 재시도를 시작하지 않을 것입니다. 여기에 언급된 빈 문자열에 대한 응답은 빈 텍스트 메시지에 대한 응답이 아니라 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消息类型

문서 시작 부분에 메시지 유형이 언급되어 있습니다: 텍스트, 이미지, 음성 , 비디오, 위치, 링크, 이벤트

관리 및 코드 작성을 용이하게 하기 위해 이러한 메시지 유형에 대한 열거형을 작성할 수 있습니다.

/// <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 ; 가독성은 좋아졌으나 호출이 예전만큼 편리하지 않습니다. 친구들, 제안 좀 해주세요

)

다음은 기본 클래스입니다.

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 유형입니다. 이 클래스는 사용자가 토큰, 암호화 키를 포함하여 메시지의 신뢰성을 액세스하고 확인할 때 사용해야 하는 매개변수입니다. 앱 등 정의는 다음과 같습니다.

/// <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; }

     
    }
로그인 후 복사

메시지 엔터티가 정의된 후 다음 단계는 WeChat 서버가 푸시한 메시지 본문을 해당 엔터티로 구문 분석하는 것입니다. 원래는 C#에 내장된 XML 직렬화를 사용하여 직렬화된 구성 요소를 보낼 계획이었지만 시도할 때마다 일부 XML 오류가 보고되었기 때문에 단순히 리플렉션을 사용하여 처리 방법을 작성했습니다.

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.

WeChat 공개 계정 플랫폼 소스 코드 다운로드

2.

WeChat Lala Takeaway 2.2.4 WeChat Rubik's Cube 소스 코드의 복호화된 오픈 소스 버전

위 내용은 문자 메시지 수신을 위한 WeChat 개발의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!