创建Wpf库项目Hello、Wpf项目HelloServer、Wpf项目HelloClient
-
库项目Hello中引入Nuget
Grpc、Grpc.Tools
-
Wpf项目Client、Server分别引入Nuget
Grpc
- 编写proto
syntax = "proto3";
option csharp_namespace = "greeter.hello";
service Greeter{
rpc SayHello (HelloRequest) returns (HelloResponse);
rpc SayWorld (HelloRequest) returns (HelloResponse);
}
message HelloRequest{
string name = 1;
}
message HelloResponse{
string message = 1;
}
- 编译proto
..\packages\Grpc.Tools.2.27.0\tools\windows_x64\protoc.exe -I.\Proto\ --csharp_out ./ --grpc_out ./ --plugin=protoc-gen-grpc=..\packages\Grpc.Tools.2.27.0\tools\windows_x64\grpc_csharp_plugin.exe .\Proto\routine.proto
- Server实现gRpcService
using System.Threading.Tasks;
using greeter.hello;
using Grpc.Core;
namespace HelloServer.gRpcService
{
class GreeterService: Greeter.GreeterBase
{
public override Task<HelloResponse> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloResponse() {Message = "server responsed: " + "hello " + request.Name});
}
public override Task<HelloResponse> SayWorld(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloResponse() {Message = "server responsed: " + request.Name + " world"});
}
}
}
- 创建服务端
using System.ComponentModel;
using System.Windows;
using greeter.hello;
using Grpc.Core;
using HelloServer.gRpcService;
namespace HelloServer
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private Server server;
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
server = new Server()
{
Services = { Greeter.BindService(new GreeterService())},
Ports = { new ServerPort("localhost", 8099, ServerCredentials.Insecure)}
};
server.Start();
}
protected override void OnClosing(CancelEventArgs e)
{
server?.ShutdownAsync().Wait();
base.OnClosing(e);
}
}
}
- 创建客户端
using System.ComponentModel;
using System.Windows;
using greeter.hello;
using Grpc.Core;
namespace HelloClient
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private Channel channel;
private Greeter.GreeterClient client;
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
channel = new Channel("localhost", 8099, ChannelCredentials.Insecure);
client = new Greeter.GreeterClient(channel);
var response = client.SayHello(new HelloRequest() { Name = "Link Sun" });
lvResponse.Items.Add(response);
}
private void TbHello_OnClick(object sender, RoutedEventArgs e)
{
string name = tbName.Text;
var response = client.SayHello(new HelloRequest() { Name = name });
lvResponse.Items.Add(response);
}
private void TbWorld_OnClick(object sender, RoutedEventArgs e)
{
string name = tbName.Text;
var response = client.SayWorld(new HelloRequest() { Name = name });
lvResponse.Items.Add(response);
}
protected override void OnClosing(CancelEventArgs e)
{
channel?.ShutdownAsync().Wait();
base.OnClosing(e);
}
}
}