做爲開發者,咱們須要面對的主要有兩個對象:微信服務器和應用程序(網站)服務器。html
當微信用戶向你的公衆平臺發送一條消息,實際上這條消息首先發送到微信服務器,由微信服務器向網站服務器發起另一個請求,網站服務器返回這個請求的結果,再由微信服務器發送到微信客戶端。node
整個消息通信流程以下圖:服務器
上述5個步驟中,做爲開發者咱們主要精力都集中在步驟3上,這個步驟主實際上要有3項任務:微信
- 接收來自2的XML信息
- 服務器內部邏輯執行
- 組織並返回用於4的XML信息
上述三項任務我會在後面作詳細說明,並提供一整套簡單、高效的處理方法。學習
2、XML通信格式
用戶使用微信客戶端發送的不一樣類型的消息,網站服務器會收到不一樣格式的數據(文字、語音、圖片等等),數據格式暫時只有XML一種。測試
做爲學習,我以爲只要熟練掌握最簡單的文字類型就能夠了,其餘的格式都是大同小異。且在後面的說明中你會發現,Senparc.Weixin.MP.dll能夠幫助咱們徹底忽略這些繁瑣的格式和定義。網站
一個簡單的文字請求XML(RequestMessage)內容以下:spa
- <xml>
- <ToUserName><![CDATA[gh_a96a4a619366]]></ToUserName>
- <FromUserName><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></FromUserName>
- <CreateTime>1357986928</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[TNT2]]></Content>
- <MsgId>5832509444155992350</MsgId>
- </xml>
對應節點的官方說明以下:.net
參數 |
描述 |
ToUserName |
開發者微信號 |
FromUserName |
發送方賬號(一個OpenID) |
CreateTime |
消息建立時間 (整型) |
MsgType |
text |
Content |
文本消息內容 |
MsgId |
消息id,64位整型 |
一個簡單的文字返回XML(ResponseMessage)內容以下:xml
- <xml>
- <ToUserName><![CDATA[olPjZjsXuQPJoV0HlruZkNzKc91E]]></ToUserName>
- <FromUserName><![CDATA[gh_a96a4a619366]]></FromUserName>
- <CreateTime>12345678</CreateTime>
- <MsgType><![CDATA[text]]></MsgType>
- <Content><![CDATA[content]]></Content>
- <FuncFlag>0</FuncFlag>
- </xml>
對應節點的官方說明以下:
參數 |
描述 |
ToUserName |
接收方賬號(收到的OpenID) |
FromUserName |
開發者微信號 |
CreateTime |
消息建立時間 |
MsgType |
text |
Content |
回覆的消息內容,長度不超過2048字節 |
FuncFlag |
位0x0001被標誌時,星標剛收到的消息。 |
3、一些須要注意和容易被忽視的問題:
- 每條XML信息都有大小限制,如文本信息,建議Content內容不要超過600字。
- 上圖中,步驟2開始以後,微信服務器有一個等待時間:5秒,若是在這個時間內沒有進行到步驟4,那麼這個請求將會被關閉(包括數據傳輸的時間)。也就是說若是超過期間,即便網站服務器返回了數據,客戶端也沒法收到回覆。
- 在文本消息中,是容許添加<a>標籤來放置鏈接的,可是有許多朋友測試以後發現iOS沒問題,Android上連接沒法點擊,其實緣由是(至少目前爲止):Android的微信客戶端對<a>標籤格式的斷定比較嚴格,請嚴格按照這個格式書寫:<a href="http://xxxx">內容</a>,href後不要使用單引號,也不要添加其餘屬性。
- 上面XML節點中的FromUserName即微信用戶的OpenId,對於同一個公衆帳號,這個OpenId的前6位是一致的,而且在整個公衆平臺的記錄中也是惟一的。也就是說同一個用戶關注了兩個不一樣的公衆帳號,他會有兩個不一樣的OpenId。
- CreateTime使用的是Unix時間,所以若是使用C#的話,須要作一個轉換。
- 儘可能保持官方API中XML節點的順序,之前微信服務器是使用節點位置的方式讀取信息的(node[0]),而非節點名稱,如今這個問題彷佛有好轉,不過仍是要當心(¥…………&%&……)。
- 因爲這種特殊的通信方式,(至少目前爲止)全部請求必須從客戶端先發起,不要期望光使用API或SDK能夠實現由網站服務器主動推送消息到客戶端(固然其餘辦法仍是有的,好比模擬登錄)。