dongyou2279 2016-04-02 11:29
浏览 100
已采纳

转到websocket jsonrpc浏览器连接关闭

I have a WebSocket JSON-RPC server example that I want to use from a browser. When you access the URL "http:localhost:8080", the browser opens the WebSocket connection properly. But when the browser sends the WebSocket request, the server closes the WebSocket connection. I can't even see a trace of the RPC method being called on the server.

However, calling the server from a Go client works perfectly.

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

Do you know what the problem could be?

Thank you very much.

Cheers

  • 写回答

1条回答 默认 最新

  • duanjue7508 2016-04-02 13:46
    关注

    When the server application calls jsonrpc.ServeConn(ws.UnderlyingConn()) } the server is switching from the WebSocket protocol to the JSON-RPC protocol. The browser continues to use the WebSocket protocol. The connection is closed because one of the peers errors out reading a protocol that it does not expect.

    The problem does not happen with the Go client application because this application also switches from the WebSocket protocol to the JSON-RPC protocol.

    It is not possible to access the underlying network connection from a browser application.

    It is possible to use the net/rpc package with Codec written to use the WebSocket protocol. Another option is to write an adaptor to convert the message based WebSocket API to the stream expected by the net/rpc/jsonrpc server.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况