Ir al RPC inverso al diario

antecedentes

El RPC normal se basa en la estructura C / S. El servidor RPC corresponde al servidor de red y el cliente RPC corresponde al cliente de red. Pero para algunos escenarios especiales, como proporcionar un servicio RPC en la intranet de la empresa, pero la extranet no se puede conectar al servidor de la intranet. En este momento, podemos referirnos a una tecnología similar al proxy inverso, primero enlazar activamente desde la red interna al servidor TCP de la red externa, y luego proporcionar servicios RPC a la red externa basados ​​en el enlace TCP.

Declarar interfaz

type HelloService struct {}

func (p *HelloService) Hello(request string, reply *string) error {
    *reply = "hello:" + request
    return nil
}

Servicio RPC inverso

func main() {
    rpc.Register(new(HelloService))

    for {
        conn, _ := net.Dial("tcp", "localhost:1234")
        if conn == nil {
            time.Sleep(time.Second)
            continue
        }

        rpc.ServeConn(conn)
        conn.Close()
    }
}

Los servicios de intranet de RPC inverso ya no proporcionarán activamente servicios de supervisión de TCP, sino que primero se conectarán activamente al servidor TCP de la otra parte. Luego, proporcione el servicio RPC a la otra parte en función de cada enlace TCP establecido.

Cliente RPC

El cliente RPC debe proporcionar un servicio TCP en una dirección pública para aceptar solicitudes de conexión del servidor RPC:

func main() {
    listener, err := net.Listen("tcp", ":1234")
    if err != nil {
        log.Fatal("ListenTCP error:", err)
    }

    clientChan := make(chan *rpc.Client)

    go func() {
        for {
            conn, err := listener.Accept()
            if err != nil {
                log.Fatal("Accept error:", err)
            }

            clientChan <- rpc.NewClient(conn)
        }
    }()

    doClientWork(clientChan)
}

Cuando se establece cada enlace, el objeto de cliente RPC se construye basándose en el enlace de red y se envía a la canalización clientChan.

La operación del cliente para ejecutar la llamada RPC se completa en la función doClientWork:

func doClientWork(clientChan <-chan *rpc.Client) {
    client := <-clientChan
    defer client.Close()

    var reply string
    err = client.Call("HelloService.Hello", "hello", &reply)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(reply)
}

Primero, obtenga un objeto de cliente RPC de la canalización y use la declaración defer para especificar que el cliente se cierra antes de que salga la función. Luego, realice llamadas RPC normales.

Supongo que te gusta

Origin blog.csdn.net/qq_32198277/article/details/85989607
Recomendado
Clasificación