github.com/516108736/tendermint@v0.36.0/light/proxy/proxy.go (about) 1 package proxy 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "net/http" 8 9 "github.com/tendermint/tendermint/libs/log" 10 tmpubsub "github.com/tendermint/tendermint/libs/pubsub" 11 lrpc "github.com/tendermint/tendermint/light/rpc" 12 rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server" 13 ) 14 15 // A Proxy defines parameters for running an HTTP server proxy. 16 type Proxy struct { 17 Addr string // TCP address to listen on, ":http" if empty 18 Config *rpcserver.Config 19 Client *lrpc.Client 20 Logger log.Logger 21 Listener net.Listener 22 } 23 24 // ListenAndServe configures the rpcserver.WebsocketManager, sets up the RPC 25 // routes to proxy via Client, and starts up an HTTP server on the TCP network 26 // address p.Addr. 27 // See http#Server#ListenAndServe. 28 func (p *Proxy) ListenAndServe() error { 29 listener, mux, err := p.listen() 30 if err != nil { 31 return err 32 } 33 p.Listener = listener 34 35 return rpcserver.Serve( 36 listener, 37 mux, 38 p.Logger, 39 p.Config, 40 ) 41 } 42 43 // ListenAndServeTLS acts identically to ListenAndServe, except that it expects 44 // HTTPS connections. 45 // See http#Server#ListenAndServeTLS. 46 func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error { 47 listener, mux, err := p.listen() 48 if err != nil { 49 return err 50 } 51 p.Listener = listener 52 53 return rpcserver.ServeTLS( 54 listener, 55 mux, 56 certFile, 57 keyFile, 58 p.Logger, 59 p.Config, 60 ) 61 } 62 63 func (p *Proxy) listen() (net.Listener, *http.ServeMux, error) { 64 mux := http.NewServeMux() 65 66 // 1) Register regular routes. 67 r := RPCRoutes(p.Client) 68 rpcserver.RegisterRPCFuncs(mux, r, p.Logger) 69 70 // 2) Allow websocket connections. 71 wmLogger := p.Logger.With("protocol", "websocket") 72 wm := rpcserver.NewWebsocketManager(r, 73 rpcserver.OnDisconnect(func(remoteAddr string) { 74 err := p.Client.UnsubscribeAll(context.Background(), remoteAddr) 75 if err != nil && err != tmpubsub.ErrSubscriptionNotFound { 76 wmLogger.Error("Failed to unsubscribe addr from events", "addr", remoteAddr, "err", err) 77 } 78 }), 79 rpcserver.ReadLimit(p.Config.MaxBodyBytes), 80 ) 81 wm.SetLogger(wmLogger) 82 mux.HandleFunc("/websocket", wm.WebsocketHandler) 83 84 // 3) Start a client. 85 if !p.Client.IsRunning() { 86 if err := p.Client.Start(); err != nil { 87 return nil, mux, fmt.Errorf("can't start client: %w", err) 88 } 89 } 90 91 // 4) Start listening for new connections. 92 listener, err := rpcserver.Listen(p.Addr, p.Config) 93 if err != nil { 94 return nil, mux, err 95 } 96 97 return listener, mux, nil 98 }