前言
上一篇《1個類,2個方法,3句代碼,完成微信公眾號開發的極簡流程》介紹了一個只用很少量的代碼,就能實現消息回復和高級接口兩大經典微信應用。
文末,我們對開發完的程序進行了測試,並且拋出了一個問題:
我沒有服務器,也沒有注冊微信公眾號,如何在本地完成以上所有上線操作和測試呢?
本文就將帶你親自實現內網穿透,在本地環境下,模擬正式環境服務器對接微信,並進行調試。本文同樣適用於微信小程序、企業微信、QQ小程序等其他需要穿透到內網測試的場景。
在上一篇已經完成的基礎上,本篇主要內容邊看邊練習的時間約為 15 分鍾,進階內容約為 10 分鍾,源碼已經開放:
- GitHub:https://github.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample
- Gitee:https://gitee.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample
內容導航
背景
微信公眾號的服務原理如下圖所示:
來源:http://book.weixin.senparc.com/BookHelper#c-40
微信用戶發送給公眾號的信息,經微信服務器中轉處理成約定的格式后,轉發給開發者的服務器(網站),然后再將網站返回的指定格式的消息經過處理轉發給微信用戶。
這個過程中,對於正式的公眾號來說,“網站”必須配有經過 ICP 備案的域名,也就是說必須部署在正規機房或特殊地點,而不能是一般的家中或公司中。
這就帶來了篇頭所說的問題,如果我現在手里沒有服務器、沒有域名,或者即使有了,我也不想每次都部署,而是在本地進行運行和調試,那應該怎么做呢?
這就牽出了一個技術:內網穿透。
關於內網穿透的方案有很多,這里不一一列舉,僅介紹其中我覺得最簡便的方案之一:ngrok —— 只需一行命令即可完成整個穿透過程。
安裝 ngrok
ngrok 的官網:https://ngrok.com/
點擊 Download 即可下載,下載后解壓安裝到本地目錄,如 D:\ngrok,文件夾下面只有一個文件,非常清爽:
使用 ngrok 進行內網穿透
按照《1個類,2個方法,3句代碼,完成微信公眾號開發的極簡流程》中的流程,運行項目(一定要確保正在運行),在運行狀態中找到對應的 Url 地址:
使用命令行進入 D:\ngrok 目錄,輸入命令:ngrok http http://localhost:45638
注意:這里使用的是 http,而不是 https,至於為什么現在只能使用 http,下文會解釋。
運行之后,即可啟動 ngrok 的代理程序:
此時我們獲得了1個隨機的公網域名(每次啟動 ngrok 都會變),同時支持 http 和 https 訪問(映射到的都是內網的 http):
- http://bb2042af5b6a.ngrok.io
- https://bb2042af5b6a.ngrok.io
我們訪問一下這兩個域名,發現都返回了錯誤:
如果看到 400 Bad Request 的錯誤頁面,不用着急,按 Ctrl+C 退出程序,修改一下命令為:
D:\ngrok>ngrok http http://localhost:45638 --host-header="localhost:45638"
(如果端口好不同,對應修改)
重新運行后將獲得新的隨機域名:
訪問 https://704728067974.ngrok.io 臨時域名,此時已經又看到了熟悉的畫面:
太棒了!得到這個“小確信”的頁面后,就可以放心進行配置了。
配置測試號
由於正式的公眾號必須要 ICP 備案的國內域名才可以對接,顯然這個域名並不滿足條件,但是作為測試,我們可以使用測試賬號,為了方便大家查找入口,我們在線上Demo(https://sdk.weixin.senparc.com/)提供了快捷入口:
點擊進入后,即可用每個人的個人微信掃碼,“領用”到一個測試號(每個個人微信唯一):
記錄下【測試號信息】中的 appID 和 appsecret 參數,分別填寫到 appsetting.json 中的 “WeixinAppId” 和 “WeixinAppSecret” 值中(如果不需要使用高級接口,只處理消息回復的話,則不需要用到這兩個參數,可以忽略)。
同時將 appsettings.json 中的 "Token" 自定義一個更加復雜的值(3-32個字符),稍后會用到。
設置 appsetting.json
隨后點擊頁面【接口配置信息】后面的【修改】按鈕,輸入剛才設置的 Token,以及 ngrok 正在運行中的消息頁面地址(注意:必須是帶有消息接口完整路徑的地址),如本例中的:
設置 URL & Token | https://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,則需要到官網(https://ngrok.com/)注冊一個賬號。
這里有一個小提示:常規注冊過程需要使用到 Google 的 reCAPTCHA 驗證,對於“原始”狀態訪問互聯網的同學可能因此無法完成注冊過程,此處建議直接使用 GitHub 等外部賬號授權登錄,可以跳過這個尷尬的異步。
注冊完成后進入后台(https://dashboard.ngrok.com/get-started/setup)就可以找到一個 authtoken:
復制這一段令牌信息,打開桌面命令行,進入 ngrok 目錄,輸入:
D:\ngrok>ngrok authtoken 6vwCLn**********************
儲存 authtoken
ngrok 會把這個令牌自動存入到本地文件中,以后再調用 ngrok 的命令,就是“持證上崗”啦!
下面我們修改一下之前的 http 綁定為 https 綁定:
D:\ngrok>ngrok http https://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句代碼,完成微信公眾號開發的極簡流程