本文作者:小黑黑

[微信]简单使用MessageHandler

小黑黑 1年前 ( 2019-03-23 ) 488 抢沙发
[微信]简单使用MessageHandler摘要:       在开发微信公众号之前,我们需要先了解一下微信消息的通信过程,从图中我们可以看出,当微信用户在微信客户端向公众号发送一条...

clipboard.png

      在开发微信公众号之前,我们需要先了解一下微信消息的通信过程,从图中我们可以看出,当微信用户在微信客户端向公众号发送一条消息的时候,首先这条消息会发送的微信服务器上,然后由微信服务器向我们的应用服务器发起另一个请求,然后我们的应用服务器处理完消息后再将请求的结果发送给微信服务器,最后由微信服务器发送到微信客户端。

在上面我们看到了,微信服务器和网站之间的消息传输格式主要是XML格式,让我们看看发送和响应的XML格式吧。我们以文字请求为例。

请求:

<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[text]]></MSGTYPE>
  <Content><![CDATA[CONTENT]]></CONTENT>
</xml>
参数描述
ToUserName开发者微信号
FromUserName发送方账号(OpenId)
CreateTime消息创建时间
MsgType消息类型,text
Content文本消息内容
MsgId消息Id,62位整数

      在了解了数据的传输格式后,我们就可以根据XML的结构,然后在响应的位置上填上内容,然后格式化输出就可以了,但微信的消息类型有很多,如果我们按照这种方式的话需要根据消息类型进行判断,然后在组装xml,想一想就是一件很恐怖的事情。senparc为我们提供了更加优雅的方式来处理这些消息,让我们一起来看看吧。

MessageHandler初体验     
一、通过Nuget包安装 Senparc.Weixin.Mp,Senparc.Weixin.Mvc两个dll

二、单个用户上下文类
/// <summary>
/// 单个用户上下文类
/// </summary>
public class CustomMessageContext : MessageContext<IRequestMessageBase, IResponseMessageBase>
{
    public CustomMessageContext()
    {
        base.MessageContextRemoved += CustomMessageContext_MessageContextRemoved;
    }

    private void CustomMessageContext_MessageContextRemoved(object sender, WeixinContextRemovedEventArgs<IRequestMessageBase, IResponseMessageBase> e)
    {
        var message = e.MessageContext as CustomMessageContext;
        if (message == null)
        {
            return;
        }
    }
}
三、创建MessageHandler类
/// <summary>
/// 消息处理类
/// </summary>
public class CustomMessageHandler : MessageHandler<CustomMessageContext>
{
    public CustomMessageHandler(Stream  inputStream, PostModel postModel, int maxRecordCount = 0)
        :base(inputStream, postModel, maxRecordCount)
    {

    }

    /// <summary>
    /// 默认返回一条消息,比如:当我们没有实现位置消息的时候,当用户发送位置消息,将会被此方法处理
    /// </summary>
    /// <param name="requestMessage"></param>
    /// <returns></returns>
    public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
    {
        var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
        responseMessage.Content = "回复默认消息";

        return responseMessage;
    }
}
四、在WeiXinController中创建Post方法

/// <summary>
/// 用户发送消息后,微信平台自动Post一个请求到这里,并等待响应XML
/// </summary>
/// <param name="postModel"></param>
/// <returns></returns>
[HttpPost]
[ActionName("Index")]
public ActionResult Post(PostModel postModel)
{
    //创建MessageHandler实例,对微信请求的详细判断都在这里面
    var messageHandler = new CustomMessageHandler(Request.GetRequestMemoryStream(), postModel, 10);

    try
    {
        //执行微信消息处理过程
        messageHandler.Execute();

        return new FixWeixinBugWeixinResult(messageHandler);

    }
    catch (Exception)
    {

        throw;
    }

}
这样我们就实现了最简单的消息处理。在CustomMessageHandler中我们可以看到base.CreateResponseMessage<T>,其中的T代表的是响应的类型。比如,我们要接收用户发送的文本消息类型,那么我们就可以重写相对应的方法。
/// <summary>
/// 文本消息
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();
    responseMessage.Content = "您发送的消息为:" + requestMessage.Content;

    return responseMessage;
}
那么同理,我们还可以重写位置信息消息等。。。,如果是点击按钮事件呢,同样很简单,我们只需要重写相对应的方法即可,如:
/// <summary>
/// 点击按钮事件
/// </summary>
/// <param name="requestMessage"></param>
/// <returns></returns>
public override IResponseMessageBase OnEvent_ClickRequest(RequestMessageEvent_Click requestMessage)
{
    var responseMessage = base.CreateResponseMessage<ResponseMessageText>();

    responseMessage.Content = "您点击了按钮:" + requestMessage.EventName;

    return responseMessage;
}
建议将CustomMessageHandler设置为部分类,将普通消息存放在一个类中,将事件消息存放在另一个类中,这样有助于我们维护代码。
分享到: 网站分享代码

发表评论

快捷回复:

评论列表 (暂无评论,488人围观)参与讨论

还没有评论,来说两句吧...