grpc简直是如今最流行的跨平台间的通信技术。远不止.net上使用。grpc是谷歌公司推出的跨语言平台之间的通信技术。和webapi差别的是,可以使用自己的语言和另一种语言举行通信。
简单来讲就是首先使用一种Proto的协议文件,可以天生客户端和服务端两种文件。客户端和服务端可以使用任意的语言。grpc工具会将proto编译成任何一种语言。
比方说c#和java举行通讯。这时首先确认谁作server谁做client。然后使用grpc tools编译成c#类库和java的jar包,再引入到各自的项目,这时在c#引用的grpc tools天生的dll里就有proto文件中天生的方法。而java中的jar包也会有对应的方法。当然在这之前需要在proto中规定两端使用的api方法。也就是先天生proto文件约定两端之间调用的方法名称,参数,及参数类型。然后就可以完成跨语言之间的协同开辟。可以一个java server端,对应于多个差别语言的client端,如python、nodejs、c#等。也可以一个server端如rust server端,对应多个相同的客户端如php等。非常的灵活。
grpc可以说是一种非常高效的跨平台的通讯方案。由于它已经支持是http2。将来会支持基于udp的http3真正实现异步io。
下面我通过一个框架搭建的demo举行演示
1.GrpcProject项目框架
框架分为客户端和服务端,以及一些公共类库,使得框架完善
1.1 GrpcClient_Console客户端,采用控制台
通过客户端连接服务端,发送数据
主要代码实现如下- public class Program
- {
- static async Task Main(string[] args)
- {
- Channel channel = new("localhost:5099", ChannelCredentials.Insecure);
- try
- {
- Console.WriteLine("这个应用是客户端,正在连接远程服务端...");
- await channel.ConnectAsync();
- Console.WriteLine("服务端连接成功");
- Console.WriteLine("Successfully connected to the server!");
- Console.WriteLine("First name?");
- var name = Console.ReadLine();
- Console.WriteLine("Last name? ");
- var lastName = Console.ReadLine();
- var request = new CreatePersonRequest
- {
- FirstName = name,
- LastName = lastName
- };
- var client = new PeopleService.PeopleServiceClient(channel);
- var response = await client.CreatePersonAsync(request);
- Console.WriteLine($"{response.FirstName} {response.LastName} has been created " +
- $"on the server! (id = {response.Id})");
- Console.WriteLine("Press enter to close the client");
- Console.ReadLine();
- }
- catch (Exception ex)
- {
- Console.WriteLine("An error occurred: " + ex.ToString());
- Console.ReadLine();
- }
- finally
- {
- if (channel is not null)
- {
- await channel.ShutdownAsync();
- }
- }
- }
- }
复制代码 2.GrpcServer_Console服务端,采用控制台
服务端可以接送客户端发送消息,并写入数据库
主要是这三个类Program,PeopleServiceImpl,ServerDbContext
通过这三个类之间的调用,可以天生数据库,数据写入库,数据库采用sqlite
 - internal class Program
- {
- static async Task Main(string[] args)
- {
- new ServerDbContext().Database.EnsureCreated();
- Server server = new()
- {
- Ports = { new ServerPort("localhost", 5099, ServerCredentials.Insecure) },
- Services = { PeopleService.BindService(new PeopleServiceImpl()) }
- };
- try
- {
- Console.WriteLine("这应用是服务端,正在启动服务端...");
- server.Start();
- Console.WriteLine("服务端启动成功");
- Console.WriteLine("Press enter to close the server");
- Console.ReadLine();
- }
- catch (Exception ex)
- {
- Console.WriteLine("An error occurred: " + ex.ToString());
- }
- finally
- {
- if (server is not null)
- {
- await server.ShutdownAsync();
- }
- }
- }
- }
- public class PeopleServiceImpl : PeopleServiceBase
- {
- public override async Task<Person> CreatePerson(
- CreatePersonRequest request,
- ServerCallContext context)
- {
- using var ctx = new ServerDbContext();
- var dbPerson = new Person
- {
- LastName = request.LastName,
- FirstName = request.FirstName
- };
- ctx.People.Add(dbPerson);
- await ctx.SaveChangesAsync();
- return new Person
- {
- LastName = request.LastName,
- FirstName = request.FirstName,
- Id = dbPerson.Id
- };
- }
- }
- public class ServerDbContext : DbContext
- {
- public DbSet<Person> People { get; set; }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlite("Filename = data.db");
- }
- }
复制代码 3.共用类库
GrpcProtos :用于存放Proto文件
AbstractDAL :用于数据库操作抽象类
DBEntity : 存放数据库表实体
EntityMap :用于grpc通信实体与数据库实体之间相互转换的帮助类
GrpcEntity :存放grpc通信的参数实体,相应返回实体等;
4.demo启动演示
先启动服务端:
再启动客户端,如果客户端连上了服务端,效果如下
分别按指示输入:
服务端的数据库会新增people数据
到此,演示算成功,客户端与服务端成功通信,并且操作数据可以落库。
感兴趣的朋友可以访问我的gitee代码库:https://gitee.com/chenshibao/grpc-project
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |