2

メッセージを受信し、それに応じて処理するループに取り組んでいます。基本的には、キープアライブと認証を備えた websocket echo-er であり、キープアライブの部分でしばらく立ち往生しています。

概念は単純です。サーバーが起動すると、ティッカーを使用してゴルーチンを作成し、uint64 ポインターを初期化します。ティッカーがティックするたびに (2 秒ごと)、atomic.AddUint64(clockTicks, 1) でポインターをインクリメントします。 Websocket 接続ゴルーチンごとに、compare と atomic.LoadUint64(clockTicks) を使用してティックごとに変数をチェックし、ping/pong メッセージを送信します。

編集:メッセージが受信されるまで、何かが for ループをブロックしているようです。結果:

i := atomic.LoadUint64(clockTicks)
    if i != cur {
        cur = i
        if act != true {
            fmt.Println("Quit Nao U filthy bot.")
            return
        } else {
            fmt.Println("Keep Going.")
            act = false
        }
    }

このスニペットでは、 i := atomic.LoadUint64(clockTicks) & すべての if ブロックは i メッセージが送信されたときにのみ実行されます (msg に "Keep Going." が出力されます)。これは私が望むものではありません。反復のために、そして「続けてください」。& 「Quit nao ...」で clockTicks がインクリメントされるたびにトリガー

重要なコード部分は次のとおりです。Go と Gorilla の Websockets ライブラリを使用しています。

func Clock() {
clockTicks = new(uint64)
*clockTicks = 0
clock := time.NewTicker(authIntervals).C
for {
    <-clock
    atomic.AddUint64(clockTicks, 1)
}
}

var wsu = websocket.Upgrader{
ReadBufferSize:  1024,
WriteBufferSize: 1024,
CheckOrigin:     OriginHandler,
}

func serveWS(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
    http.Error(w, "Method not allowed", 405)
    return
}

ws, err := wsu.Upgrade(w, r, nil)
if err != nil {
    fmt.Println(err)
    return
}

defer ws.Close()
cur := atomic.LoadUint64(clockTicks)
var act, val = true, false
for {
    i := atomic.LoadUint64(clockTicks)
    if i != cur { /* Only triggers when I receive a msg */
        cur = i
        if act != true {
            fmt.Println("Quit Nao U filthy bot.")
            return
        } else {
            fmt.Println("Keep Going.")
            act = false
        }
    }

    mtype, p, err := ws.ReadMessage()
    if err != nil {
        return
    }

    ...

}

編集 2: IRC の誰かが、おそらく ws.ReadMessage がブロックしていると示唆しましたが、私にはよくわかりません (彼は、ws.ReadMessage 実装で使用されている ioutil.ReadAll がそれをブロックしていると言い、彼はそれについてかなり確信しています)。

4

1 に答える 1

4

Websocket 読み取りメソッドは、ネットワーク接続の Read メソッドを呼び出して、ネットワークからデータを取得します。ネットワーク接続の Read メソッドがブロックされるため、webscocket メソッドもブロックされます。

ping を送信するには、Gorilla チャットの例のように書き込みループでティッカーを使用するか、Gorilla コマンドの例のようにping 用に別のゴルーチンを実行します。

于 2015-11-01T19:38:39.567 に答える