Go、HTMX、Web Socket を使用したシンプルなリアルタイム システム モニターの構築

Barbara Streisand
リリース: 2024-11-21 11:37:15
オリジナル
550 人が閲覧しました

私は Go、HTMX、Tailwwindcss を使用する楽しいプロジェクトを見つけて、最終的に Web ソケットの力を使ったシンプルなリアルタイム Web ベースのシステム モニターを構築しました。結果は次のとおりです。

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

システム情報、メモリ、ディスク、CPU、実行中のプロセスが表示され、5 秒ごとに自動的に更新されます。

この投稿ではコードを少し詳しく説明します。

スタック

  • 1.23.2 に進みます
  • HTML
  • 追い風
  • ゴプスティル
  • ウェブソケット
  • 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 ハンドラーとして http.ServeMux が含まれており、後で Web ソケット ブロードキャストを行うためのサブスクライバーも含まれています。加入者はデータ更新用のメッセージ チャネルを持っているだけです。

単一の HTML ファイルを提供するだけでよいため、ページを表示するための URL と、Web ソケット接続用の URL が 1 つ必要です。

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 ソケット接続とサブスクライバー

エンドポイント /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()
        }
    }
}

ログイン後にコピー

自動更新

システム情報データの自動更新は go ルーチンによって処理されます。 Web ソケット経由で送信される HTML 応答を構築し、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>
ログイン後にコピー

CDN を使用するための HTMX と 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ソケットに接続するにはどうすればよいですか?

システム モニター ページは Web ソケットですべてのデータを受信することが想定されているため、メインの div コンテナーから設定できます。 Web ソケット拡張機能を使用するように HTMX に指示するには hx-ext=”ws” を指定し、Web ソケットに /ws URL 経由で接続するように指示するには ws-connect=”/ws” を指定します。




<h2>
  
  
  完全なコード
</h2>

<p>コードの完全版は https://github.com/didikz/gosysmon-web です。独自のバージョンを試してみることもできます。</p>

<p>コーディングを楽しんでください!</p>


          
ログイン後にコピー

以上がGo、HTMX、Web Socket を使用したシンプルなリアルタイム システム モニターの構築の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート