gnunet-go

GNUnet Bindings for Go
Log | Files | Refs | README | LICENSE

rpc.go (2571B)


      1 // This file is part of gnunet-go, a GNUnet-implementation in Golang.
      2 // Copyright (C) 2019-2022 Bernd Fix  >Y<
      3 //
      4 // gnunet-go is free software: you can redistribute it and/or modify it
      5 // under the terms of the GNU Affero General Public License as published
      6 // by the Free Software Foundation, either version 3 of the License,
      7 // or (at your option) any later version.
      8 //
      9 // gnunet-go is distributed in the hope that it will be useful, but
     10 // WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12 // Affero General Public License for more details.
     13 //
     14 // You should have received a copy of the GNU Affero General Public License
     15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 //
     17 // SPDX-License-Identifier: AGPL3.0-or-later
     18 
     19 package service
     20 
     21 import (
     22 	"context"
     23 	"net/http"
     24 	"time"
     25 
     26 	"github.com/bfix/gospel/logger"
     27 	"github.com/gorilla/mux"
     28 	"github.com/gorilla/rpc/v2"
     29 	"github.com/gorilla/rpc/v2/json2"
     30 )
     31 
     32 //----------------------------------------------------------------------
     33 //----------------------------------------------------------------------
     34 
     35 // JRPCServer for JSON-RPC handling (wrapper to keep type in our package)
     36 type JRPCServer struct {
     37 	*rpc.Server
     38 }
     39 
     40 //----------------------------------------------------------------------
     41 // JSON-RPC interface for services to be used as the primary client API
     42 // for perform, manage and monitor GNUnet activities.
     43 //----------------------------------------------------------------------
     44 
     45 // RunRPCServer runs the JSON-RPC server. It can be terminated by context only.
     46 func RunRPCServer(ctx context.Context, endpoint string) (srvRPC *JRPCServer, err error) {
     47 	// instantiate RPC service
     48 	srvRPC = &JRPCServer{rpc.NewServer()}
     49 	srvRPC.RegisterCodec(json2.NewCodec(), "application/json")
     50 
     51 	// setup RPC request handler
     52 	router := mux.NewRouter()
     53 	router.HandleFunc("/", srvRPC.ServeHTTP)
     54 
     55 	// instantiate a server and run it
     56 	srv := &http.Server{
     57 		Handler:           router,
     58 		Addr:              endpoint,
     59 		WriteTimeout:      5 * time.Second,
     60 		ReadTimeout:       15 * time.Second,
     61 		ReadHeaderTimeout: 5 * time.Second,
     62 	}
     63 	// start listening
     64 	go func() {
     65 		if err := srv.ListenAndServe(); err != http.ErrServerClosed {
     66 			logger.Printf(logger.WARN, "[rpc] server listen failed: %s", err.Error())
     67 		}
     68 	}()
     69 	// wait for shutdown
     70 	go func() {
     71 		<-ctx.Done()
     72 		if err := srv.Shutdown(context.Background()); err != nil {
     73 			logger.Printf(logger.WARN, "[rpc] server shutdownn failed: %s", err.Error())
     74 		}
     75 	}()
     76 	return
     77 }