クライアントがサーバーにメッセージを送信する任意の時点で達成することができ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を(... バイト)[] バイト{ 戻り }