1. 程式人生 > >go伺服器向頁面推送訊息

go伺服器向頁面推送訊息

今天看了http://blog.csdn.net/hookttg/article/details/72867174#comments 這篇文章,這個html的EventSource事件之前沒有用過,所以跟著作者的程式碼重新寫了一遍,但是執行的時候一直不列印時間資料,對照著作者的提示檢查了幾遍程式碼都不行,,每次執行都直接結束了,後來在w3cschool重新看了下該技術的用法,getDate函式沒有問題,沒有執行到這裡肯定是其他出現問題了。

所以在http.ListenAndServer("",nil)中加了一個埠號,嗯這次好了,直接訪問localhost:3000可以列印訊息了。

補充更新內容:

新增錯誤提示程式碼

go中關於這個為空時預設是:80,但是我使用預設卻執行一直沒有成功,後來想起來,在mac系統中非root使用者不能啟動1024以下的埠,所以才會呼叫不到80埠,以為原作者的程式碼有漏洞,誒,原來又是自己粗心了。

下面的go程式碼main.go

package main
import (
	"net/http"
	"fmt"
	"time"
	"html/template"
	"github.com/labstack/gommon/log"
)

func viewData(w http.ResponseWriter,r *http.Request)  {
	//testserverevent.html為html頁面的名稱
	r.ParseForm()
	if r.Method == "GET"{
		t,err:=template.ParseFiles("testserverevent.html")
		if err != nil{
			fmt.Fprintf(w,"parse template error:%s",err.Error())
			//			return
		}
		t.Execute(w,nil)
	}
}

func getDate(w http.ResponseWriter,r *http.Request)  {
	fmt.Println("enter getDate.")
	for{
		w.Header().Set("Content-Type","text/event-stream;charset=utf-8")
		w.Header().Set("Catch-Control","no-cache")
		dtstr :="data:" + fmt.Sprint(time.Now()) +"\n\n"
		dtstr = dtstr + "retry:"+"1000"+"\n\n"
		w.Write([]byte(dtstr))

		if f,ok :=w.(http.Flusher);ok{
			f.Flush()
		}else{
			fmt.Println("no flush")
		}
		time.Sleep(10000*time.Millisecond)
	}
}

func main()  {
	fmt.Println("enter main.")

	http.HandleFunc("/",viewData)
	http.HandleFunc("/getdate",getDate)
	//測試當addr的傳入值為空時沒法執行的原因
	//err:=http.ListenAndServe("",nil)
	//if err != nil{
	//	log.Fatal("ListenAndServer:",err)
	//}
	//在mac下執行,必須給一個大於1024的埠
	http.ListenAndServe(":3000",nil)
}

當輸入的埠號為空時,報錯資訊如下:

{"time":"2017-09-26T12:03:53.574872333+08:00","level":"-","prefix":"-","file":"log.go","line":"317","message":"ListenAndServer:listen tcp :80: bind: permission denied"}


下面是html的程式碼testserverevent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>EventSource測試</title>
</head>
<body>
<h1>伺服器當前時間:</h1>
<div id = "result"></div>
<div>typeof(EventSource):<output id="keytype"></output></div>
<script>
var resultElement = document.getElementById("keytype")
resultElement.value = typeof (EventSource)
if (typeof(EventSource) !== "undefined"){
document.getElementById("result").innerHTML = "連線網路";
//getdate為golang中提供的訪問目錄名稱http.HandleFunc("/getdate",getDate)
var source = new EventSource("getdate");
source.onmessage = function (event) {

document.getElementById("result").innerHTML += event.data +"<br>";
};
}else{
document.getElementById("result").innerHTML = "抱歉,你的瀏覽器不支援server-sent事件...";
}
</script>
</body>
</html>
下面是嘗試的錯誤用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>EventSource測試</title>
</head>
<body>
<h1>伺服器當前時間:</h1>
<div id = "result"></div>
<div>typeof(EventSource):<output id="keytype"></output></div>
<script>
//嘗試訪問地址
var wsUrl = "ws://localhost:3000/getdate";
var resultElement = document.getElementById("keytype")
resultElement.value = typeof (EventSource)
if (typeof(EventSource) !== "undefined"){
document.getElementById("result").innerHTML = "連線網路";
//            var source = new EventSource("getdate");
//傳入訪問地址
var source = new EventSource(wsUrl);
source.onmessage = function (event) {

document.getElementById("result").innerHTML += event.data +"<br>";
};
}else{
document.getElementById("result").innerHTML = "抱歉,你的瀏覽器不支援server-sent事件...";
}
</script>
</body>
</html>

本文中大家可以拓寬的知識點: