2013-10-31 8 views
11

Sto iniziando a giocare con le websockets + go e beh penso che sto fraintendendo qualcosa di abbastanza semplice con i websocket in Go.Servire una websocket in Go

Mi piacerebbe semplicemente ascoltare una connessione web-socket ed elaborare di conseguenza. Tuttavia, tutti gli esempi che vedo in Go using websocket servono la pagina web che si connette alla websocket, è un requisito?

Il seguente è un server eco base Ho installato:

package main 

import (
    "fmt" 
    "code.google.com/p/go.net/websocket" 
    "net/http" 
) 

func webHandler(ws *websocket.Conn) { 
    var s string 
    fmt.Fscan(ws, &s) 
    fmt.Println("Received: ", s) 
} 

func main() { 
    fmt.Println("Starting websock server: ") 
    http.Handle("/echo", websocket.Handler(webHandler)) 
    err := http.ListenAndServe(":8080", nil) 
    if err != nil { 
    panic("ListenAndServe: " + err.Error()) 
    } 
} 

Questo è il javascript utilizzato per la connessione:

ws = new WebSocket("ws://localhost:8080/echo"); 
ws.onmessage = function(e) { 
    console.log("websock: " + e.data); 
}; 

Tuttavia questo si traduce in: collegamento WebSocket a 'WS:// localhost: 8080/echo 'fallito: codice di risposta inatteso: 403

risposta

15

Quando si lavora con websockets da Javascript, raramente si devono leggere i frame ctly. Ad essere onesti, non sono nemmeno sicuro di come farlo.

Fortunatamente, il pacchetto websocket ha già un tipo, Codec che fa questo per voi. Il mio suggerimento è quello di utilizzare il codec websocket.Message predefinito per i messaggi Recieve e Send.

Il messaggio è un codec per inviare/ricevere dati di testo/binari in un frame sulla connessione WebSocket. Per inviare/ricevere frame di testo, utilizzare il tipo di stringa. Per inviare/ricevere frame binario, utilizzare il tipo di byte [].

Utilizzando websocket.Message, il vostro webHandler sarebbe simile a questa:

func webHandler(ws *websocket.Conn) { 
    var in []byte 
    if err := websocket.Message.Receive(ws, &in); err != nil { 
     return 
    } 
    fmt.Printf("Received: %s\n", string(in)) 
    websocket.Message.Send(ws, in)  
} 

E, no, non è un requisito che Go serve la pagina web. L'errore 403 che hai ricevuto non ha a che fare con Go o il pacchetto websocket.

+0

Cosa significa un'interruzione in un blocco if? –

+1

@ElgsQianChen L'interruzione è molto probabilmente un residuo di me che prima mette la Ricezione e Invia in un ciclo for, per evitare che si disconnetta dopo il primo messaggio. L'ho cambiato in un 'return' invece. – ANisus

+0

Ah, capisco. Grazie per la spiegazione @ANisus. –

10

ho avuto un problema simile e il problema 403 errore è correlato al modo in cui tratta il Go http Origin header:

Handler è una semplice interfaccia a un client browser WebSocket. Controlla se l'intestazione Origin è un URL valido per impostazione predefinita. Si potrebbe voler verificare websocket.Conn.Config(). Origin nella funzione. Se si utilizza Server anziché Handler, è possibile chiamare websocket.Origin e controllare l'origine nella funzione Handshake. Pertanto, se si desidera accettare client non browser, che non invia l'intestazione Origin, è possibile utilizzare Server. che non controlla l'origine nella sua stretta di mano.

Per disattivare il controllo di origine, è necessario usare qualcosa come:

http.HandleFunc("/echo", 
    func (w http.ResponseWriter, req *http.Request) { 
     s := websocket.Server{Handler: websocket.Handler(webHandler)} 
     s.ServeHTTP(w, req) 
    }); 

Almeno questo ha risolto il problema per me (server per Communication Server WebSocket) e penso che potrebbe risolvere il problema anche se l'intestazione di origine non corrisponde.

+0

Sto cercando anche un modo per disattivare il controllo dell'origine incrociata. src/ondemand/server.go: 103: impossibile usare func literal (tipo func (http.ResponseWriter, * http.Request)) come tipo http.Handler in argomento a http.Handle: \t func (http.ResponseWriter, * http .Richiesta) non implementa http.Handler (metodo ServeHTTP mancante) – coulix

+0

Accidenti, grazie! Questa soluzione non solo ha funzionato, ma si adatta perfettamente a ciò che ho già! –