英文:
Long Polling in GO, Server Not Responding Appropriately?
问题
我正在尝试实现一个简单的“全局”计数器,它根据每个用户在其浏览器上点击按钮而更新。例如,如果你访问网站并点击按钮,如果我也在同一个网站上,我将看到计数器增加。我尝试使用长轮询来实现这一点,但遇到了一些问题。主要问题是服务器变量没有按照我认为的方式返回。
服务器端代码如下:
package main
import (
"net/http"
"log"
"io"
"io/ioutil"
)
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 <- string(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(":8005", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
客户端代码如下:
<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.value += 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>
出于某种原因,计数器变量没有从服务器返回。我认为每次点击按钮时我都在改变状态,所以长轮询函数应该获取到最新更新的计数器变量。如果你有任何建议,请告诉我!
英文:
I am trying to implement a simple "global" counter that updates based on every user that clicks the button on their browsers button. For example, if you go to the website and click the button, I will see the counter increase on my side if I'm on the same website. I sought to do this with long polling, but am facing some issues. Mainly the server variable is not coming back as I think it should.
The server:
package main
import (
"net/http"
"log"
"io"
"io/ioutil"
)
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 <- string(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(":8005", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
The client:
<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.value += 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>
The counter variable is not coming back from the server for some reason. I believe I am changing the state every time the button is clicked and so the longpolling function should get the newly updated counter variable. If you have any suggestions, please let me know!
答案1
得分: 1
我在你的程序中看到两个问题:
-
在服务器端:
messages <- string(counter)
你应该使用 "strconv" 包
messages <- strconv.Itoa(counter)
string(0) 会返回类似 []byte{0} 的内容,而不是 "0"
2. 在你的客户端:
function recv(msg) {
var box = document.getElementById("counter");
box.value += msg + "\n";
}
应该改为:
function recv(msg) {
var box = document.getElementById("counter");
box.innerHTML += msg + "\n";
}
我认为 p 元素 没有 value 属性。
英文:
I see two issues in you program:
-
In the server:
messages <- string(counter)
You should use "strconv" package
messages <- strconv.Itoa(counter)
string(0) will return something like []byte{0} not a "0"
2. In your client:
function recv(msg) {
var box = document.getElementById("counter");
box.value += msg + "\n";
}
Should be:
function recv(msg) {
var box = document.getElementById("counter");
box.innerHTML += msg + "\n";
}
I don't think the p element have value property
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论