来源:自学PHP网 时间:2015-04-14 12:58 作者: 阅读:次
[导读] 这一节我们以获取用户普通消息和发送被动响应消息为例, 微信开发,需要设计到网络编程,涉及到一个概念,c 里叫做stream,字面意思是河,水流,我们日常称为流。...
这一节我们以“获取用户普通消息”和“发送被动响应消息”为例, 微信开发,需要设计到网络编程,涉及到一个概念,c#里叫做stream,字面意思是“河,水流”,我们日常称为“流”。 那什么是流呢? 流,简单来说就是建立在面向对象基础上的一种抽象的处理数据的工具。在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向。 换句话说,我们在与微信服务器发信息时,需要把数据写进流里。相反的,微信给我们发送信息,我们也用从流里取数据。 微软提供了StreamReader和StreamWriter类帮我们实现在流上读写字符串的功能。 详细见:点这里 如果你是新手,还看不懂上边可以跳过。。 让我们分析一下开发者与微信服务器的通信过程: 一.微信主动发送给开发者信息 二.开发者主动发送给微信信息
第一类过程: API主要是涉及到两种请求方式POST/GET 对于GET请求,目前发现只有网址介入的时候用到,参见:点这里 而对于POST请求,东西就比较多了。因为微信随时可能给发送我们信息,所以我们需要有一个接口随时监听。 以“接收用户普通消息”为例 这里假设我的网址接入地址是:www.xxxx.com/home/index 所以我要在homecontroller控制器底下新建一个index方法(注意类型是httppost)。
[HttpPost] public void Index() { }建好之后,接受服务器信息,并从流中读取数据。代码修改如下:
[HttpPost] public void Index() { //获取流 Stream s = System.Web.HttpContext.Current.Request.InputStream; //转换成Byte数组 byte[] b = new byte[s.Length]; //读取流 s.Read(b, 0, (int)s.Length); //转化成utf8编码 string postStr = Encoding.UTF8.GetString(b); //写入log(后边再讲) //WriteLog(); }是不是很简单?我们还可以将postStr写入日志,当有用户给公共主页发送信息时候,消息将会被保存,postStr数据格式如下:
普通文本消息为例 让我们继续操作,微信主动发来的主要是XML格式。我们尝试解析一下: 首先我们建一个实体,在Model底下添加类RequestXML,这里边规范了所有微信可能发来的用户消息
public class RequestXML { private string toUserName = ""; /// <summary> /// 消息接收方微信号,一般为公众平台账号微信号 /// </summary> public string ToUserName { get { return toUserName; } set { toUserName = value; } } private string fromUserName = ""; /// <summary> /// 消息发送方微信号 /// </summary> public string FromUserName { get { return fromUserName; } set { fromUserName = value; } } private string createTime = ""; /// <summary> /// 创建时间 /// </summary> public string CreateTime { get { return createTime; } set { createTime = value; } } private string msgType = ""; /// <summary> /// 信息类型 地理位置:location,文本消息:text,消息类型:image /// </summary> public string MsgType { get { return msgType; } set { msgType = value; } } private string content = ""; /// <summary> /// 信息内容 /// </summary> public string Content { get { return content; } set { content = value; } } private string location_X = ""; /// <summary> /// 地理位置纬度 /// </summary> public string Location_X { get { return location_X; } set { location_X = value; } } private string location_Y = ""; /// <summary> /// 地理位置经度 /// </summary> public string Location_Y { get { return location_Y; } set { location_Y = value; } } private string scale = ""; /// <summary> /// 地图缩放大小 /// </summary> public string Scale { get { return scale; } set { scale = value; } } private string label = ""; /// <summary> /// 地理位置信息 /// </summary> public string Label { get { return label; } set { label = value; } } private string picUrl = ""; /// <summary> /// 图片链接,开发者可以用HTTP GET获取 /// </summary> public string PicUrl { get { return picUrl; } set { picUrl = value; } } }
新建一个方法,参数为上边的postStr
public void Handle(string postStr) { //封装请求类 XmlDocument doc = new XmlDocument(); doc.LoadXml(postStr); XmlElement rootElement = doc.DocumentElement; //MsgType XmlNode MsgType = rootElement.SelectSingleNode("MsgType"); //接收的值--->接收消息类(也称为消息推送) RequestXML requestXML = new RequestXML(); requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText; requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText; requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText; requestXML.MsgType = MsgType.InnerText; //根据不同的类型进行不同的处理 switch (requestXML.MsgType) { case "text": //文本消息 requestXML.Content = rootElement.SelectSingleNode("Content").InnerText; break; case "image": //图片 requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText; break; case "location": //位置 requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText; requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText; requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText; requestXML.Label = rootElement.SelectSingleNode("Label").InnerText; break; case "link": //链接 break; case "event": //事件推送 支持V4.5+ break; } //消息回复 ResponseMsg(requestXML); }这时候会根据用户发来的消息,自动判断消息类型,再将信息存储在requestXML对象中。
拿到requestXML,我们需要根据不同类型回复
private void ResponseMsg(RequestXML requestXML) { try { string resxml = ""; //主要是调用数据库进行关键词匹配自动回复内容,可以根据自己的业务情况编写。 //1.通常有,没有匹配任何指令时,返回帮助信息 // AutoResponse mi = new AutoResponse(requestXML.Content, requestXML.FromUserName); switch (requestXML.MsgType) { case "text": //在这里执行一系列操作,从而实现自动回复内容. // WriteLog(requestXML.Content); resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA["+requestXML.Content+"]]></Content></xml>"; // resxml += mi.GetRePic(requestXML.FromUserName); break; case "location": break; case "image": //图文混合的消息 具体格式请见官方API“回复图文消息” break; } System.Web.HttpContext.Current.Response.Write(resxml); // WriteToDB(requestXML, resxml, mi.pid); } catch (Exception ex) { //WriteTxt("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); //wx_logs.MyInsert("异常:" + ex.Message + "Struck:" + ex.StackTrace.ToString()); } } OK,接受用户普通消息并回复功能完成。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com