[Golang] Build A Simple Web Service part.5 — Communicate with the ReactJS page

Jen-Hsuan Hsieh (Sean)
A Layman
Published in
7 min readJan 26, 2019

Polling and use web socket in Golang and React.

Copy right@A layman

Introduction

建立Route, 加入Middleware, 連接Database的學習,已經足夠讓我們以用Golang建立起簡單的API以提供服務。在學習連接到server的Windows service的能力後,web service可以接受外部的請求後在server執行一些工作並在任務完畢後更新到Database。

下一個問題則是:如何讓使用者即時地知道工作執行的狀態呢?

可以先從建立簡單的頁面開始(這部分可以參考此文); 接著參考本篇以了解如何讓前端頁面與提供API的web service溝通。

本篇文章將說明前端頁面主動呼叫API,以及透過Web socket讓後端主動推送訊息到前端的做法,以下將以ReactJS為前端的範例。

前端頁面主動呼叫API: AJAX and Short polling

在React上可以透過AxiosJQueryAJAX ,或是瀏覽器所提供的Fetch API完成AJAX call,不同瀏覽器的AJAX支援度如下:

Picture originated from https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

在React上正確的做法,是將Fetch寫在componentDidMount裡,componentDidMount的將會在component載入完畢後執行,Fetch是一個單向的做法,由前端發動request向service取得資料,後端被動地等待request。

如果要做短輪詢(Short polling), 讓瀏覽器定期檢查server是否有新的資料,可以將setTimeout寫到componentDidMount裡,這麼做簡單,但並非好作法, request數量很大而且消耗network throughput資源。

後端主動推送訊息: Web socket

準確地說,web socket不只是讓後端推送訊息,而是讓瀏覽器與伺服器互動的技術,屬於雙向溝通,讓瀏覽器不必定期傳送訊息至伺服器並接受事件驅動回應,進而節省server side的資源。

在web socket官網中說明了polling與web socket在不同數量的client時的network throughput,case A,case B,case C的client數分別是1000,10000,10000,可以看出在client數量很大時,polling會產生很多不必要的traffic。

在開發上做法上也很簡單,只要創建連結後client-server就能互相通訊,以下將說明在Golang及React上web socket的用法。

Web socket for Golang

這裏所使用的web socket套件是gorilla/websocket,安裝方式為在terminal中輸入以下指令:

go get github.com/gorilla/websocket

繼續修改專案,新增libs/webSocket.go:

Copy right@A layman

libs/webSocket.go的內容如下,透過websocket.Upgrader做web socket的設定,其中的checkOrigin是提供跨域校驗,可以讓他always return true以不做檢驗,這段程式碼是讓server在特定情形下推送訊息給client,因此這個function中應該是 個無限迴圈,以接收或傳送訊息。

如果需要讀取從client傳送來的訊息,可以用:

_, body, _ := c.ReadMessage()

接著修改routes/webService.go如下,先在InitRouter()的routes中增加一個新的controller, 接著新增對應的function,如此一來便替client提供了web socket的接口:

Web socket for React

在React可以使用react-websocket套件,安裝方式為在terminal中輸入:

npm install --save react-websocket

以下為範例,透過<Websocket url=‘ws://10.127.32.101:3000/socket.io’
onMessage={this.handleData.bind(this)},當接收到server所送來的訊息時將會觸發callback function而改變state,由於state被改變,React將會重新render頁面以達成即時更新的效果:

Summary

client-server間的溝通方式很多,這篇說明了polling與web socket的區別,以及在多數時刻我們應該盡量使用web socket以節省資源,此外也說明了React及Golang的web socket用法, 以及兩者間通訊的實作

謝謝你耐心地讀到Summary,我是Sean HS, 是位軟體工程師。
這片文章是我在研究過程時的筆記,若有錯誤之處,期待您的見解,與您交流討論。

--

--

Jen-Hsuan Hsieh (Sean)
A Layman

Frontend Developer🚀 Angular • React • Nest • Electron • Micro-frontend • Monorepo Architecture • https://daily-learning.herokuapp.com/