golangのgrpc双方向

クライアントがサーバーにメッセージを送信する任意の時点で達成することができgrpc双方向モードを使用して、サーバーにも、もはや、いつでもクライアントにメッセージを送信しない質問と回答モードすることができます。

grpc_stream / hellowoldstream / helloworldstream.proto

構文=「proto3」パッケージPB; 

メッセージHelloRequest { 
  文字列名 = 1 
} 

メッセージHelloResponse { 
  文字列メッセージ = 1 
} 

// + 
メッセージClientStream { 
    バイトストリーム = 1 
} 
メッセージServerStream { 
    バイトストリーム = 1 
} 
サービスHelloService { 
  RPCのsayHello(HelloRequest)リターン(HelloResponse){} 

  RPCチャット(ストリームClientStream)戻る(ストリームServerStream){} 
}

protoc --go_out =プラグイン= grpc :. helloworldstream.proto生成helloworldstream.pb.go

 

grpc_stream / server_stream.go

パッケージメイン

インポート "コンテキスト" 
    "FMT" 
    "IO" 
    "ネット" 
    "のStrConv" 
    "時間" 

    PB "github.com/mypractise/grpc/grpc_stream/helloworldstream" 
    "google.golang.org/grpcは" 

{HelloService構造体を入力します
} 

FUNC(HS * HelloService)のsayHello(CTX context.Context、REQ * pb.HelloRequest)(* pb.HelloResponse、エラー){
     リターン&pb.HelloResponse {メッセージ:fmt.Sprintf( "你好、%sの" 、REQ。ユーザー名)}、nilの
} 

// ++++++++++++++++++++++++++++++++ 
FUNC(* HSは、 HelloService)チャット(CONN pb.HelloService_ChatServer)エラー{
    FUNC(){行く
        私はVARをint型 = 100
         { 
            time.Sleep( 2 * time.Second)
            conn.Send( []:&pb.ServerStream {ストリームバイト( "サーバ送信I:" + strconv.Itoa(I))}を)
            私は ++ 
        } 
    ()} 

    のため{ 
        time.Sleep( 2 * time.Second)
        ERR、ストリーム: = conn.Recv()
         もし ERR == io.EOF {
             リターンゼロ
        } 
        なら!ERR = ゼロ{
             戻りERR
        } 
        fmt.Println( "サーバーRECV:" 、文字列(stream.Stream))
         // fmt.Println( "クライアントからの受信:"、stream.Stream)

    } 

    の戻りはnil 
} 

// +++++++++ +++++++++++ 

FUNCメイン(){ 
    ERR、LIS: = net.Listen( "TCP"、 ":6001" であれば!ERR = nilの{ 
        fmt.Println(err.Error())
        リターン
    } 
    S: = grpc.NewServer()
    pb.RegisterHelloServiceServer(S、 HelloService {})
    FUNC(){行く
        s.Serve(LIS)を
    }()
    fmt.Println(s.GetServiceInfo())
    を選択し、{} 
}

FUNCのnewBytes(... バイト)[] バイトは{
     返すA 
}

 

 

grpc_stream / client_stream.go

パッケージメイン

インポート "コンテキスト" 
    "FMT" 
    "IO" 
    "のStrConv" 

    "時間" 

    PB "github.com/mypractise/grpc/grpc_stream/helloworldstream" 
    "google.golang.org/grpc" 

主FUNC(){ 
    CONN、 E: = grpc.Dial( "ローカルホスト:6001" 、grpc.WithInsecure())
     であれば、E =!ゼロ{ 
        fmt.Println(e.Error())
        リターン
    } 
    延期はconn.close()
    C: = pb.NewHelloServiceClient( CONN)
     //  // 挨拶
     //R、E:= c.SayHello(context.Background()、&pb.HelloRequest {ユーザー名: "FT"})
     // !もしE = nilの{
     //      fmt.Println(e.Error())
     //      リターン
     / / }
     // fmt.Println(r.Message)

    // ++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++
     // チャット 
    chatClilent、E:= c.Chat(コンテキストを。背景())
     であれば E!= nilの{ 
        fmt.Println(e.Error())
        のリターンは
    } 
    FUNCを行く(){ 
        のための{ 
            time.Sleep( 3 * time.Second)
            ストリーム、E: =chatClilent.Recv()
             もし E == io.EOF { 
                fmt.Println( "EOF" リターン
            } 
            であれば、E =!ゼロ{ 
                fmt.Println( "----- ERR:" 、E)
                 リターン
            } 
            fmt.Println( "クライアントRECV:" 、文字列(stream.Stream))
        } 
    }()

    (FUNC行く){ 
        I: = 0
         のための{ 
            time.Sleep( 3 * time.Second)
            chatClilent.Send(&pb.ClientStream {ストリーム:[]バイト( "クライアント送信I:" + strconv.Itoa(I))})
            私は ++ 
        } 
    }()
    {を選択し
    た場合、<-time.After(20 * time.Second):
    } 
} 

FUNCのnewBytesを(... バイト)[] バイト{
     戻り
}

 

おすすめ

転載: www.cnblogs.com/chaselogs/p/11776250.html