2013-11-04 53 views
1

我想实现一个简单的“全局”计数器,基于每个用户点击浏览器按钮上的按钮进行更新。例如,如果你访问网站并点击按钮,如果我在同一个网站上,我会看到柜台增加。我试图通过长时间投票来做到这一点,但我面临一些问题。主要是服务器变量不会回来,因为我认为它应该。GO中的长轮询,服务器没有合适的响应?

服务器:

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> 

计数器变量不来从服务器由于某种原因回来。我相信每次单击按钮时我都会改变状态,所以longpolling函数应该得到最新更新的计数器变量。如果您有任何建议,请让我知道!

+0

shamless塞:我创建了一个库调用golongpoll是负责所有样板的为您服务。见https://github.com/jcuga/golongpoll – jCuga

回答

1

我看到你的程序的两个问题: 1.在服务器:

messages <- string(counter) 

您应该使用 “STRCONV” 包

messages <- strconv.Itoa(counter) 

串(0)将返回类似[]字节{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元素财产

+0

非常感谢!我一直在盯着这个太久,但你的回答抓住了我的两个错误。 – ZAX