Orleans在.net core的开发
Goods 服务 启动
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Entity; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Orleans; using Orleans.Configuration; using Orleans.Hosting; using Orleans.Serialization; namespace Order { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); int silePort = 11113; int gatewayPort = 30000; int mainSiloPort = 11111; //启动Host StartAsyncHost(silePort, gatewayPort, mainSiloPort, services); //启动本地服务 StartAsyncClient(mainSiloPort, gatewayPort, silePort, services).Wait(); services.ServerInjectionADD(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseMvc(); } /// <summary> /// 在本地启动一个Host /// </summary> /// <returns></returns> async Task<ISiloHost> StartAsyncHost(int silePort, int gatewayPort, int mainSiloPort, IServiceCollection servicesCollection) { var builder = new SiloHostBuilder() .Configure<SerializationProviderOptions>(d => { d.SerializationProviders.Add(typeof(ProtobufSerializer).GetTypeInfo()); d.FallbackSerializationProvider = typeof(ProtobufSerializer).GetTypeInfo(); }) .UseDevelopmentClustering(new IPEndPoint(IPAddress.Loopback, mainSiloPort)) .ConfigureEndpoints(siloPort: silePort, gatewayPort: gatewayPort) .Configure<ClusterOptions>(options => { //ClusterId为集群名称 相同的名称才能被分配到一个集群中 options.ClusterId = "dev"; //当前服务的名称 options.ServiceId = "GoodsServer"; }) .AddStartupTask( async (IServiceProvider services, CancellationToken cancellation) => { var grainFactory = services.GetRequiredService<IGrainFactory>(); //var grain = grainFactory.GetGrain<IMyGrain>(0); //注册本机服务 }) //注入打印消息的入口 .ConfigureLogging(logging => logging.AddConsole()); //进行构建 var host = builder.Build(); //启动服务 await host.StartAsync(); Console.WriteLine("服务启动成功"); return host; } async Task StartAsyncClient(int mainSiloProt, int gatewayProt, int siloProt, IServiceCollection servicesCollection) { IClusterClient client = new ClientBuilder() .Configure<SerializationProviderOptions>(d => { d.SerializationProviders.Add(typeof(ProtobufSerializer).GetTypeInfo()); d.FallbackSerializationProvider = typeof(ProtobufSerializer).GetTypeInfo(); }) //与主简仓进行连接 .UseStaticClustering(new IPEndPoint[] { new IPEndPoint(GetInternalIp(), gatewayProt) }) .Configure<ClusterOptions>(options => { options.ClusterId = "dev"; options.ServiceId = "GoodsClient"; }) //配置刷新简仓的时间 一般来说不会这么短 //.Configure<GatewayOptions>(d => d.GatewayListRefreshPeriod = TimeSpan.FromSeconds(5)) .ConfigureLogging(logging => logging.AddConsole()).Build(); await client.Connect(); Console.WriteLine("Orleans客户端已经启动"); servicesCollection.AddSingleton(client); } public static IPAddress GetInternalIp() { IPHostEntry myEntry = Dns.GetHostEntry(Dns.GetHostName()); return myEntry.AddressList.FirstOrDefault(e => e.AddressFamily.ToString().Equals("InterNetwork")); } } }
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Orleans; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Order { /// <summary> /// 注入本地服务 /// </summary> public static class ServerInjection { /// <summary> /// 服务注入 在最后使用 /// </summary> /// <param name="services"></param> public static void ServerInjectionADD(this IServiceCollection services) { services.AddSingleton<IShoppingRecord.IShoppingRecord, OrderServer.OrderServer>(); //引用对象留在最后 serviceProvider = services.BuildServiceProvider(); } public static ServiceProvider serviceProvider { get; set; } public static T GetServer<T>(this Controller controller) where T:class, IGrainWithIntegerKey { var TService = serviceProvider.GetService<T>(); if (TService==null) { var client = serviceProvider.GetService<IClusterClient>(); if (client==null) { throw new Exception("客户端没有启动 或者没有被注入"); } TService = client.GetGrain<T>(0); if (TService==null) { throw new Exception("没有找到该类型" + TService.GetType()); } return TService; } return TService; } } }
截图
Goods服务
Order服务
GitHub地址:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!