.NET平台gRPC对接StarLink路由器C#开发问题求助
新增信息:
全网检索后未找到任何StarLink的C#语言对接示例,因此将当前调试内容完整发布,希望能为有同类需求的开发者提供参考,也欢迎大家共同贡献完善方案。
编写的Proto文件(部分)
采纳了Yuri提供的方向建议,非常感谢。调试过程中使用相关工具获取了很多信息,但C#侧的代码实现始终卡住。本人是资深VB.NET开发者,虽有不少C#开发经验,但并不算精通,很可能遗漏了非常基础的实现要点,任何相关思路都非常有价值。受论坛发帖字符数限制,无法发布完整的proto文件,以下为包含消息定义的核心片段,如有需要可以补充更多内容:
syntax = "proto3"; option csharp_namespace = "SpaceX.API.Device"; package SpaceX.API.Device; service Device { //rpc Handle (.SpaceX.API.Device.Request) returns (.SpaceX.API.Device.Response) {} //rpc Stream (stream .SpaceX.API.Device.ToDevice) returns (stream .SpaceX.API.Device.FromDevice) {} rpc Handle (Request) returns (Response); rpc Stream (Request) returns (Response); } message ToDevice { string message = 1; } message Request { uint64 id = 1; string target_id = 13; uint64 epoch_id = 14; oneof request { SignedData signed_request = 15; RebootRequest reboot = 1001; SpeedTestRequest speed_test = 1003; GetStatusRequest get_status = 1004; AuthenticateRequest authenticate = 1005; GetNextIdRequest get_next_id = 1006; GetHistoryRequest get_history = 1007; GetDeviceInfoRequest get_device_info = 1008; GetPingRequest get_ping = 1009; SetTrustedKeysRequest set_trusted_keys = 1010; FactoryResetRequest factory_reset = 1011; GetLogRequest get_log = 1012; SetSkuRequest set_sku = 1013; UpdateRequest update = 1014; GetNetworkInterfacesRequest get_network_interfaces = 1015; PingHostRequest ping_host = 1016; GetLocationRequest get_location = 1017; EnableFlowRequest enable_flow = 1018; GetHeapDumpRequest get_heap_dump = 1019; RestartControlRequest restart_control = 1020; FuseRequest fuse = 1021; GetPersistentStatsRequest get_persistent_stats = 1022; GetConnectionsRequest get_connections = 1023; FlushTelemRequest flush_telem = 1026; StartSpeedtestRequest start_speedtest = 1027; GetSpeedtestStatusRequest get_speedtest_status = 1028; ReportClientSpeedtestRequest report_client_speedtest = 1029; InitiateRemoteSshRequest initiate_remote_ssh = 1030; SelfTestRequest self_test = 1031; SetTestModeRequest set_test_mode = 1032; DishStowRequest dish_stow = 2002; DishGetContextRequest dish_get_context = 2003; DishSetEmcRequest dish_set_emc = 2007; DishGetObstructionMapRequest dish_get_obstruction_map = 2008; DishGetEmcRequest dish_get_emc = 2009; DishSetConfigRequest dish_set_config = 2010; DishGetConfigRequest dish_get_config = 2011; StartDishSelfTestRequest start_dish_self_test = 2012; WifiSetConfigRequest wifi_set_config = 3001; WifiGetClientsRequest wifi_get_clients = 3002; WifiSetupRequest wifi_setup = 3003; WifiGetPingMetricsRequest wifi_get_ping_metrics = 3007; WifiGetDiagnosticsRequest wifi_get_diagnostics = 3008; WifiGetConfigRequest wifi_get_config = 3009; WifiSetMeshDeviceTrustRequest wifi_set_mesh_device_trust = 3012; WifiSetMeshConfigRequest wifi_set_mesh_config = 3013; WifiGetClientHistoryRequest wifi_get_client_history = 3015; TransceiverIFLoopbackTestRequest transceiver_if_loopback_test = 4001; TransceiverGetStatusRequest transceiver_get_status = 4003; TransceiverGetTelemetryRequest transceiver_get_telemetry = 4004; } reserved 1025, 3011, 3014; } message SignedData { bytes data = 1; bytes signature = 2; }
当前C#代码实现情况
参考微软官方示例以及其他公开的gRPC样例尝试了多种实现方式,始终无法调通,目前没有解决思路。任何相关的指导都非常有价值,也能为其他寻找C#实现方案的开发者提供帮助。代码中保留了调试过程中的注释内容,目前主要希望实现三个目标,其中一个已有进展:
实现目标
- 使用Server Reflection实现服务发现:基于dot-net grpc库基本完成了该功能。
- 枚举服务下的所有可用方法,支持在StarLink未公开官方proto schema、接口可能随时无预警变更的场景下,校验或自动生成新的.proto文件。
- 成功调用任意一个可用的设备方法:尝试调用GetDeviceInfoRequest接口,但始终无法正确构造请求消息,使用gRPCurl工具也未调试成功。可以正常运行微软官方提供的基础gRPC服务示例,但StarLink的接口逻辑更复杂,调用时持续出现各类报错。
再次感谢大家提供的任何思路或协助。
C#测试代码文件
using System; using System.Diagnostics; using System.Threading.Tasks; using Grpc.Core; using Grpc.Net.Client; using Grpc.Reflection.V1Alpha; using ServerReflectionClient = Grpc.Reflection.V1Alpha.ServerReflection.ServerReflectionClient; using SpaceX.API.Device; public class Program { static async Task Main(string[] args) { //SETUP CHANNEL AND CLIENT using var channel = GrpcChannel.ForAddress("http://192.168.100.1:9200"); var client = new ServerReflectionClient(channel); var StarLinkClient = new Device.DeviceClient(channel); //using var call = StarLinkClient.StreamAsync(new ToDevice { Request = GetDeviceInfoRequest }); //await foreach (var response in call.ResponseStream.ReadAllAsync()) //var request = Device.GetDeviceInfoRequest; //var reply = await StarLinkClient.HandleAsync( // new Request {"getDeviceInfo" : {} }); //Console.WriteLine(reply.Message); //=============================================SERVER REFLECTION============================================================= Console.WriteLine("Calling reflection service:"); var response = await SingleRequestAsync(client, new ServerReflectionRequest { ListServices = "" // Get all services }); Console.WriteLine("Services:"); foreach (var item in response.ListServicesResponse.Service) { Console.WriteLine("- " + item.Name); Console.WriteLine(); var StarLink = item.Name; //Console.WriteLine(StarLink.getStatus()); } //=============================================SERVER REFLECTION============================================================= Console.WriteLine("Press any key to exit..."); Console.ReadKey(); } void setupchannel() { } private static Task SingleRequestAsync(ServerReflectionClient client, Metadata metadata) { throw new NotImplementedException(); } private static async Task<ServerReflectionResponse> SingleRequestAsync(ServerReflectionClient client, ServerReflectionRequest request) { using var call = client.ServerReflectionInfo(); await call.RequestStream.WriteAsync(request); Debug.Assert(await call.ResponseStream.MoveNext()); var response = call.ResponseStream.Current; await call.RequestStream.CompleteAsync(); return response; } }
再次提前感谢所有愿意提供协助的开发者,希望本次分享的内容也能帮到其他有同类需求的人。
内容的提问来源于stack exchange,提问作者nathan
相关产品推荐
相关产品推荐

