gpt4 book ai didi

javascript - 长轮询, "Global"按钮,向所有人广播?

转载 作者:IT王子 更新时间:2023-10-29 01:49:07 24 4
gpt4 key购买 nike

我正在尝试实现一个全局按钮计数器,它会随着任何/不同用户的点击而更新。所以我的想法是,如果有人点击按钮,我会在我的页面实例上看到计数器更新。

我目前使用长轮询技术,或者我认为是这样,但经过审查后,我相信我在向所有浏览器“广播”更新时遇到了错误。

当前的错误是,例如,如果我打开了两个浏览器,并且我连续单击一个浏览器,那么我单击该按钮的那个浏览器只会更新一半时间。它将得到 1 3 5 等,而另一个浏览器显示 2 4 6 等。

在线查看后,我认为这可能与 channel 和向网站上的所有浏览器广播有关。如果有人能帮我举例说明我如何每次都将更新发送到所有浏览器,我将不胜感激。

客户:

<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)
}
}

最佳答案

问题不在于 Go 代码(单独;参见 PS PS),而是浏览器(Chrome)。对同一个 URL 发出 2 个请求是按顺序发生的,而不是并行发生的。

解决方案您需要在 longpoll URL 中添加一个唯一的时间戳来欺骗浏览器:

req.open ('GET', url+"?"+(new Date().getTime()), true); 

PS - 通过这个问题,我学到了很多关于 Go channel 和互斥体的知识。谢谢:)

PS PS - James 的回答 (https://stackoverflow.com/a/19803051/143225) 是让服务器端 Go 代码一次处理超过 1 个请求的关键,因为 Go channel 是阻塞的,这意味着一次只能接收 1 个 goroutine。所以OP的问题的解决方案是前端和后端代码更改的组合。

关于javascript - 长轮询, "Global"按钮,向所有人广播?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19802037/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com