使用Golang的channel将时间推送到浏览器
使用Golang的channel将时间推送到浏览器 我正在尝试使用通道将时间推送到浏览器,因此编写了以下代码:
package main
import (
"net/http"
"time"
)
type DataPasser struct {
logs chan string
}
func main() {
passer := &DataPasser{logs: make(chan string)}
go func() {
for {
passer.logs <- time.Now().String()
}
}()
http.HandleFunc("/", passer.handleHello)
http.ListenAndServe(":9999", nil)
}
func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) {
for {
w.Write([]byte(<-p.logs))
}
/* for {
io.WriteString(w, <-p.logs)
}
*/
}
它确实工作了,但会不断添加带有新时间的新行,如下所示:

我需要的是每次服务器发送时间时,都能得到一行被清除并被新时间替换的文本?有什么帮助吗?
更新
我尝试使用 SSE 服务器发送事件,如下所示,但没有成功:
package main
import (
"net/http"
"time"
)
type DataPasser struct {
logs chan string
}
func main() {
passer := &DataPasser{logs: make(chan string)}
t := time.NewTicker(time.Second)
defer t.Stop()
go func() {
for range t.C {
passer.logs <- time.Now().String()
}
}()
http.HandleFunc("/", passer.handleHello)
http.ListenAndServe(":9999", nil)
}
func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) {
setupCORS(&w, r)
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Internal error", 500)
return
}
for {
w.Write([]byte(<-p.logs))
// c := []byte(<-p.logs)
// fmt.Fprint(w, c)
flusher.Flush()
}
/* for {
io.WriteString(w, <-p.logs)
}
*/
// w.Write([]byte("Hi, from Service: " + ws.name))
}
func setupCORS(w *http.ResponseWriter, req *http.Request) {
(*w).Header().Set("Cache-Control", "no-cache")
(*w).Header().Set("Access-Control-Allow-Origin", "*")
(*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
(*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}
HTML文件如下:
<html>
<head></head>
<body>
<div id="counter" width="500" height="600">
</body>
<script>
var source = new EventSource("http://localhost:9999/");
source.onmessage = function (event) {
console.log(event)
var counter = event.data; // JSON.parse(event.data);
document.getElementById("counter").innerHTML = counter;
}
</script>
</html>
更多关于使用Golang的channel将时间推送到浏览器的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
您可以在 onload 方法中使用 XMLHttpRequest 获取服务器发送的数据。
![]()

发送和接收二进制数据 - Web APIs | MDN
可以设置 XMLHttpRequest 对象的 responseType 属性来更改预期的服务器响应类型。可能的值为空字符串(默认值)、“arraybuffer”、“blob”、“document”、“json” 和 “text”。response 属性将…
更多关于使用Golang的channel将时间推送到浏览器的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
要实现每次更新替换同一行文本,需要修改服务器端发送的数据格式和客户端的处理方式。以下是修正后的代码:
服务器端代码:
package main
import (
"fmt"
"net/http"
"time"
)
type DataPasser struct {
logs chan string
}
func main() {
passer := &DataPasser{logs: make(chan string)}
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
go func() {
for range ticker.C {
passer.logs <- time.Now().Format("2006-01-02 15:04:05")
}
}()
http.HandleFunc("/", passer.handleHello)
http.ListenAndServe(":9999", nil)
}
func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) {
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
}
for {
select {
case <-r.Context().Done():
return
case msg := <-p.logs:
fmt.Fprintf(w, "data: %s\n\n", msg)
flusher.Flush()
}
}
}
客户端HTML代码:
<!DOCTYPE html>
<html>
<head>
<title>Time Stream</title>
</head>
<body>
<div id="time-display" style="font-size: 24px; font-family: monospace;"></div>
<script>
const eventSource = new EventSource("http://localhost:9999/");
eventSource.onmessage = function(event) {
document.getElementById("time-display").textContent = event.data;
};
eventSource.onerror = function(error) {
console.error("EventSource failed:", error);
eventSource.close();
};
</script>
</body>
</html>
关键修改点:
- SSE格式规范:服务器发送事件必须遵循
data: {message}\n\n格式,每个事件以双换行符结束 - 时间格式化:使用
time.Now().Format("2006-01-02 15:04:05")获得更易读的时间格式 - 上下文处理:添加
r.Context().Done()检查,确保连接关闭时能正确清理资源 - 客户端处理:使用
textContent而不是innerHTML来更新文本内容,这样会替换而不是追加
运行效果:浏览器中会显示一个不断更新的时间文本,每次新时间会替换旧时间,而不是添加新行。

