2013-11-04 91 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