安卓项目之微信公众好---初体验
由于俱樂部的需要,最近開始著手微信公眾平臺的開發,之前一直都有使用,不過只是簡單的基于關鍵字的自動回復功能而沒有使用開發者模式。這次開始使用開發者模式,注意【開發者模式】和【自動回復功能】不能共存,也就是說一個處于啟用狀態,另一個只能處于停用狀態。其實微信公眾平臺的開發和網頁編寫時一樣的,只不過顯示在微信客戶端中而不是瀏覽器網頁界面。
?
一、開發者原理
二、啟用開發者模式
三、一個簡單的例子
?
一、????????開發者原理
要想更好的開發微信公眾平臺,理解一下原理還是很重要的,如果出現了錯誤這樣也就更容易調試。
?
微信平臺有一個服務器A用于與手機微信客戶端通訊(接收和發送消息),如果啟用開發者模式,還需要一個服務器B(需要自己準備),服務器A接收客戶端發來的消息a,并將消息a發送給服務器B,在服務器B中對消息進行處理返回消息b(這里便是開發者主要要實現的功能)給服務器A,微信平臺的服務器A再將消息b發給客戶端,這就是大體的消息發送和回應的原理。
以上描述的是在已經成為開發者之后,公眾號的關注者發送消息時的情景。
?
在初次申請成為開發者時,你需要準備的是一個服務器(我使用的是SAE),然后需要在公眾號中配置一下,主要也就是告訴公眾號(處于服務器A中)你的服務器在哪里(服務器B的URL)以及其他信息。之后就需要一個初次驗證,也就是讓服務器A和服務器B相互熟悉熟悉,畢竟以后要一起工作啦。
開發模式成為開發者時的消息校驗原理
在開發者首次提交驗證申請時,微信服務器將發送GET請求到填寫的URL上,并且帶上四個參數(signature、timestamp、nonce、echostr),開發者通過對簽名(即signature)的效驗,來判斷此條消息的真實性。此后,每次開發者接收用戶消息的時候,微信也都會帶上前面三個參數(signature、timestamp、nonce)訪問開發者設置的URL。
| 參數 | 描述 |
| signature | 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 |
| timestamp | 時間戳 |
| nonce | 隨機數 |
| echostr | 隨機字符串 |
開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則接入生效,成為開發者成功,否則接入失敗。
加密/校驗流程如下:
1. 將token、timestamp、nonce三個參數進行字典序排序
2. 將三個參數字符串拼接成一個字符串進行sha1加密
3. 開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信啟用接口是由代碼中的checkSignature()函數來實現校驗的。
有點亂的話,也沒問題,之后再例子中還會再說。
?
二、????????啟用開發者模式
上面說的是開發者的初次驗證和普通消息接收發送的原理,當然這都是在啟用開發者模式之后才管用的,所以現在我們就來說一說如何啟用開發者模式和相關的一些配置。
進入微信公眾平臺公眾號的首頁,選擇開發者中心,點擊進入:
?
這里我的已經配置和啟用完畢了,界面如上圖所示。你首先做的是點擊配置,在配置中你需要填寫四個內容:URL、Token、EncodingAESKey、消息加解密方式,URL就是你的服務器的URL,Token就是一個令牌,填寫什么都可以不過一定要記住,因為之后要使用,EncodingAESKey選擇隨機生成即可,加密方式我選擇了明文模式,填好了這四項,確定之后可能失敗,因為我們忘記了一件事情,就是在自己的服務器中要編寫初次驗證的代碼(這個在例子中會有體現),然后確定配置即可。再選擇啟用即可啟用開發者模式。
?
三、????????一個簡單的例子
先把測試代碼拋出,然后進行講解:
1 <?php2 /**3 * wechat php test4 * update time: 201501145 */6 7 //define your token8 define("TOKEN", "weixin");9 $wechatObj = new wechatCallbackapiTest(); 10 if (isset($_GET['echostr'])) { 11 $wechatObj->valid(); 12 }else{ 13 $wechatObj->responseMsg(); 14 } 15 16 class wechatCallbackapiTest 17 { 18 public function valid() 19 { 20 $echoStr = $_GET["echostr"]; 21 22 //valid signature , option 23 if($this->checkSignature()){ 24 echo $echoStr; 25 exit; 26 } 27 } 28 29 public function responseMsg() 30 { 31 //get post data, May be due to the different environments 32 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 33 34 //extract post data 35 if (!empty($postStr)){ 36 37 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 38 $fromUsername = $postObj->FromUserName; 39 $toUsername = $postObj->ToUserName; 40 $keyword = trim($postObj->Content); 41 $time = time(); 42 $textTpl = "<xml> 43 <ToUserName><![CDATA[%s]]></ToUserName> 44 <FromUserName><![CDATA[%s]]></FromUserName> 45 <CreateTime>%s</CreateTime> 46 <MsgType><![CDATA[%s]]></MsgType> 47 <Content><![CDATA[%s]]></Content> 48 <FuncFlag>0</FuncFlag> 49 </xml>"; 50 if(!empty( $keyword )) 51 { 52 $msgType = "text"; 53 $contentStr = "Welcome to wechat world!"; 54 $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 55 echo $resultStr; 56 }else{ 57 echo "Input something..."; 58 } 59 60 }else { 61 echo ""; 62 exit; 63 } 64 } 65 66 private function checkSignature() 67 { 68 $signature = $_GET["signature"]; 69 $timestamp = $_GET["timestamp"]; 70 $nonce = $_GET["nonce"]; 71 $token = TOKEN; 72 $tmpArr = array($token, $timestamp, $nonce); 73 sort($tmpArr, SORT_STRING); 74 $tmpStr = implode( $tmpArr ); 75 $tmpStr = sha1( $tmpStr ); 76 77 if( $tmpStr == $signature ){ 78 return true; 79 }else{ 80 return false; 81 } 82 } 83 } 84 85 ?>?我之前定義的Token是“weixin”所以在代碼中也要定義相應的Token,有了之前的原理說明我們知道,如果是在開發者首次提交驗證申請時,微信服務器將發送GET請求到填寫的URL上,并且帶上四個參數(signature、timestamp、nonce、echostr),開發者通過對簽名(即signature)的效驗,來判斷此條消息的真實性。我們通過GET中是否含echostr來判斷是不是首次提交驗證申請,如果是,我們調用$wechatObj->valid()來驗證消息的真實性,驗證的方法在前面已經提到過,具體的代碼在checkSignature()中。
如果消息并不是提交驗證申請,那么,我們調用$wechatObj->responseMsg()來回應用戶發送的文本消息,回應的文本是“Welcome to wechat world!”。
下面簡要的說一下responseMsg()這個函數,它主要功能是用戶發送非空的文本,返回給用戶一個文本“Welcome to wechat world!”:
1. 獲取post數據,存入$postStr中;
2. 如果非空,解析$postStr,存入對象$postObj中;
3. 通過$postObj獲取$fromUsername(發送方)、$toUsername(接收方)、$keyword(關鍵字)、$time(時間);
說到這里,不得不提一下微信端的服務器A和我們自己的服務器B之間發送的消息是怎樣的,絕不僅僅是用戶在客戶端發送的字符串,而是XML數據包的格式,下面是一個例子:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><FuncFlag>0</FuncFlag> </xml>標簽依次記錄接收方、發送方、創建時間、消息類型、消息內容。無論是A發送給B,還是B發送給A都是以此格式發送,當B準備好數據發送給A時,B的發送方就是之前的接收方,接收方就是之前的發送方,時間不變,類型也是text,內容成為“Welcome to wechat world!”,對應的代碼就是:
1 $fromUsername = $postObj->FromUserName;2 $toUsername = $postObj->ToUserName;3 $keyword = trim($postObj->Content);4 $time = time();5 $textTpl = "<xml>6 <ToUserName><![CDATA[%s]]></ToUserName>7 <FromUserName><![CDATA[%s]]></FromUserName>8 <CreateTime>%s</CreateTime>9 <MsgType><![CDATA[%s]]></MsgType> 10 <Content><![CDATA[%s]]></Content> 11 <FuncFlag>0</FuncFlag> 12 </xml>"; 13 if(!empty( $keyword )) 14 { 15 $msgType = "text"; 16 $contentStr = "Welcome to wechat world!"; 17 $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 18 echo $resultStr; 19 }else{ 20 echo "Input something..."; 21 }xml格式的信息就好比填空題試卷,A填完之后發給B,B修改填空題的答案之后再發給A,開發者要做的就是處理接受的數據得到新的數據,并把新的數據填到試卷上。
?
代碼寫完之后發布在服務器B上,然后配置好微信公眾平臺,使得微信平臺服務器A和服務器B相互連接。啟用開發者模式,客戶端發送任何文本消息就可以接收到“Welcome to wechat world!”的信息啦。其他形式的消息也是如此,只不過更改一下XML的格式即可。
http://www.cnblogs.com/jtianwen2014/p/4223606.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的安卓项目之微信公众好---初体验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 轻松搞定个人虚拟桌面部署之4-配置远程访
- 下一篇: AX2012 referencegrou