标签:turn ddr hand rip zook mic 标题 == datetime
增加两个静态方法SayHello和SayByebye,用于提供远程调用,超级简单,不解释。
public static class Say { public static string SayHello(string content) { return $"hello {content}"; } public static string SayByebye(string content) { return $"byebye {content}"; } }
在我们原来的ChannelRead函数中,将原有的Echo回路传输,直接替换成如下内容。
1 public override void ChannelRead(IChannelHandlerContext context, object message) 2 { 3 if (message is IByteBuffer buffer) 4 { 5 Console.WriteLine($"message length is {buffer.Capacity}"); 6 var obj = JsonConvert.DeserializeObject<Dictionary<string, string>>(buffer.ToString(Encoding.UTF8).Replace(")", "")); // (1) 7 8 byte[] msg = null; 9 if (obj["func"].Contains("sayHello")) // (2) 10 { 11 msg = Encoding.UTF8.GetBytes(Say.SayHello(json["username"])); 12 } 13 14 if (obj["func"].Contains("sayByebye")) // (2) 15 { 16 msg = Encoding.UTF8.GetBytes(Say.SayByebye(json["username"])); 17 } 18 19 if (msg == null) return; 20 // 设置Buffer大小 21 var b = Unpooled.Buffer(msg.Length, msg.Length); // (3) 22 IByteBuffer byteBuffer = b.WriteBytes(msg); // (4) 23 context.WriteAsync(byteBuffer); // (5) 24 } 25 }
我们将上一个demo中的EchoClientHandler做如下修改,以完成一个简单的请求
1 public EchoClientHandler() 2 { 3 var hello = new Dictionary<string, string> // (1) 4 { 5 {"func", "sayHello"}, 6 {"username", "stevelee"} 7 }; 8 SendMessage(ToStream(JsonConvert.SerializeObject(hello))); 9 } 10 11 private byte[] ToStream(string msg) 12 { 13 Console.WriteLine($"string length is {msg.Length}"); 14 using (var stream = new MemoryStream()) // (2) 15 { 16 Serializer.Serialize(stream, msg); 17 return stream.ToArray(); 18 } 19 } 20 21 private void SendMessage(byte[] msg) 22 { 23 Console.WriteLine($"byte length is {msg.Length}"); 24 _initialMessage = Unpooled.Buffer(msg.Length, msg.Length); 25 _initialMessage.WriteBytes(msg); // (3) 26 }
由于在客户端明文标注了使用sayHello这个方法,客户端会收到服务端返回的"hello stevelee"。
这样一个最简单的RPC远程调用就完成了(其实上一篇就也属于RPC,只是这里用方法和过滤来指定调用)。
先看看接口定义了些什么:
1 /// <summary> 2 /// 接口UserService的定义 3 /// </summary> 4 [RpcTagBundle] 5 public interface IUserService 6 { 7 Task<string> GetUserName(int id); 8 9 Task<int> GetUserId(string userName); 10 11 Task<DateTime> GetUserLastSignInTime(int id); 12 13 Task<UserModel> GetUser(int id); 14 15 Task<bool> Update(int id, UserModel model); 16 17 Task<IDictionary<string, string>> GetDictionary(); 18 19 Task Try(); 20 21 Task TryThrowException(); 22 }
1 [ProtoContract] 2 public class UserModel 3 { 4 [ProtoMember(1)] public string Name { get; set; } 5 6 [ProtoMember(2)] public int Age { get; set; } 7 }
上面有两个不一样的标记,也是protobuf-net中独有的特性。
接下来继续服务端的代码
1 static void Main() 2 { 3 var bTime = DateTime.Now; 4 5 // 实现自动装配 6 var serviceCollection = new ServiceCollection(); 7 { 8 serviceCollection 9 .AddLogging() 10 .AddRpcCore() 11 .AddService() 12 .UseSharedFileRouteManager("d:\\routes.txt") 13 .UseDotNettyTransport(); 14 15 // ** 注入本地测试类 16 serviceCollection.AddSingleton<IUserService, UserServiceImpl>(); 17 } 18 19 // 构建当前容器 20 var buildServiceProvider = serviceCollection.BuildServiceProvider(); 21 22 // 获取服务管理实体类 23 var serviceEntryManager = buildServiceProvider.GetRequiredService<IServiceEntryManager>(); 24 var addressDescriptors = serviceEntryManager.GetEntries().Select(i => new ServiceRoute 25 { 26 Address = new[] 27 { 28 new IpAddressModel {Ip = "127.0.0.1", Port = 9881} 29 }, 30 ServiceDescriptor = i.Descriptor 31 }); 32 var serviceRouteManager = buildServiceProvider.GetRequiredService<IServiceRouteManager>(); 33 serviceRouteManager.SetRoutesAsync(addressDescriptors).Wait(); 34 35 // 构建内部日志处理 36 buildServiceProvider.GetRequiredService<ILoggerFactory>().AddConsole((console, logLevel) => (int) logLevel >= 0); 37 38 // 获取服务宿主 39 var serviceHost = buildServiceProvider.GetRequiredService<IServiceHost>(); 40 41 Task.Factory.StartNew(async () => 42 { 43 //启动主机 44 await serviceHost.StartAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9881)); 45 }); 46 47 Console.ReadLine(); 48 }
1 static void Main() 2 { 3 var serviceCollection = new ServiceCollection(); 4 { 5 serviceCollection 6 .AddLogging() // 添加日志 7 .AddClient() // 添加客户端 8 .UseSharedFileRouteManager(@"d:\routes.txt") // 添加共享路由 9 .UseDotNettyTransport(); // 添加DotNetty通信传输 10 } 11 12 var serviceProvider = serviceCollection.BuildServiceProvider(); 13 14 serviceProvider.GetRequiredService<ILoggerFactory>().AddConsole((console, logLevel) => (int) logLevel >= 0); 15 16 var services = serviceProvider.GetRequiredService<IServiceProxyGenerater>() 17 .GenerateProxys(new[] {typeof(IUserService)}).ToArray(); 18 19 var userService = serviceProvider.GetRequiredService<IServiceProxyFactory>().CreateProxy<IUserService>( 20 services.Single(typeof(IUserService).GetTypeInfo().IsAssignableFrom) 21 ); 22 23 while (true) 24 { 25 Task.Run(async () => 26 { 27 Console.WriteLine($"userService.GetUserName:{await userService.GetUserName(1)}"); 28 Console.WriteLine($"userService.GetUserId:{await userService.GetUserId("rabbit")}"); 29 Console.WriteLine($"userService.GetUserLastSignInTime:{await userService.GetUserLastSignInTime(1)}"); 30 var user = await userService.GetUser(1); 31 Console.WriteLine($"userService.GetUser:name={user.Name},age={user.Age}"); 32 Console.WriteLine($"userService.Update:{await userService.Update(1, user)}"); 33 Console.WriteLine($"userService.GetDictionary:{(await userService.GetDictionary())["key"]}"); 34 await userService.Try(); 35 Console.WriteLine("client function completed!"); 36 }).Wait(); 37 Console.ReadKey(); 38 } 39 }
NET Core微服务之路:让我们对上一个Demo通讯进行修改,完成RPC通讯
标签:turn ddr hand rip zook mic 标题 == datetime
原文地址:https://www.cnblogs.com/SteveLee/p/9914397.html