From 3266bf6a8d8c061aeab9900cec66a52803373bb8 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Sat, 7 Jun 2014 00:35:34 -0500 Subject: [PATCH] Convert to use gorilla websockets package. Also, since the new websoscket package allows the message type to be set independently from the type of the variable, remove the casts between strings and []byte in the websocket read/write paths. This avoids extra copies thereby reducing the garbage generated. Closes #134. --- rpcserver.go | 18 ++++++++++++------ rpcwebsocket.go | 14 +++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 4e17ddbdd..b9d796896 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -6,7 +6,6 @@ package main import ( "bytes" - "code.google.com/p/go.net/websocket" "crypto/subtle" "crypto/tls" "encoding/base64" @@ -23,6 +22,7 @@ import ( "github.com/conformal/btcwire" "github.com/conformal/btcws" "github.com/conformal/fastsha256" + "github.com/conformal/websocket" "io/ioutil" "math/big" "math/rand" @@ -252,12 +252,18 @@ func (s *rpcServer) Start() { http.Error(w, "401 Unauthorized.", http.StatusUnauthorized) return } - wsServer := websocket.Server{ - Handler: websocket.Handler(func(ws *websocket.Conn) { - s.WebsocketHandler(ws, r.RemoteAddr, authenticated) - }), + + // Attempt to upgrade the connection to a websocket connection + // using the default size for read/write buffers. + ws, err := websocket.Upgrade(w, r, nil, 0, 0) + if err != nil { + if _, ok := err.(websocket.HandshakeError); !ok { + rpcsLog.Errorf("Unexpected websocket error: %v", + err) + } + return } - wsServer.ServeHTTP(w, r) + s.WebsocketHandler(ws, r.RemoteAddr, authenticated) }) for _, listener := range s.listeners { diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 5a95ab641..55f625331 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -7,7 +7,6 @@ package main import ( "bytes" "code.google.com/p/go.crypto/ripemd160" - "code.google.com/p/go.net/websocket" "container/list" "crypto/subtle" "encoding/base64" @@ -21,6 +20,7 @@ import ( "github.com/conformal/btcwire" "github.com/conformal/btcws" "github.com/conformal/fastsha256" + "github.com/conformal/websocket" "io" "sync" "time" @@ -917,11 +917,11 @@ type wsClient struct { // (including pass through for standard RPC commands), sends the appropriate // response. It also detects commands which are marked as long-running and // sends them off to the asyncHander for processing. -func (c *wsClient) handleMessage(msg string) { +func (c *wsClient) handleMessage(msg []byte) { if !c.authenticated { // Disconnect immediately if the provided command fails to // parse when the client is not already authenticated. - cmd, jsonErr := parseCmd([]byte(msg)) + cmd, jsonErr := parseCmd(msg) if jsonErr != nil { c.Disconnect() return @@ -961,7 +961,7 @@ func (c *wsClient) handleMessage(msg string) { } // Attmpt to parse the raw json into a known btcjson.Cmd. - cmd, jsonErr := parseCmd([]byte(msg)) + cmd, jsonErr := parseCmd(msg) if jsonErr != nil { // Use the provided id for errors when a valid JSON-RPC message // was parsed. Requests with no IDs are ignored. @@ -1051,8 +1051,8 @@ out: default: } - var msg string - if err := websocket.Message.Receive(c.conn, &msg); err != nil { + _, msg, err := c.conn.ReadMessage() + if err != nil { // Log the error if it's not due to disconnecting. if err != io.EOF { rpcsLog.Errorf("Websocket receive error from "+ @@ -1153,7 +1153,7 @@ out: // closed. select { case r := <-c.sendChan: - err := websocket.Message.Send(c.conn, string(r.msg)) + err := c.conn.WriteMessage(websocket.TextMessage, r.msg) if err != nil { c.Disconnect() break out