2016-04-02 2 views
0

У меня есть пример сервера WebSocket JSON-RPC, который я хочу использовать в браузере. Когда вы получаете доступ к URL-адресу «http: localhost: 8080», браузер правильно открывает соединение WebSocket. Но когда браузер отправляет запрос WebSocket, сервер закрывает соединение WebSocket. Я даже не вижу следа метода RPC, вызываемого на сервере.Перейти 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()) } сервер переходит из протокола WebSocket к протоколу JSON-RPC. Браузер продолжает использовать протокол WebSocket. Соединение закрыто, потому что один из сверстников ошибается, читая протокол, которого он не ожидает.

Проблема не возникает с клиентским приложением Go, потому что это приложение также переключается с протокола WebSocket на протокол JSON-RPC.

Невозможно получить доступ к базовому сетевому соединению из приложения браузера.

Возможно использование пакета net/rpc с Codec, написанным для использования протокола WebSocket. Другой вариант - написать адаптер, чтобы преобразовать API WebSocket на основе сообщений в поток, ожидаемый сервером net/rpc/jsonrpc.

+0

Хорошо, я вижу. Но тогда, есть ли способ использовать сервер jsonrpc для websocket из браузера? – Alvaro

+0

Невозможно использовать протокол JSON-RPC из браузера. –

+0

@Alvaro. Вы можете использовать [Codec] (https://godoc.org/net/rpc#ServerCodec), чтобы использовать пакет net/rpc из браузера. Кроме того, перекрестите эти публикации в Google Groups, чтобы люди не теряли времени, отвечая на то, что здесь описано. –

Смежные вопросы