欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

surging 社区版本支持.net core 3.1

程序员文章站 2022-04-06 10:13:54
简介 surging 经过两年多的研发,微服务引擎已经略有雏形,也承蒙各位的厚爱, GitHub上收获了将近2800星,fork 811,付费用户企业也有十几家,还有咨询培训, 在2020年,我们将依靠社区的力量,去完善社区版本,更会花更多的精力去维护好付费用户,大家一起把surging 的社区建设 ......

简介

surging 经过两年多的研发,微服务引擎已经略有雏形,也承蒙各位的厚爱, github上收获了将近2800星,fork 811,付费用户企业也有十几家,还有咨询培训,

在2020年,我们将依靠社区的力量,去完善社区版本,更会花更多的精力去维护好付费用户,大家一起把surging 的社区建设好,还有十几天就要过年,大家可以加入surging唯一官方群:615562965, 过年的时候会和往常一样发红包,而且不少哦。让我们过年狂欢起来。

 surging 将会有自己的官方站,作者正在用vuepress进行研发,在不久的日子将会和大家见面

新功能简述

1.grpc协议支持:

添加接口,将servercallcontext参数的默认值设置为null。 代码如下:

 

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);
    }
}

添加greeterbehavior,代码如下

using greet;
using surging.core.cplatform.ioc;

namespace surging.modules.common.greeterservices
{
    public  partial class greeterbehavior : greeter.greeterbase,iservicebehavior
    {
        
    }
}

 添加业务代码,代码如下:

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调用,代码如下

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.支持workservice后台托管守护程序

引擎支持workservice后台服务,可以支持rpc远程调用开启,关闭,添加任务处理,代码如下:

添加接口代码如下:

   [servicebundle("background/{service}")]
    public interface iworkservice : iservicekey
    {
        task<bool> addwork(message message);

         task startasync();

        task stopasync();
    }

然后需要继承backgroundservicebehavior,而且服务的生命周期设置为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 = logger;
            _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.支持特性验证

支持接口特性验证,代码如下

   [servicebundle("api/{service}/{method}")]
    //[servicebundle("api/{service}")]
    //[servicebundle("api/{service}/{method}/test")]
    //[servicebundle("api/{service}/{method}/test",false)]
    public interface iuserservice: iservicekey
    {
        /// <summary>
        /// 获取用户姓名
        /// </summary>
        /// <param name="id">用户编号</param>
        /// <returns></returns>
        [serviceroute("{id}")]
        task<string> getusername([validate] [range(1, 10, errormessage = "只能为1到10")] int id);


 /// <summary>
        /// 获取用户
        /// </summary>
        /// <param name="user">用户模型</param>
        /// <returns></returns>
        [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);
          

}

支持模型特性验证,接口方法一定要添加 [validate]特性,要不然不会进行验证,代码如下

   [protocontract]
    public class usermodel
    {

        [protomember(1)]
        [cachekey(1)]
        public int userid { get; set; }

        [protomember(2)]
        public string name { get; set; }

        [protomember(3)]
        [range(0, 150, errormessage = "年龄只能在0到150岁之间")]
        public int age { get; set; }

        [protomember(4)]
        [range(0, 1, errormessage = "性别只能选男或女")]
        public sex sex { get; set; }

    }

总结

开源不易,请大家多多支持