2016-04-02 12 views
0

Ich habe ein WebSocket JSON-RPC Server-Beispiel, das ich von einem Browser verwenden möchte. Wenn Sie auf die URL "http: localhost: 8080" zugreifen, öffnet der Browser die WebSocket-Verbindung ordnungsgemäß. Wenn der Browser jedoch die WebSocket-Anforderung sendet, schließt der Server die WebSocket-Verbindung. Ich kann nicht einmal eine Spur der RPC-Methode sehen, die auf dem Server aufgerufen wird.Go websocket jsonrpc browser connection schließen

Der Aufruf des Servers von einem Go-Client funktioniert jedoch einwandfrei.

server.go

package main 

import (
     "log" 
     "net/http" 
     "net/rpc" 
     "net/rpc/jsonrpc" 
     "github.com/gorilla/websocket" 
) 

type Service struct{} 

func (t *Service) Echo(req *string, res *string) error { 
     log.Printf("Service.Echo") 
     *res = *req 
     log.Printf("Service.Echo req:%s res:%s", *req, *res) 
     return nil 
} 

var upgrader = websocket.Upgrader{ 
     ReadBufferSize: 1024, 
     WriteBufferSize: 1024, 
} 

func serveWS(w http.ResponseWriter, r *http.Request) { 
     ws, err := upgrader.Upgrade(w, r, nil) 
     defer ws.Close() 


     if err != nil { 
       log.Println(err) 
       return 
     } 
     jsonrpc.ServeConn(ws.UnderlyingConn()) 
} 

func main() { 
     rpc.Register(new(Service)) 
     http.Handle("/", http.FileServer(http.Dir("web"))) 
     http.HandleFunc("/ws", serveWS) 
     http.ListenAndServe(":8080", nil) 
} 

web/index.html

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<script type="text/javascript"> 
    var ws = new WebSocket("ws://localhost:8080/ws"); 
    ws.onopen = function(ev){ 
     alert("open"); 
    } 
    ws.onmessage = function(ev){ 
     alert("message"); 
    } 
    ws.onclose = function(ev){ 
     alert("close"); 
    } 

    function send() { 
     msg = { 
       method: "Service.Echo", 
       params: "hello", 
       id: 0 
     }; 
     var s = JSON.stringify(msg); 
     alert(s); 
     ws.send(s); 
    } 
</script> 
</head> 
<body>   
<button onclick='send()'>Send</button> 
</body> 
</html> 

client.go

package main 

import (
     "log" 
     "net/rpc/jsonrpc" 
     "github.com/gorilla/websocket" 
) 

func main() { 
     ws, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil) 
     if err != nil { 
       log.Fatal("dial:", err) 
     } 
     defer ws.Close() 

     client := jsonrpc.NewClient(ws.UnderlyingConn()) 

     req := "hello" 
     var res string 
     err = client.Call("Service.Echo", &req, &res) 
     if err != nil { 
       log.Fatal("Service.Echo error:", err) 
     } 
     log.Printf("Service.Echo: req:%s res:%s", req, res) 
} 

Wissen Sie, was das Problem sein könnte?

Vielen Dank.

Prost

+0

Diese Frage wurde auch unter https://groups.google.com/forum/#!topic/gorilla-web/CqBIuUCd0zA und https://groups.google.com/forum/#!topic/golang-nuts gestellt/4IKhYSuly9o –

Antwort

1

Wenn die Server-Anwendung aufruft jsonrpc.ServeConn(ws.UnderlyingConn()) } der Server von dem WebSocket Protokoll dem Protokoll JSON-RPC Schalt. Der Browser verwendet weiterhin das Protokoll WebSocket. Die Verbindung wird geschlossen, weil einer der Peers beim Lesen eines Protokolls, das nicht erwartet wird, Fehler meldet.

Das Problem tritt nicht mit der Go-Client-Anwendung auf, da diese Anwendung auch vom WebSocket-Protokoll zum JSON-RPC-Protokoll wechselt.

Es ist nicht möglich, über eine Browseranwendung auf die zugrunde liegende Netzwerkverbindung zuzugreifen.

Es ist möglich, das net/rpc-Paket mit Codec zu verwenden, das für die Verwendung des WebSocket-Protokolls geschrieben wurde. Eine andere Option besteht darin, einen Adapter zu schreiben, um die nachrichtenbasierte WebSocket-API in den Stream zu konvertieren, der vom net/rpc/jsonrpc-Server erwartet wird.

+0

Ok, ich verstehe. Aber gibt es eine Möglichkeit, einen Websocket JsonRPC Server von einem Browser zu verwenden? – Alvaro

+0

Es ist nicht möglich, das JSON-RPC-Protokoll von einem Browser aus zu verwenden. –

+0

@Alvaro Sie können einen [Codec] (https://godoc.org/net/rpc#ServerCodec) implementieren, um das net/rpc-Paket vom Browser zu verwenden. Verlinken Sie auch diese Google Groups-Postings, damit die Leute keine Zeit damit verschwenden, zu antworten, was hier behandelt wird. –