在開發環境內網穿透測試微信公眾號
- 2021 年 5 月 15 日
- 筆記
- .NET Core, Asp.Net, ASP.NET MVC
前言
上一篇《1個類,2個方法,3句代碼,完成微信公眾號開發的極簡流程》介紹了一個只用很少量的代碼,就能實現消息回復和高級接口兩大經典微信應用。
文末,我們對開發完的程序進行了測試,並且拋出了一個問題:
我沒有服務器,也沒有註冊微信公眾號,如何在本地完成以上所有上線操作和測試呢?
本文就將帶你親自實現內網穿透,在本地環境下,模擬正式環境服務器對接微信,並進行調試。
在上一篇已經完成的基礎上,本篇主要內容邊看邊練習的時間約為 15 分鐘,進階內容約為 10 分鐘,源碼已經開放:
- GitHub://github.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample
- Gitee://gitee.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample
內容導航
背景
微信公眾號的服務原理如下圖所示:
來源://book.weixin.senparc.com/BookHelper#c-40
微信用戶發送給公眾號的信息,經微信服務器中轉處理成約定的格式後,轉發給開發者的服務器(網站),然後再將網站返回的指定格式的消息經過處理轉發給微信用戶。
這個過程中,對於正式的公眾號來說,「網站」必須配有經過 ICP 備案的域名,也就是說必須部署在正規機房或特殊地點,而不能是一般的家中或公司中。
這就帶來了篇頭所說的問題,如果我現在手裡沒有服務器、沒有域名,或者即使有了,我也不想每次都部署,而是在本地進行運行和調試,那應該怎麼做呢?
這就牽出了一個技術:內網穿透。
關於內網穿透的方案有很多,這裡不一一列舉,僅介紹其中我覺得最簡便的方案之一:ngrok —— 只需一行命令即可完成整個穿透過程。
安裝 ngrok
ngrok 的官網://ngrok.com/
點擊 Download 即可下載,下載後解壓安裝到本地目錄,如 D:\ngrok,文件夾下面只有一個文件,非常清爽:
使用 ngrok 進行內網穿透
按照《1個類,2個方法,3句代碼,完成微信公眾號開發的極簡流程》中的流程,運行項目(一定要確保正在運行),在運行狀態中找到對應的 Url 地址:
使用命令行進入 D:\ngrok 目錄,輸入命令:ngrok http //localhost:45638
注意:這裡使用的是 http,而不是 https,至於為什麼現在只能使用 http,下文會解釋。
運行之後,即可啟動 ngrok 的代理程序:
此時我們獲得了兩隨機的公網域名(每次啟動 ngrok 都會變):
- //bb2042af5b6a.ngrok.io
- //bb2042af5b6a.ngrok.io
我們訪問一下這兩個域名,發現都返回了錯誤:
如果看到 400 Bad Request 的錯誤頁面,不用着急,按 Ctrl+C 退出程序,修改一下命令為:
D:\ngrok>ngrok http //localhost:45638 -host-header=”localhost:45638″
(如果端口好不同,對應修改)
重新運行後將獲得新的隨機域名:
訪問 //704728067974.ngrok.io 臨時域名,此時已經又看到了熟悉的畫面:
太棒了!得到這個「小確信」的頁面後,就可以放心進行配置了。
配置測試號
由於正式的公眾號必須要 ICP 備案的國內域名才可以對接,顯然這個域名並不滿足條件,但是作為測試,我們可以使用測試賬號,為了方便大家查找入口,我們在線上Demo(//sdk.weixin.senparc.com/)提供了快捷入口:
點擊進入後,即可用每個人的個人微信掃碼,「領用」到一個測試號(每個個人微信唯一):
記錄下【測試號信息】中的 appID 和 appsecret 參數,分別填寫到 appsetting.json 中的 「WeixinAppId」 和 「WeixinAppSecret」 值中(如果不需要使用高級接口,只處理消息回復的話,則不需要用到這兩個參數,可以忽略)。
同時將 appsettings.json 中的 “Token” 自定義一個更加複雜的值(3-32個字符),稍後會用到。
設置 appsetting.json
隨後點擊頁面【接口配置信息】後面的【修改】按鈕,輸入剛才設置的 Token,以及 ngrok 正在運行中的消息頁面地址(注意:必須是帶有消息接口完整路徑的地址),如本例中的:
設置 URL & Token | //704728067974.ngrok.io/WeixinAsync
注意:修改 appsetting.json 之後需要重啟站點(此時千萬不要重啟 ngrok,否則需要重新到後台設置 URL)
重啟後,點擊【提交】按鈕,即可看到設置成功的界面:
設置成功
聯機測試
將頁面向下拉,可以看到個人測試號的二維碼,用微信掃一掃,並關注(最多可以添加100個關注者)
掃碼註冊
關注之後,即可在手機上看到這個測試公眾號的界面,每次發送消息後,即可看到兩條回復,第一條是通過高級接口(AppId + Secret)發送的,你可以嘗試一下一口氣多發幾條,第二條是正式的回復消息,每次最多只能收到1條,因為程序中是先調用了高級接口(客服消息),然後返回回複信息,因此客戶端先收到的就是客服消息。
如果我們不發送文字信息,而是一個圖片信息,系統會發現我們並沒有重寫圖片處理過程,因此返回的是默認消息。
消息回復成功,穿透到內網服務器
調試
穿透到內網之後,可以非常方便地進行調試,我們使用調試模式打開站點,並且在文字回複信息返回之前設置一個斷點:
開始調試
當我們在客戶端發送一條文字消息之後,即可在調試模式下看到收到的消息,以及即將回復的信息。其中客服消息應該在斷點之前就運行了,因此微信客戶端立即就能收到。
但因為調試時間超過了 5 秒鐘,超過了微信服務器等待的時間,因此客戶端收到了「該公眾號提供的服務出現故障」的提示,此時,我們超時回復的消息將被忽略。
發送消息
下面我們再試一次,在5秒內快速修改返回內容:
成功調試並修改信息
這一次,前面 2 個步驟和之前是一致的,我們使用【即使窗口】輸入命令修改了 responseMessage.Content 的值,然後讓程序繼續運行,返回屬性值後的 responseMessage 對象,最後在手機端收到了被修改的回複信息。
查看日誌
Senparc.Weixin SDK 在默認設置下,會記錄所有的消息和接口調用信息。
消息發送和返回的日誌,可以在 /App_Data/WeChat_OfficialAccount 目錄下看到已經按照日期分類的公眾號消息日誌,以上述經過調試的消息為例:
一組 Request(請求)和 Response(響應)消息日誌
高級接口的調用信息默認存放在 /App_Data/SenparcTraceLog 目錄下,每天的日誌放在一個 .log 文件中:
高級接口的調用及傳送信息可以完全透明地看到
進階
1. 如何使用 ngrok 映射到內部 https 協議的網址上?
ngrok 默認情況下只支持映射內網的 http 協議,如果強行映射 https,則會提示錯誤,如果必須要映射內網 https,則需要到官網(//ngrok.com/)註冊一個賬號。
這裡有一個小提示:常規註冊過程需要使用到 Google 的 reCAPTCHA 驗證,對於「原始」狀態訪問互聯網的同學可能因此無法完成註冊過程,此處建議直接使用 GitHub 等外部賬號授權登錄,可以跳過這個尷尬的異步。
註冊完成後進入後台(//dashboard.ngrok.com/get-started/setup)就可以找到一個 authtoken:
複製這一段令牌信息,打開桌面命令行,進入 ngrok 目錄,輸入:
D:\ngrok>ngrok authtoken 6vwCLn**********************
儲存 authtoken
ngrok 會把這個令牌自動存入到本地文件中,以後再調用 ngrok 的命令,就是「持證上崗」啦!
下面我們修改一下之前的 http 綁定為 https 綁定:
D:\ngrok>ngrok http //localhost:44368 -host-header=”localhost:44368″
(注意:http 和 https 的端口是不一樣的)
運行後可以看到 ngrok 已經並訂到了內網的 https 協議地址上:
成功綁定 https
當然,也可以注意到外網域名已經發生了變化,如果需要繼續使用的話,需要再次到微信測試號後台綁定新域名。
如果需要自定義域名(固定),那麼需要購買對應的服務才能開通權限。即使每次都變化,如果電腦不重啟的話(親測系統休眠和睡眠都沒問題),可以一直使用,所以並不是特別大的痛點。
2. 如何關閉日誌?
Senparc.Weixin SDK 將日誌分為了消息日誌和調試日誌(包含接口調用信息),默認為開啟狀態,如果不希望記錄消息,可以通過如下方法關閉。
2.1 關閉消息日誌
修改之前寫入到 Startup.cs 中的中間件配置,添加禁用代碼:
1 //使用中間件註冊 MessageHandler,指定 CustomMessageHandler 為自定義處理方法 2 app.UseMessageHandlerForMp("/WeixinAsync", 3 (stream, postModel, maxRecordCount, serviceProvider) => new CustomMessageHandler(stream, postModel, maxRecordCount, serviceProvider), 4 options => 5 { 6 options.AccountSettingFunc = context => senparcWeixinSetting.Value; 7 options.EnableRequestLog = false; //關閉請求消息日誌 8 options.EnbleResponseLog = false; //關閉響應消息日誌 9 });
為了達到更好的靈活性,我們將 Request(請求)和 Resposne(響應)消息的日誌記錄狀態進行了分離的管理。
2.1 關閉接口日誌
接口日誌必須在調試狀態下開啟,默認為開啟狀態,如果需要禁用,可以在執行完 app.UseSenparcGlobal() 方法後的任意位置調用:
1 Senparc.CO2NET.Config.IsDebug = false; //關閉全局調試狀態,不記錄日誌
添加以下 3 行代碼將全面禁用調試日誌(包括接口調用日誌)以及消息請求/響應日誌:
特別說明:本文所提供的「內網穿透」技術是一項常見的輔助信息調試的技術,僅供用於本項目測試使用,請勿用於違規用途!
更多微信開發教程:
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(一):微信公眾平台註冊
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二):成為開發者
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(三):微信公眾平台開發驗證
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(四):Hello World
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(五):使用Senparc.Weixin.MP SDK
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(六):了解MessageHandler
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(七):解決用戶上下文(Session)問題
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(八):通用接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(九):自定義菜單接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十):多客服接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十一):高級接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十二):OAuth2.0說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十三):地圖相關接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十四):請求消息去重
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十五):消息加密
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十六):AccessToken自動管理機制
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十七):個性化菜單接口說明
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十八):Web代理功能
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(十九):MessageHandler 的未知類型消息處理
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十):使用菜單消息功能
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十一):在小程序中使用 WebSocket (.NET Core)
- Senparc.Weixin.MP SDK 微信公眾平台開發教程(二十二):如何安裝 Nuget(dll) 後使用項目源代碼調試
- 【番外篇】1個類,2個方法,3句代碼,完成微信公眾號開發的極簡流程