質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

2118閲覧

Webページ内部のリアルタイム更新を書きたい(Go言語、Ginパッケージ)

kamuycikap

総合スコア135

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2022/05/07 05:02

以下のやりたい事をGo言語のGinライブラリで実現したいのですが、書き方がわからず。
経験者もしくは書き方が閃く方のご教示を頂きたく。
作成コードの指針となる情報及び、私が見つけられていないURL等参考情報をお願い致します。

【やりたい事】
1.Go言語にてWebページを作成(Ginパッケージ)
2.Webページアプリ自身が、自身が配置されているディレクトリ以下に作成されているCSVファイルをポーリング
3.CSVファイルは常に更新されており、同様の更新内容をWebページの一部にリアルタイム表示
※CSSはBootstrapを採用

【わからない事】
定期的にWebページの内容を更新するためのGo言語Ginを利用した書き方がわからない

【試してみた事】
Gin公式サイトのExampleとGoogle検索結果のブログ記事
https://gin-gonic.com/docs/examples/html-rendering/
https://nunubuff.com/blog/golang-gin-tutorial/

【実現できたこと】
Bootstrapを利用し、TopWebページの表示を行えるところまでは実現。
TopWebページに、任意の文字列(変数)を1度だけ表示させる事に成功。

【試してみた事補足】
r := gin.Default()
の後、
r.Run()
を実施するまえに

go

1 2time.Sleep(3 * time.Second) // 3秒休む 3r.GET("/", func(c *gin.Context) { 4 c.HTML(200, "index.html", gin.H{ 5 "message": "Hello World ★何らかの異なる文字★", 6 })

をmain関数内部に、上から複数並べても、画面更新には至らず。
サーバー内に配置されたCSVファイルを、自身がポーリングして情報更新するため、REST APIのように別プログラムからURLを叩くような作りは想定していません。
そもそも、この考え方が間違っているのか?とも考え始めています。

【現在進行形で試している事】
CSVファイルから読み取ったデータをTableタグに入れてテンプレートに表示させる方法を模索。
CSVファイルのポーリングは、ゴルーチンで実現。
※データは取得できても、Webページ反映の書き方がわからず

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2022/05/07 05:19

サーバー上のファイルをクライアントが直接ポーリングするのは不可能なので、サーバー側で変更を監視して、WebSocket などで通知すればよいのでは。
kamuycikap

2022/05/07 05:33

あ・・・ サーバーとクライアントが同居しているようなアプリケーションを考えていたのですが、、。 そうではなくて、クライアントからのリクエストでCSVファイルの内容を返すようなサーバーを作り、同時に定期的にリクエストを投げるクライアントも作成するというイメージでしょうか? ■サーバー(Go言語によるサーバーアプリ) クライアントからの指示を常に待ち続ける(REST API等) 指示を受けたら、CSVファイルをReadし、内容をクライアントに応答させる ■クライアント(Go言語によるWebアプリ) サーバーに対し、定期的に要求を投げ続ける(5~10秒間隔)
nobonobo

2022/05/09 02:01

クライアントとはブラウザのことを指していますか? 「■クライアント(Go言語によるWebアプリ)」この書き方だとそうではないように見えます。 ブラウザ=JS/WASMしか動かないので「Go言語による」ものをブラウザで動かすにはかなりレアなやり方になってしまいます。GoでJS/WASMを作る方法をおたずねでしょうか?
kamuycikap

2022/05/09 04:16

「クライアントとはブラウザのことを指していますか?」 → はい。そのとおりです。 質問を投稿した当初、ブラウザ側の何かを開発する想定ではありませんでした。 ブラウザに、Goで作ったサーバーアプリのIPアドレス入力してWebページを開けば、定期的に画面内容が更新されれば良いくらいの発想でした。 でしたので、クライアント側に何か知らの仕組みが必要だとは思っていなかったのです。 Ginのサンプルプログラムをアレコレ試しているのですが、画面更新を実現する為に、同じサーバーURLを繰り返し何度も叩く必要があると理解しはじめたところです。
kamuycikap

2022/05/09 04:24

Goサーバー側で ・CSVファイルの情報を収集(ゴルーチンA) → チャネルD ・画面表示機能(ゴルーチンB) ← チャネルD を動かしておき、クライアント(Webブラウザ)で、画面表示機能を呼び出すURLを叩けばOK。 を実現できないかと考えた次第です。
nobonobo

2022/05/09 11:39 編集

「画面表示機能(ゴルーチンB)」という記述から画面表示機能をGoが受け持つというのはどういうものを想定しているのかがなかなか伝わってきません・・・。Ginはサーバーであり、コンテンツやデータをクライアントに返すだけであって、実際に画面表示をしているのはブラウザです。表示に関して一般的なGoの実装が介入できるところはありません(GoをJS化したりWASM化することで介入する方法はありますが一般的ではありません)。 なので、Goのチャネルがつなげられるのは同じホストの同じプロセス内のgoroutine間だけですので、 異なる処理系(GoとJS)間の通信をチャネルのように行うには何らかのプロトコルに則った別の仕掛けを利用するしかありません。その例が「WebSockets」と「Server Sent Events」です。 従来のHTTPではクライアントからの能動的な要求に対しサーバーが受動的に応答を返すという手順しかありません。 つまり、「CSVファイル監視ー>変更検出ー>サーバーからクライアントにイベントを通知ー>画面を更新」という流れをまともに作るためには、WSやSSEなどでサーバーから能動的にクライアントにメッセージを渡す仕掛けが必要となり、それらをハンドリングする実装がサーバー、クライアントともに必要です。 そしてクライアント側でその実装を行うにはJS用に用意されたWSやSSEのAPIを利用する以外の実装方法はありません。
guest

回答1

0

ベストアンサー

この手の処理を実現するには一般的にフロントエンドのノウハウが必要です。
フロントエンドのノウハウさえあれば、GoもGinも極めてシンプルな実装で実現できます。

Gin側は静的ファイルのサーブさえしていればよく(Ginすら特に必要なく)

Webサーバー実装

go:main.go

1package main 2 3import ( 4 "github.com/gin-gonic/gin" 5) 6 7func main() { 8 r := gin.Default() 9 r.Static("/", "./assets") 10 r.Run() 11}

./assetsフォルダーの下に以下のindex.htmlとdata.csvがおいてあればよいわけです。

index.html例

html:index.html

1<h1>hello world!</h1> 2<table id="data"></table> 3<script> 4 async function update() { 5 let res = await fetch("data.csv"); 6 let csv = await res.text(); 7 let lines = csv.split("\n"); 8 let table = document.createElement("table"); 9 for (let i = 0; i < lines.length; i++) { 10 let line = lines[i]; 11 let cells = line.split(","); 12 let tr = document.createElement("tr"); 13 for (let j = 0; j < cells.length; j++) { 14 let td = document.createElement("td"); 15 td.innerHTML = cells[j]; 16 tr.appendChild(td); 17 } 18 table.appendChild(tr); 19 } 20 document.getElementById("data").replaceChildren(table); 21 } 22 update(); 23 setInterval(update, 5000); 24</script>

### CSVファイル例

csv:data.csv

1hoge1, moge1, 21, address1 2hoge2, moge2, 22, address2 3hoge2, moge2, 22, address2

表示例

Webサーバー実装を実行して、ブラウザでhttp://localhost:8080/を開いてみましょう。以下のような表示になると思います。
イメージ説明

この状態で./assets/data.csvを編集してみましょう。5秒以内に反映されることがわかると思います。

まとめ

  • JSを学びましょう
  • index.htmlのscriptタグ内のコードが読み書きできるようになれば簡単に実現できます

投稿2022/05/09 04:27

編集2022/05/09 05:27
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobonobo

2022/05/09 05:32

index.htmlをGinテンプレートを使ってCSVを読み込んだ結果を埋め込んで返すようにして置き、ブラウザ側で何秒か置きにページリロードを掛けるというやり方でもOKです。
nobonobo

2022/05/09 05:36

ここから先リアルタイム性を高くしたい場合には「WebSockets」や「Server Sent Events」といった技術が必要になってきます。(実装例のままインターバルを小さくしていくと、一般公開したときサーバー負荷がひどく高くなってしまうからです。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問