.net core实践系列之短信服务-Sikiro.SMS.Bus服务的实现

前言

前两篇《.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现》、《.net core实践系列之短信服务-Api的SDK的实现与测试》分别讲解了API提供服务与SDK调用API实现。

本篇会继续讲解Sikiro.SMS.Bus的服务实现,此实现是基于开篇的架构设计的拥有调度任务服务,在最后一篇会给架构优化的,抛弃了调度任务服务使用MQ代替。

源码地址:https://github.com/SkyChenSky/Sikiro.SMS

功能流程描述

如上图所示,消费者订阅到消费消息后,通过工厂类创建出对应的短信运营商类,通过调用Send方法进行对短信运营商服务请求,得到响应结果后对持久化数据的状态进行更新。假如中途遇到异常则回滚数据状态,等待下一次调度任务进行调度。

下面是MainService的代码示例:

  public class MainService : IMicroService
    {
        private readonly IBus _bus;
        private readonly SmsService _smsService;

        public MainService(IBus bus, SmsService smsService)
        {
            _bus = bus;
            _smsService = smsService;
        }

        public void Start()
        {
            Console.WriteLine("I started");

            _bus.Subscribe<SmsQueueModel>("", msg =>
            {
                try
                {
                    _smsService.Send(msg.MapTo<SmsQueueModel, SmsModel>());
                }
                catch (Exception e)
                {
                    _smsService.RollBack();
                    e.WriteToFile();
                }
            });
        }

        public void Stop()
        {
            ConfigServer.Container?.Dispose();
            Console.WriteLine("I stopped");
        }
    }

下面是SmsService的代码示例:

public void Send(SmsModel item)
        {
            Sms = item;

            var isSuccess = _smsFactory.Create(item.Type).SendSMS(item.Mobiles, item.Content, _configuration["Sms:SignName"]);
            if (isSuccess)
                Success(item.Id);
            else
                Fail(item.Id);
        }

        public void RollBack()
        {
            RollBack(Sms.Id);
        }

        public void RollBack(string id)
        {
            _mongoProxy.Update<SmsModel>(a => a.Id == id,
                a => new SmsModel { Status = SmsEnums.SmsStatus.待处理 });
        }

        private void Success(string id)
        {
            _mongoProxy.Update<SmsModel>(a => a.Id == id,
                a => new SmsModel { Status = SmsEnums.SmsStatus.成功 });
        }

        private void Fail(string id)
        {
            _mongoProxy.Update<SmsModel>(a => a.Id == id,
                a => new SmsModel { Status = SmsEnums.SmsStatus.失败 });
        }

组件选择

宿主框架

对于有在.Net Framework上开发Windows服务的朋友对TopShelf应该会很熟悉。

优势主要体现下面三点:

  • 基于控制台应用
  • 调试方便
  • 易于安装部署

不少人认为,Core的出现,跨平台加命令行的优势,可以轻易的在Linux部署守护进程。难道还需要宿主框架?

然而并不是所有公司选用了Linux系统的服务器,就像我们公司。既然使用了Windows服务器应该将他部署为Windows服务使其可视化方便管理,另外没有等待到TopShelf的Core版本,因此我选择了另一款宿主框架:PeterKottas.DotNetCore.WindowsService

PeterKottas.DotNetCore.WindowsService

源码地址:https://github.com/PeterKottas/DotNetCore.WindowsService

虽然比不起TopShelf的功能强大,但是对于一般的需求使用基本满足,而且使用方式也与TopShelf相似。下面是使用示例:

class Program
    {
        static void Main(string[] args)
        {
            ServiceRunner<MainService>.Run(config =>
            {
                config.SetServiceInfo();

                config.Service(serviceConfig =>
                {
                    serviceConfig.UseAutofac();
                    serviceConfig.UseServiceFactory();

                    serviceConfig.OnStart((service, extraParams) =>
                    {
                        service.Start();
                    });
                        
                    serviceConfig.OnStop(service =>
                    {
                        service.Stop();
                    });

                    serviceConfig.OnError(Console.WriteLine);
                });
            });
        }
    }

下面是安装卸载的命令示例:“

dotnet Sikiro.SMS.BUS.dll action:install
dotnet Sikiro.SMS.BUS.dll action:uninstall

结尾

这里就是本篇的内容,相比于前面几篇的内容相对少点,如果有中途来看的朋友可以把《.net core实践系列之短信服务-架构设计》看看作个补充,如果有任何建议,可以在下方评论反馈给我。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

用U盘或移动硬盘安装Windows7 (超简单制作Win7安装U盘方法)

本文来源:http://www.iplaysoft.com/win7-usb-dvd-download-tool.html

2.3K1
来自专栏FreeBuf

Powershell最佳安全实践

? 写在前面的话 其实很早之前,攻击者就已经开始使用合法工具来渗透目标网络并实现横向攻击了。理由很简单:使用合法工具可以降低被检测到的几率,而且进过授权的工具...

58310
来自专栏逍遥剑客的游戏开发

C#脚本实践(一)

2294
来自专栏草根博客站长有话说

命令行界面 (CLI)、终端 (Terminal)、Shell、TTY,这些都是啥意思?

为什么突然想写这样一篇文章呢?其实是因为在最近计划发布的一篇关于 WSL (Windows Subsystem for Linux) 的博文中,我打算对终端模拟...

1796
来自专栏张善友的专栏

WinRT:WebAuthenticationBroker For OAuth认证

之前开发过QQ互联的OAuth 的.NET/Mono/Windows Phone SDK,具体可以 QQ互联OAuth2.0 .NET SDK 发布以及网站QQ...

2085
来自专栏逸鹏说道

专业上的常用的工具和类库集

Visual Studio 2013 扩展 CodeMaid: 可快速整理代码文件,清理不必要的代码和杂乱的格式。并在开发时实时提供代码复杂度的报告,以便帮助开...

3159
来自专栏自由而无用的灵魂的碎碎念

让WMP12成为万能播放器

Windows 7下的WMP12还是非常优秀的,最新卸载掉本机的KM PLAYER、XMP、暴风后,一直想使用WMP来一统本地视频播放,索性今天找到了:Wind...

1093
来自专栏程序员的知识天地

10 款最好的 Python 开发编辑器

Python 非常易学,强大的编程语言。Python 包括高效高级的数据结构,提供简单且高效的面向对象编程。

2081
来自专栏哲学驱动设计

Rafy 领域实体框架示例(1) - 转换传统三层应用程序

Rafy 领域实体框架发布后,虽然有帮助文档,许多朋友还是反映学习起来比较复杂,希望能开发一个示例程序,展示如何使用 Rafy 领域实体框架所以,本文通过使用 ...

2105
来自专栏张善友的专栏

.NET 4.5.1 预览版新特性

上个月的微软Build大会上宣布了.NET 4.5.1的推出,Heydarian的这个演讲题为“.NET开发中的新内容”,涵盖了.NET Framework中一...

1956

扫码关注云+社区

领取腾讯云代金券