github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/utilities/utils/server.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "strings" 8 9 "github.com/neatio-net/neatio/chain/log" 10 "github.com/neatio-net/neatio/network/node" 11 "github.com/neatio-net/neatio/network/rpc" 12 "gopkg.in/urfave/cli.v1" 13 ) 14 15 var ( 16 httpListener net.Listener 17 httpMux *http.ServeMux 18 httpHandlerMapping map[string]*rpc.Server 19 20 wsListener net.Listener 21 wsMux *http.ServeMux 22 wsOrigins []string 23 wsHandlerMapping map[string]*rpc.Server 24 ) 25 26 func StartRPC(ctx *cli.Context) error { 27 28 rpcConfig := node.DefaultConfig 29 30 SetHTTP(ctx, &rpcConfig) 31 SetWS(ctx, &rpcConfig) 32 wsOrigins = rpcConfig.WSOrigins 33 34 httperr := startHTTP(rpcConfig.HTTPEndpoint(), rpcConfig.HTTPCors, rpcConfig.HTTPVirtualHosts, rpcConfig.HTTPTimeouts) 35 if httperr != nil { 36 return httperr 37 } 38 39 wserr := startWS(rpcConfig.WSEndpoint()) 40 if wserr != nil { 41 return wserr 42 } 43 44 return nil 45 } 46 47 func StopRPC() { 48 if httpListener != nil { 49 httpAddr := httpListener.Addr().String() 50 httpListener.Close() 51 httpListener = nil 52 log.Info("HTTP endpoint closed", "url", fmt.Sprintf("http://%s", httpAddr)) 53 } 54 if httpMux != nil { 55 for _, httpHandler := range httpHandlerMapping { 56 httpHandler.Stop() 57 } 58 } 59 60 if wsListener != nil { 61 wsAddr := wsListener.Addr().String() 62 wsListener.Close() 63 wsListener = nil 64 log.Info("WebSocket endpoint closed", "url", fmt.Sprintf("ws://%s", wsAddr)) 65 } 66 if wsMux != nil { 67 for _, wsHandler := range wsHandlerMapping { 68 wsHandler.Stop() 69 } 70 } 71 } 72 73 func IsHTTPRunning() bool { 74 return httpListener != nil && httpMux != nil 75 } 76 77 func IsWSRunning() bool { 78 return wsListener != nil && wsMux != nil 79 } 80 81 func HookupHTTP(chainId string, httpHandler *rpc.Server) error { 82 if httpMux != nil { 83 log.Infof("Hookup HTTP for (chainId, http Handler): (%v, %v)", chainId, httpHandler) 84 if httpHandler != nil { 85 httpMux.Handle("/", httpHandler) 86 httpHandlerMapping[chainId] = httpHandler 87 } 88 } 89 return nil 90 } 91 92 func HookupWS(chainId string, wsHandler *rpc.Server) error { 93 if wsMux != nil { 94 log.Infof("Hookup WS for (chainId, ws Handler): (%v, %v)", chainId, wsHandler) 95 if wsHandler != nil { 96 wsMux.Handle("/", wsHandler.WebsocketHandler(wsOrigins)) 97 wsHandlerMapping[chainId] = wsHandler 98 } 99 } 100 return nil 101 } 102 103 func startHTTP(endpoint string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) error { 104 if endpoint == "" { 105 return nil 106 } 107 108 var err error 109 httpListener, httpMux, err = startNeatChainHTTPEndpoint(endpoint, cors, vhosts, timeouts) 110 if err != nil { 111 return err 112 } 113 httpHandlerMapping = make(map[string]*rpc.Server) 114 115 log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%s", endpoint), "cors", strings.Join(cors, ","), "vhosts", strings.Join(vhosts, ",")) 116 return nil 117 } 118 119 func startNeatChainHTTPEndpoint(endpoint string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) (net.Listener, *http.ServeMux, error) { 120 var ( 121 listener net.Listener 122 err error 123 ) 124 if listener, err = net.Listen("tcp", endpoint); err != nil { 125 return nil, nil, err 126 } 127 mux := http.NewServeMux() 128 go rpc.NewHTTPServer(cors, vhosts, timeouts, mux).Serve(listener) 129 return listener, mux, err 130 } 131 132 func startWS(endpoint string) error { 133 if endpoint == "" { 134 return nil 135 } 136 137 var err error 138 wsListener, wsMux, err = startNeatChainWSEndpoint(endpoint) 139 if err != nil { 140 return err 141 } 142 wsHandlerMapping = make(map[string]*rpc.Server) 143 144 log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%s", wsListener.Addr())) 145 return nil 146 } 147 148 func startNeatChainWSEndpoint(endpoint string) (net.Listener, *http.ServeMux, error) { 149 var ( 150 listener net.Listener 151 err error 152 ) 153 if listener, err = net.Listen("tcp", endpoint); err != nil { 154 return nil, nil, err 155 } 156 mux := http.NewServeMux() 157 wsServer := &http.Server{Handler: mux} 158 go wsServer.Serve(listener) 159 return listener, mux, err 160 }