Brief introduction
surging after two years of research and development, micro-services engine has slightly prototype, also courtesy of you for your love, on GitHub harvest nearly 2800 stars, fork 811, subscribers have more than a dozen companies, as well as consulting and training,
In 2020, we will rely on the power of the community, to improve community version, but will spend more energy to maintain good paying customers we can work together to build a community surging, there are ten days will the New Year, everyone can join the only official surging population: 615 562 965, when the New Year red envelopes will be issued as usual, but also a lot of oh. Let the New Year carnival together.
surging will have its own official station, the authors are being developed with VuePress, we will meet you in the near days
New Function Description
1.GRPC protocol support:
Add interfaces, the default value is set ServerCallContext parameter is null. code show as below:
using Greet; using Grpc.Core; using Surging.Core.CPlatform.Ioc; using Surging.Core.CPlatform.Runtime.Server.Implementation.ServiceDiscovery.Attributes; using System.Threading.Tasks; namespace Surging.IModuleServices.Common { [ServiceBundle("api/{Service}/{Method}")] public interface IGreeterService : IServiceKey { Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context=null); } }
Add GreeterBehavior, the following code
using Greet; using Surging.Core.CPlatform.Ioc; namespace Surging.Modules.Common.GreeterServices { public partial class GreeterBehavior : Greeter.GreeterBase,IServiceBehavior { } }
Add business code, the code is as follows:
using Greet; using Grpc.Core; using Surging.IModuleServices.Common; using Surging.Modules.Common.GreeterServices; using System.Threading.Tasks; namespace Surging.Modules.Common.Domain { public class GreeterService: GreeterBehavior, IGreeterService { public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) { return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } } }
GRPC client calls, the code is as follows
using Greet; using Grpc.Core; using System; namespace GrpcService1 { public class Program { public static void Main(string[] args) { var channel = new Channel("127.0.0.1", 95, ChannelCredentials.Insecure); var client = new Greeter.GreeterClient(channel); var result = client.SayHello(new HelloRequest { Name = "fanly" }); Console.WriteLine("grpc Client Call SayHello():" + result); Console.ReadKey(); } } }
2. Support WorkService background daemon hosting
WorkService engine supports back-office services, can support remote RPC call to open, close, add-tasking, as follows:
Add interface code as follows:
[ServiceBundle("Background/{Service}")] public interface IWorkService : IServiceKey { Task<bool> AddWork(Message message); Task StartAsync(); Task StopAsync(); }
Then you need to inherit BackgroundServiceBehavior , and service life cycle is set to ISingleInstance
public class WorkService : BackgroundServiceBehavior, IWorkService, ISingleInstance { private readonly ILogger<WorkService> _logger; private readonly Queue<Message> _queue = new Queue<Message>(); private readonly IServiceProxyProvider _serviceProxyProvider; private CancellationToken _token; public WorkService(ILogger<WorkService> logger, IServiceProxyProvider serviceProxyProvider) { _logger = log; _serviceProxyProvider = serviceProxyProvider; } public Task<bool> AddWork(Message message) { _queue.Enqueue(message); return Task.FromResult(true); } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { try { _token = stoppingToken; _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); _queue.TryDequeue(out Message message); if (message != null) { var result = await _serviceProxyProvider.Invoke<object>(message.Parameters, message.RoutePath, message.ServiceKey); _logger.LogInformation("Invoke Service at: {time},Invoke result:{result}", DateTimeOffset.Now, result); } if (!_token.IsCancellationRequested) await Task.Delay(1000, stoppingToken); } catch (Exception ex){ _logger.LogError("WorkService execute error, message:{message} ,trace info:{trace} ", ex.Message, ex.StackTrace); } } public async Task StartAsync() { if (_token.IsCancellationRequested) { await base.StartAsync(_token); } } public async Task StopAsync() { if (!_token.IsCancellationRequested) { await base.StopAsync(_token); } } }
3. Support characteristic verification
Support validation interface characteristics, as follows
[ServiceBundle("api/{Service}/{Method}")] //[ServiceBundle("api/{Service}")] //[ServiceBundle("api/{Service}/{Method}/test")] //[ServiceBundle("api/{Service}/{Method}/test",false)] public interface IUserService: IServiceKey { /// <Summary> /// Get user's name /// </ Summary> /// <param name = "ID"> User ID </ param> /// <Returns> </ Returns> [ServiceRoute ( " ID} { " )] The Task < String > the GetUserName ([the Validate] [the Range ( . 1 , 10 , the ErrorMessage = " only 1 to 10 " )] int ID); /// <Summary> /// Get user /// </ Summary> /// <param name = "User"> user model </ param> /// <Returns> </ Returns> [the Command (= Strategy StrategyType.Injection, Injection = @ " return new Surging.IModuleServices.Common.Models.UserModel { Name=""fanly"", Age=19 };", RequestCacheEnabled = true, InjectionNamespaces = new string[] { "Surging.IModuleServices.Common" })] [InterceptMethod(CachingMethod.Get, Key = "GetUser_id_{0}", CacheSectionType = SectionType.ddlCache, Mode = CacheTargetType.Redis, Time = 480)] [Validate] Task<UserModel> GetUser(UserModel user); }
Support characteristics model validation, add interface method must be [the Validate] properties, or else not be verified, as follows
[ProtoContract] public class UserModel { [ProtoMember ( 1 )] [CacheKey(1)] public int UserId { get; set; } [ProtoMember(2)] public string Name { get; set; } [ProtoMember ( 3 )] [The Range ( 0 , 150 , the ErrorMessage = " Age only between 0 and 150 years " )] public int Age { GET ; SET ;} [ProtoMember ( 4 )] [The Range ( 0 , . 1 , the ErrorMessage = " Gender male or female can only choose " )] public Sex Sex { GET ; SET ;} }
to sum up
Open source is not easy, please support