using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using Senparc.Weixin.MP.Entities.Request;
using Senparc.Weixin.MP.MvcExtension;
using Senparc.Weixin.MP.Sample.CommonService.CustomMessageHandler;
using System.IO;
using Senparc.Weixin;
using Senparc.Weixin.MP;
namespace Yespace.Site.Areas.Weixin.Controllers
{ //
public class WxAsyncController : AsyncController
{
public static readonly string Token = Config.SenparcWeixinSetting.Token ?? CheckSignature.Token;//与微信公众账号后台的Token设置保持一致,区分大小写。
public static readonly string EncodingAESKey = Config.SenparcWeixinSetting.EncodingAESKey;//与微信公众账号后台的EncodingAESKey设置保持一致,区分大小写。
public static readonly string AppId = Config.SenparcWeixinSetting.WeixinAppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
readonly Func<string> _getRandomFileName = () => DateTime.Now.ToString("yyyyMMdd-HHmmss") + "_Async_" + Guid.NewGuid().ToString("n").Substring(0, 6);
//正式发布时要将wxToken换成真正的Token wxToken属于写死的Token
string wxToken = "";
public WxAsyncController()
{
}
[HttpGet]
[ActionName("Index")]
public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr, string spaceid)
{
return Task.Factory.StartNew(() =>
{
// if (CheckSignature.Check(signature, timestamp, nonce, Token))
if (CheckSignature.Check(signature, timestamp, nonce, wxToken))
{
return echostr; //返回随机字符串则表示验证通过
}
else
{
//return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, Token) + "。" +
// "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。";
return "failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, wxToken) + "。" +
"如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。";
}
}).ContinueWith<ActionResult>(task => Content(task.Result));
}
public CustomMessageHandler MessageHandler = null;//开放出MessageHandler是为了做单元测试,实际使用过程中不需
/// <summary>
/// 最简化的处理流程
/// </summary>
[HttpPost]
[ActionName("Index")]
public async Task<ActionResult> Post(PostModel postModel)
{
//正式发布时要将wxToken换成Token wxToken属于写死的Token
if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, wxToken))
{
return new WeixinResult("参数错误!");
}
//postModel.Token = Token;
//postModel.EncodingAESKey = EncodingAESKey; //根据自己后台的设置保持一致
// postModel.AppId = AppId; //根据自己后台的设置保持一致
//测试时,直接写入,正式发布时删除
postModel.Token = wxToken;
postModel.EncodingAESKey = "MJgY1dTgoSGfkle9I7aypwR2mLuuC3NMuITLoNSXyHj"; //根据自己后台的设置保持一致
postModel.AppId = "wxc255f5605754cc80"; //根据自己后台的设置保持一致
var messageHandler = new Yespace.MessageHandler.CustomMessageHandler(Request.InputStream, postModel, 10);
messageHandler.DefaultMessageHandlerAsyncEvent = Senparc.Weixin.MessageHandlers.DefaultMessageHandlerAsyncEvent.SelfSynicMethod;//没有重写的异步方法将默认尝试调用同步方法中的代码(为了偷懒)
#region 设置消息去重
/* 如果需要添加消息去重功能,只需打开OmitRepeatedMessage功能,SDK会自动处理。
* 收到重复消息通常是因为微信服务器没有及时收到响应,会持续发送2-5条不等的相同内容的RequestMessage*/
messageHandler.OmitRepeatedMessage = true;//默认已经开启,此处仅作为演示,也可以设置为false在本次请求中停用此功能
#endregion
#region 记录 Request 日志
var logPath = Server.MapPath(string.Format("~/App_Data/MP/{0}/", DateTime.Now.ToString("yyyy-MM-dd")));
if (!Directory.Exists(logPath))
{
Directory.CreateDirectory(logPath);
}
//测试时可开启此记录,帮助跟踪数据,使用前请确保App_Data文件夹存在,且有读写权限。
messageHandler.RequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_{1}_{2}.txt", _getRandomFileName(),
messageHandler.RequestMessage.FromUserName,
messageHandler.RequestMessage.MsgType)));
if (messageHandler.UsingEcryptMessage)
{
messageHandler.EcryptRequestDocument.Save(Path.Combine(logPath, string.Format("{0}_Request_Ecrypt_{1}_{2}.txt", _getRandomFileName(),
messageHandler.RequestMessage.FromUserName,
messageHandler.RequestMessage.MsgType)));
}
#endregion
await messageHandler.ExecuteAsync(); //执行微信处理过程
#region 记录 Response 日志
//测试时可开启,帮助跟踪数据
//if (messageHandler.ResponseDocument == null)
//{
// throw new Exception(messageHandler.RequestDocument.ToString());
//}
if (messageHandler.ResponseDocument != null)
{
messageHandler.ResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_{1}_{2}.txt", _getRandomFileName(),
messageHandler.ResponseMessage.ToUserName,
messageHandler.ResponseMessage.MsgType)));
}
if (messageHandler.UsingEcryptMessage && messageHandler.FinalResponseDocument != null)
{
//记录加密后的响应信息
messageHandler.FinalResponseDocument.Save(Path.Combine(logPath, string.Format("{0}_Response_Final_{1}_{2}.txt", _getRandomFileName(),
messageHandler.ResponseMessage.ToUserName,
messageHandler.ResponseMessage.MsgType)));
}
#endregion
//MessageHandler = messageHandler;//开放出MessageHandler是为了做单元测试,实际使用过程中不需要
return new FixWeixinBugWeixinResult(messageHandler);
}
/// <summary>
/// 为测试并发性能而建
/// </summary>
/// <returns></returns>
public Task<ActionResult> ForTest()
{
//异步并发测试(提供给单元测试使用)
return Task.Factory.StartNew<ActionResult>(() =>
{
DateTime begin = DateTime.Now;
int t1, t2, t3;
System.Threading.ThreadPool.GetAvailableThreads(out t1, out t3);
System.Threading.ThreadPool.GetMaxThreads(out t2, out t3);
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.1));
DateTime end = DateTime.Now;
var thread = System.Threading.Thread.CurrentThread;
var result = string.Format("TId:{0}\tApp:{1}\tBegin:{2:mm:ss,ffff}\tEnd:{3:mm:ss,ffff}\tTPool:{4}",
thread.ManagedThreadId,
HttpContext.ApplicationInstance.GetHashCode(),
begin,
end,
t2 - t1
);
return Content(result);
});
}
}
}