最近在研究SignalR這個微軟開發的通訊函式庫, 不知道的人可以參考微軟介紹: SignalR 簡介
簡單POC一下後感覺蠻好用的, 唯一可惜的地方是SignalR client端的程式語言支援的有點少, 官方支援的有JavaScript, .Net, Java, 非官方 or 實驗性質的則有C++跟Swift, 只考慮官方支援語言的話就只能寫.net或JAVA的用戶端程式或網頁上使用了。
既然學了一個新東西, 除了POC以外當然會想做些實際應用了, 目前想到自己需要用到SignalR的地方, 大概就是需要即時更新內容的網站, 以我自己網站來說, 大概就只有投資頁面的個股報價資訊, 要能即時更新股價資訊, 主要有兩個問題要處理:
1. 網頁前端需要即時跟後端取得股價資料, 如果用ajax polling不斷問後端server有無更新股價的方式會極度浪費資源, 應該要使用支援雙向傳輸的通訊方式(e.g. websocket), 只有在後端server發現真的有股價需要更新時, 在傳送最新的股價給前端。
2. 後端必須即時取得股價資料, 在通知前端更新, 而後端的股價的數據源要從哪取得就是個問題了, 總不可能一直polling打request到YAHOO財經的網站上要資料, 這樣太浪費電腦資源得到的數據也太慢, 還有被ban ip的可能。
上述兩個問題的話, 1可以直接用SignalR解決, 2的話可以參考我之前介紹的finnhub.io網站:
[美股API推薦] finnhub.io介紹 - 美股即時股價API
這網站提供50個個股報價的websocket訂閱, 而且取得的報價是以tick為單位, 可以即時取得個股的報價資訊。
既然前後端通訊跟數據源的問題都解決了, 再來就是實作面了! 最簡單的做法其實可以寫個service裝在自己的Azure VM上, 在用websocket接finnhub.io的個股報價, 之後就把得到的報價用SignalR轉給架好的SignalR hub, 前端網頁的部分一樣也是連到這台SignalR hub, 就可以即時得到股價資料了。
整個網站架構大致如下, SignalR的部分是這次新增:
3. 所有個股基本資料, 健康分析, 個股新聞跟SEC文件等等這些不需要即時而且要花費許多時間的工作透過Github Action每日觸發做批次工作, 然後在落地成檔案讓網站直接存取。
4. 個股即時報價部分就像上述提到的, 用websocket接finnhub.io數據源, 在透過SignalR傳到前端, 另外因為自己的VM規格已經夠爛了, 一直接finnhub.io怕會讓server loading更重, 畢竟finnhub.io傳過來的是tick資料, 所以這部分決定拉出來部屬到免費規格的Azure function, 讓Azure function去接finnhub.io數據源, 然後把Azure function接到的報價資料統整起來, 只送股價有更新的資料, 並且每1.5秒統一把所有有更新的個股報價一起送過來, 這樣可以省自己Azure VM的大量網路流量, 不用不斷去接tick單位等級的資料。
而再來就是websocket要是運氣好真的連上了, 只要有更新股價finnhub.io就會主動送報價資訊過來, 可是維持連線很久之後, 會有一定機率finnhub.io只會送{"type":"ping"}, 而只有重新斷線在連線後才會恢復正常。
2. 免費版Azure function掛載的Azure App Service會自動休眠:
沒有留言:
張貼留言