首頁 > 後端開發 > Golang > 主體

使用 Go、HTMX 和 Web Socket 建立簡單的即時系統監視器

Barbara Streisand
發布: 2024-11-21 11:37:15
原創
567 人瀏覽過

我正在尋找一個可以與 Go、HTMX 和 Tailwwindcss 配合使用的有趣項目,最終利用 Web 套接字的功能構建了一個簡單的基於 Web 的實時系統監視器。這是結果。

Building Simple Real-Time System Monitor using Go, HTMX, and Web Socket

它顯示系統資訊、記憶體、磁碟、CPU 和正在運行的進程,每 5 秒自動更新一次。

我將在這篇文章中對程式碼進行一些分解。

堆疊

  • 去1.23.2
  • Htmx
  • Tailwindcss
  • Gopsutil
  • Websocket
  • Htmx websocket 擴充

HTTP伺服器

type HttpServer struct {
    subscriberMessageBuffer int
    Mux                     http.ServeMux
    subscribersMutex        sync.Mutex
    subscribers             map[*subscriber]struct{}
}

type subscriber struct {
    msgs chan []byte
}
登入後複製

這非常簡單。 HttpServer 包含一個 http.ServeMux 作為 http 處理程序和稍後用於 Web 套接字廣播的訂閱者。訂閱者只是有用於資料更新的訊息通道。

由於它只需要提供單一 HTML 文件,因此它需要 URL 來顯示頁面,以及用於 Web 套接字連接的 URL。

func NewHttpServer() *HttpServer {
    s := &HttpServer{
        subscriberMessageBuffer: 10,
        subscribers:             make(map[*subscriber]struct{}),
    }

    s.Mux.Handle("/", http.FileServer(http.Dir("./views")))
    s.Mux.HandleFunc("/ws", s.subscribeHandler)
    return s
}
登入後複製

Web Socket 連線和訂閱者

端點 /ws 將處理 Web 套接字連線並管理訂閱者。首先,它將啟動一個新訂閱者並將其新增至 http 伺服器結構中的對應。鎖將用於防止競爭條件,因為我們稍後將使用 go 例程。

func (s *HttpServer) subscribeHandler(w http.ResponseWriter, r *http.Request) {
    err := s.subscribe(r.Context(), w, r)
    if err != nil {
        fmt.Println(err)
        return
    }
}

func (s *HttpServer) addSubscriber(subscriber *subscriber) {
    s.subscribersMutex.Lock()
    s.subscribers[subscriber] = struct{}{}
    s.subscribersMutex.Unlock()
    fmt.Println("subscriber added", subscriber)
}
登入後複製

Web 套接字開始接受連接,並透過循環,我們將偵測來自訂閱者的傳入通道訊息並將其寫入 Web 套接字。

func (s *HttpServer) subscribe(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
    var c *websocket.Conn
    subscriber := &subscriber{
        msgs: make(chan []byte, s.subscriberMessageBuffer),
    }

    s.addSubscriber(subscriber)

    c, err := websocket.Accept(w, r, nil)
    if err != nil {
        return err
    }

    defer c.CloseNow()

    ctx = c.CloseRead(ctx)
    for {
        select {
        case msg := <-subscriber.msgs:
            ctx, cancel := context.WithTimeout(ctx, time.Second)
            defer cancel()
            err := c.Write(ctx, websocket.MessageText, msg)
            if err != nil {
                return err
            }
        case <-ctx.Done():
            return ctx.Err()
        }
    }
}

登入後複製

自動更新

自動更新系統資訊資料由 goroutine 處理。我們將建立一個 html 回應,該回應將透過 Web 套接字發送,htmx 將處理 html 端的更新。

func main() {
    fmt.Println("Starting system monitor")
    s := server.NewHttpServer()

    go func(s *server.HttpServer) {
        for {
            hostStat, _ := host.Info()
            timestamp := time.Now().Format("2006-01-02 15:04:05")
            html := `
            <span hx-swap-oob="innerHTML:#data-timestamp">` + timestamp + `</span>
            <span hx-swap-oob="innerHTML:#system-hostname">` + hostStat.Hostname + `</span>
            <span hx-swap-oob="innerHTML:#system-os">` + hostStat.OS + `</span>
            `
            s.Broadcast([]byte(html))
            time.Sleep(time.Second * 5)
        }
    }(s)
    // ...
}
登入後複製

htmx 中的語法 hx-swap-oob="innerHTML:#data-timestamp" 告訴我們在 HTML 中交換 data-timestamp id 內的元件。所有交換機制對於其他系統資訊組件都是相同的。

所有可交換的 html 元件將透過 Broadcast(msg) 方法發送,稍後將每 5 秒通過通道發送一次。

func (s *HttpServer) Broadcast(msg []byte) {
    s.subscribersMutex.Lock()
    for subscriber := range s.subscribers {
        subscriber.msgs <- msg
    }
    s.subscribersMutex.Unlock()
}
登入後複製

HTMX 視圖

這是純 HTML 文件,對於 Tailwindcss 我簡單地使用了 CDN

<script src="https://cdn.tailwindcss.com"></script>
登入後複製

HTMX 和使用 CDN 的 Web 套接字擴充的想法相同。

<script src="https://unpkg.com/htmx.org@2.0.3" integrity="sha384-0895/pl2MU10Hqc6jd4RvrthNlDiE9U1tWmX7WRESftEDRosgxNsQG/Ze9YMRzHq" crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx-ext-ws@2.0.1/ws.js"></script>
登入後複製

如何連接網路套接字?

系統監視器頁面預計會透過 Web 套接字接收所有數據,以便我可以從主 div 容器中設定它。指定 hx-ext=”ws” 告訴 HTMX 使用 Web 套接字擴展,指定 ws-connect=”/ws” 告訴 Web 套接字透過 /ws URL 連線。




<h2>
  
  
  完整程式碼
</h2>

<p>這是程式碼的完整版本 https://github.com/didikz/gosysmon-web,您可能想嘗試自己的版本。 </p>

<p>編碼愉快! </p>


          
登入後複製

以上是使用 Go、HTMX 和 Web Socket 建立簡單的即時系統監視器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板