2016-04-02 18 views
0

ブラウザから使用したいWebSocket JSON-RPCサーバーの例があります。 URL「http:localhost:8080」にアクセスすると、ブラウザはWebSocket接続を適切に開きます。しかし、ブラウザがWebSocketリクエストを送信すると、サーバーはWebSocket接続を閉じます。私は、RPCメソッドがサーバー上で呼び出されるのを見ることさえできません。go websocket jsonrpcブラウザ接続のクローズ

しかし、Goクライアントからサーバーを呼び出すことは完全に機能します。

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) 
} 

ウェブ/ 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) 
} 

問題の原因を知っていますか?

ありがとうございました。

乾杯

+0

この質問はhttps://groups.google.com/forum/#!topic/gorilla-web/CqBIuUCd0zAとhttps://groups.google.com/forum/#!topic/golang-nutsでも確認できました/ 4IKhYSuly9o –

答えて

1

サーバアプリケーションはjsonrpc.ServeConn(ws.UnderlyingConn()) }サーバがJSON-RPCプロトコルのWebSocketプロトコルの切り替えさを呼び出します。ブラウザは引き続きWebSocketプロトコルを使用します。ピアの1つが予期しないプロトコルを読み取ってエラーになるため、接続は閉じられます。

このアプリケーションがWebSocketプロトコルからJSON-RPCプロトコルにも切り替わるため、Goクライアントアプリケーションで問題は発生しません。

ブラウザアプリケーションから基本的なネットワーク接続にアクセスすることはできません。

WebSocketプロトコルを使用するにはCodecと書かれたnet/rpcパッケージを使用できます。別のオプションは、メッセージベースのWebSocket APIをnet/rpc/jsonrpcサーバーが予期するストリームに変換するためのアダプタを作成することです。

+0

ええ、そうです。しかし、ブラウザからwebsocket jsonrpcサーバーを使用する方法はありますか? – Alvaro

+0

ブラウザからJSON-RPCプロトコルを使用することはできません。 –

+0

@Alvaro [Codec](https://godoc.org/net/rpc#ServerCodec)を実装して、ブラウザからnet/rpcパッケージを使用することができます。また、これらのGoogleグループの投稿をクロスリンクするので、ここで取り上げた内容に時間を割くことなく時間を費やすことができます。 –

関連する問題