【发布时间】:2013-11-17 02:19:57
【问题描述】:
我正在尝试实现一个全局按钮计数器,该计数器会在任何/不同用户单击它时更新。 所以这个想法是,如果一个人点击按钮,我会在我的页面实例上看到计数器更新。
我目前使用长轮询技术,或者我认为是这样,但经过审查,我认为我在将更新“广播”到所有浏览器时出错。
当前的错误是,例如,如果我打开了两个浏览器,并且我不断单击一个浏览器,则我单击按钮的那个浏览器只会更新一半时间。它将得到 1 3 5 等,而其他浏览器显示 2 4 6 等。
在线查看后,我认为这可能与频道和网站上所有浏览器的广播有关。如果有人可以帮助我举例说明我如何将更新发送到所有浏览器,每一次,我都会非常感激。
客户:
<html>
<script language=javascript>
function longpoll(url, callback) {
var req = new XMLHttpRequest ();
req.open ('GET', url, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if (req.status == 200) {
callback(req.responseText);
longpoll(url, callback);
} else {
alert ("long-poll connection lost");
}
}
};
req.send(null);
}
function recv(msg) {
var box = document.getElementById("counter");
box.innerHTML += msg + "\n";
}
function send() {
var box = document.getElementById("counter");
var req = new XMLHttpRequest ();
req.open ('POST', "/push?rcpt=", true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if (req.status == 200) {
} else {
alert ("failed to send!");
}
}
};
req.send("hi")
//box.innerHTML += "test" ;
}
</script>
<body onload="longpoll('/poll', recv);">
<h1> Long-Poll Chat Demo </h1>
<p id="counter"></p>
<button onclick="send()" id="test">Test Button</button>
</body>
</html>
服务器:
package main
import (
"net/http"
"log"
"io"
// "io/ioutil"
"strconv"
)
var messages chan string = make(chan string, 100)
var counter = 0
func PushHandler(w http.ResponseWriter, req *http.Request) {
//body, err := ioutil.ReadAll(req.Body)
/*if err != nil {
w.WriteHeader(400)
}*/
counter += 1
messages <- strconv.Itoa(counter)
}
func PollResponse(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, <-messages)
}
func main() {
http.Handle("/", http.FileServer(http.Dir("./")))
http.HandleFunc("/poll", PollResponse)
http.HandleFunc("/push", PushHandler)
err := http.ListenAndServe(":8010", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
【问题讨论】:
-
您能添加一些调试输出并查看推送请求何时通过吗?
-
@Brenden 如果您就您想要的东西给我更多的指导,我很乐意效劳。推送请求通过客户端的
send()函数进行,只要用户按下按钮就会激活该函数 -
我会添加一些
fmt.Println()电话以确认这些电话何时通过,而不是民意调查响应何时通过。我会在一个小时左右运行本地测试,看看我能得到什么结果(我现在在工作,无法测试你的代码) -
@Brenden 据我所知,他们正在按预期进行,一个接一个。但是非常感谢你帮助我!对此,我真的非常感激!期待您的回音!
-
我让它在本地运行,它按预期工作。编号是连续的。我在 Linux/Chromium 上进行测试,你在测试什么?您可以在没有 Javascript 的情况下手动请求轮询和推送 URL 吗?它的工作方式不同吗?
标签: javascript go global-variables long-polling