起因
因为鱼做DCIM系统需要机器人在群内输出日志调试的需求,我就把原来给某群写的机器人Shrink改了改。
而且鱼还点名了我提供的API通过gRPC调用,所以我就去哔哩哔哩搜了一下gRPC的概念,顺带找了一下可用的nuget包。
使用
首先我在原Shrink的解决方案nuget中导入了Grpc.Tools Grpc.core Grpc.Net.Client Google.Protobuf
。后来得知有一些更新的包可以用,我现在使用的已经没有正常维护了。
然后是定义proto文件,定义好命名空间以及Service,我放了loglevel、msgtype、data等字段,定义了一个SendData方法供远程发送需要打印的日志。
同时在解决方案中添加以下内容,确保Build时能够生成相应的文件。
<Protobuf Include="proto\apiService.proto" GrpcServices="Server" />
之后就可以在我的Shrink这里实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| using Debugger; using Grpc.Core; using Shrink.Logger;
namespace Shrink.Service;
public class ApiService : APIService.APIServiceBase { private static readonly Lazy<ApiService> _instance = new(() => new ApiService()); public static ApiService Instance => _instance.Value;
public override Task<DataResponse> SendData(DataRequest request, ServerCallContext context) { LogManager.Instance.LogChain.LogMessage(request.Data, request.Event, request.LogLevel, request.MsgType, request.Uin, request.Text); var response = new DataResponse(); if (LogManager.Instance.IsSent) { response.Message = $"已发送至: {request.Uin}。"; response.Success = true; } else { response.Message = "未发送,可能的原因是信息被设置为忽略或出现其他问题。"; response.Success = false; }
LogManager.Instance.IsSent = false; return Task.FromResult(response); } }
|
远端也足够简单,复制一下proto,设置好解决方案
<Protobuf Include="API/service.proto" GrpcServices="Client" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| using Debugger; using Grpc.Net.Client;
namespace GrpcClient { internal static class Program { private static async Task Main() { using var channel = GrpcChannel.ForAddress("https://localhost:5001"); var client = new APIService.APIServiceClient(channel);
var request = new DataRequest { LogLevel = LogLevel.Info, MsgType = MsgType.Public, Uin = 954600523, Data = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Event = "TestEvent", Text = "逸一时误一世" };
Console.WriteLine("向服务端发送请求..."); var response = await client.SendDataAsync(request);
Console.WriteLine($"收到服务端响应:{response.Message}, Success: {response.Success}"); } } }
|
然后Shrink启动等待远程的请求即可。
总结
gRPC使用起来十分简单,通过一个proto文件即可实现数据的序列化和反序列化处理,而且还能够跨语言使用。
如果应用在Unity,那也能手搓一个网络框架出来。