Golang中MVM的实现与应用
Golang中MVM的实现与应用 大家好下午好。 朋友们,请告诉我如何使用 html/template 来持续向 HTML 模板传输数据,例如计时器或已下载的数据量? 提前感谢您的帮助。
4 回复
您无法做到。模板只会被精确渲染一次。
如果您想在不触发手动请求的情况下动态更新一个值,您需要在客户端使用 JavaScript 来实现这一点。
更多关于Golang中MVM的实现与应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
也就是说,我有一个方法返回下载文件的值,它不会实时在客户端显示信息?也就是说,没有属性包装器?真遗憾。 
在Go语言中,可以使用html/template包结合服务器推送技术来实现持续向HTML模板传输数据,例如计时器或下载进度。以下是一个使用Server-Sent Events (SSE) 的示例:
首先,创建一个HTML模板文件 index.html:
<!DOCTYPE html>
<html>
<head>
<title>实时数据更新</title>
</head>
<body>
<h1>实时数据监控</h1>
<div id="timer">计时器: 0秒</div>
<div id="download">下载进度: 0%</div>
<script>
const eventSource = new EventSource('/events');
eventSource.onmessage = function(event) {
const data = JSON.parse(event.data);
document.getElementById('timer').textContent = `计时器: ${data.timer}秒`;
document.getElementById('download').textContent = `下载进度: ${data.download}%`;
};
eventSource.onerror = function() {
console.log('连接错误');
};
</script>
</body>
</html>
然后,创建Go服务器程序:
package main
import (
"encoding/json"
"html/template"
"log"
"net/http"
"time"
)
type UpdateData struct {
Timer int `json:"timer"`
Download int `json:"download"`
}
func main() {
// 解析模板
tmpl := template.Must(template.ParseFiles("index.html"))
// 首页路由
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, nil)
})
// SSE事件流路由
http.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
// 设置SSE相关头部
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Access-Control-Allow-Origin", "*")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
return
}
// 模拟计时器和下载进度
timer := 0
download := 0
for {
select {
case <-r.Context().Done():
log.Println("客户端断开连接")
return
case <-time.After(1 * time.Second):
timer++
if download < 100 {
download += 10
}
data := UpdateData{
Timer: timer,
Download: download,
}
jsonData, err := json.Marshal(data)
if err != nil {
log.Printf("JSON编码错误: %v", err)
continue
}
// 发送SSE格式数据
fmt.Fprintf(w, "data: %s\n\n", jsonData)
flusher.Flush()
if download >= 100 {
fmt.Fprintf(w, "event: close\ndata: 下载完成\n\n")
flusher.Flush()
return
}
}
}
})
log.Println("服务器启动在 :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
如果需要使用WebSocket实现更复杂的双向通信,可以使用gorilla/websocket库:
package main
import (
"html/template"
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func main() {
tmpl := template.Must(template.ParseFiles("index_ws.html"))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, nil)
})
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("WebSocket升级失败:", err)
return
}
defer conn.Close()
timer := 0
download := 0
for {
timer++
if download < 100 {
download += 10
}
data := map[string]interface{}{
"timer": timer,
"download": download,
}
if err := conn.WriteJSON(data); err != nil {
log.Println("发送数据失败:", err)
break
}
time.Sleep(1 * time.Second)
if download >= 100 {
break
}
}
})
log.Println("服务器启动在 :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
对应的WebSocket HTML模板 index_ws.html:
<!DOCTYPE html>
<html>
<head>
<title>WebSocket实时数据</title>
</head>
<body>
<h1>实时数据监控</h1>
<div id="timer">计时器: 0秒</div>
<div id="download">下载进度: 0%</div>
<script>
const ws = new WebSocket('ws://' + window.location.host + '/ws');
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
document.getElementById('timer').textContent = `计时器: ${data.timer}秒`;
document.getElementById('download').textContent = `下载进度: ${data.download}%`;
};
ws.onclose = function() {
console.log('连接关闭');
};
</script>
</body>
</html>
运行前需要安装WebSocket库:
go get github.com/gorilla/websocket
这些示例展示了如何使用SSE和WebSocket技术实现持续向HTML模板传输实时数据。SSE适用于服务器向客户端单向推送数据的场景,而WebSocket支持双向通信。

