数据库自动备份服务,带配置,还算可以吧

  wcf虽然功能多、扩展性强但是也面临配置忒多,而且restful的功能相当怪异,并且目前没法移植。asp.net
core虽然支持webapi,但是功能也相对繁多、配置复杂。就没有一个能让码农们安安心心的写webapi,无需考虑性能、配置、甚至根据问题场景自行设计、改造等问题的方案么?

1.发布项目是出现这个错误网上找了有两种方式,

周末抽时间,编写了一个这样的工具,可以让,对数据库不了解或不熟悉的人,直接学会使用备份,省时省力,同样,我也将一份,通过脚本进行备份的,也奉献上来,

  当然不是,特别是在dnc2.0已经相当强大的此时,完全可以自行设计一套简洁、高效的webapi框架!说到自行写一套框架,很多码农们就可能会想到开发工作量难以想像,事实真的如此么?java因为开源众多,很多对mvc稍有了解的都可以拿这个拿那个拼出一个自已的mvc框架;而面对日益强大的dnc,本人觉得C#根本无需东拼西凑这么麻烦,完全可以根据自已的需求简单快速的写出一个来,不服就开干!

澳门微尼斯人手机版 1

  1. 通过sql脚本进行数据库备份

  设计的编码思路就是仿asp.net mvc,原因就是asp.net
mvc成功发展了这么多年,有着大量的C#码农习惯了这套优良的编码方式;至于spring
mvc、spring
boot那些,站在使用者的角度来说,光配置和注解都能敲死人,如要要说简洁快速,asp.net
mvc比他强多了,更别提ruby on
rails。不扯远了,下面就按C#经典来。那么需要考虑的问题有tcp、http、request、response、server、controller、actionresult、routetable等,下面就一一来解决这个问题。

 

通过脚本备份数据库,同样也支持压缩,但是需要安装winrar来实现,整体来说也还行,在服务器上创建一个 维护计划,就可以实现,也是很方便的,脚本如下:

  一、Tcp:这个是实现传输通信的底层,当然采用IOCP来提高吞吐量和性能,本人之前在做Redis
Client等的时候就使用这个IOCP
Socket的框架,此时正好也可以用上

一种是重新安装VS2015的ClickOnce程序

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
declare @prefix         nvarchar(100),
        @datefile       nvarchar(100),
        @bakfile        nvarchar(100),
        @rarfile        nvarchar(100),
        @rarcmd         nvarchar(150),
        @str_date       nvarchar(100),
        @sql            nvarchar(100)

--设置备份的目录      
set @prefix='D:/DataBase/' 
set @str_date = replace(replace(replace(convert(varchar(20),getdate(), 120),' ',''),'-',''),':','')
set @datefile = 'xx' +@str_date
set @bakfile = @prefix+@datefile+'.bak'
set @rarfile = @prefix+@datefile+'.rar'
--备份
BACKUP Database mpe_db_Data TO DISK = @bakfile WITH NOFORMAT, NOINIT,  NAME = N'xx-完整 数据库 备份', SKIP, NOREWIND, NOUNLOAD,  STATS = 10
--压缩rar
set @rarcmd ='"c:\Program Files\WinRAR\winrar.exe" ' +'a -df ' +@rarfile+' '+@bakfile
exec master..xp_cmdshell @rarcmd,NO_OUTPUT;
 1 /****************************************************************************
 2 *Copyright (c) 2018 Microsoft All Rights Reserved.
 3 *CLR版本: 4.0.30319.42000
 4 *机器名称:WENLI-PC
 5 *公司名称:Microsoft
 6 *命名空间:SAEA.WebAPI.Http.Net
 7 *文件名: ServerSocket
 8 *版本号: V1.0.0.0
 9 *唯一标识:ab912b9a-c7ed-44d9-8e48-eef0b6ff86a2
10 *当前的用户域:WENLI-PC
11 *创建人: yswenli
12 *电子邮箱:wenguoli_520@qq.com
13 *创建时间:2018/4/8 17:11:15
14 *描述:
15 *
16 *=====================================================================
17 *修改标记
18 *修改时间:2018/4/8 17:11:15
19 *修改人: yswenli
20 *版本号: V1.0.0.0
21 *描述:
22 *
23 *****************************************************************************/
24 using SAEA.Sockets.Core;
25 using SAEA.Sockets.Interface;
26 using System;
27 using System.Collections.Generic;
28 using System.Net;
29 using System.Text;
30 
31 namespace SAEA.WebAPI.Http.Net
32 {
33     class ServerSocket : BaseServerSocket
34     {
35         public event Action<IUserToken, string> OnRequested;
36 
37         public ServerSocket(int bufferSize = 1024 * 100, int count = 10000) : base(new HContext(), bufferSize, true, count)
38         {
39 
40         }
41 
42         protected override void OnReceiveBytes(IUserToken userToken, byte[] data)
43         {
44             HCoder coder = (HCoder)userToken.Coder;
45 
46             coder.GetRequest(data, (result) =>
47             {
48                 OnRequested?.Invoke(userToken, result);
49             });
50         }
51 
52         public void Reply(IUserToken userToken, byte[] data)
53         {
54             base.Send(userToken, data);
55             base.Disconnected(userToken);
56         }
57     }
58 }

第二种是修改项目文件的签名

别问我代码都是干啥的,无非就是打开权限,创建变量、时间戳的文件名、备份脚本、启动备份,哈哈。。都说完了,你也不用问了,

澳门微尼斯人手机版,  二、Http:这个是个应用协议,本人了解下来至少有3个版本,完全熟悉的话估计没个半年都搞不定;但是只需要关键,比如说http1.1的工作模式、传输格式、常见异常code、常见mime类型、js跨域支持等,这些基本能覆盖绝大部分日常场景,至于更多的那些细枝末节的理它作甚,本人的做法就是用Chrome的开发人员工具来查看相关network详情,这样的话就可以清楚http这个协议的具体编码解码了。

右击项目文件的属性,选择签名,然后把红框内去掉,保存即可。

  • 你是不是要问,那删除文件呢?

    –删除15天之前的备份
    set @sql=’del d:\DataBase\xx’ +rtrim(replace(replace(replace(convert(varchar(20),getdate()-15, 120),’ ‘,”),’-‘,”),’:’,”))+’.rar’

 1         public void GetRequest(byte[] data, Action<string> onUnpackage)
 2         {
 3             lock (_locker)
 4             {
 5                 var str = Encoding.UTF8.GetString(data);
 6 
 7                 var index = str.IndexOf(ENDSTR);
 8 
 9                 if (index > -1)
10                 {
11                     var s = str.Substring(0, index);
12 
13                     _result.Append(s);
14 
15                     onUnpackage.Invoke(_result.ToString());
16 
17                     _result.Clear();
18 
19                     if (str.Length > index + 4)
20                     {
21                         _result.Append(str.Substring(index + 4));
22                     }
23                 }
24                 else
25                 {
26                     _result.Append(str);
27                 }
28             }
29         }

澳门微尼斯人手机版 2

为啥删除15天的?你想删除多少天,自己写, -15 的15,随你填写。

  经过分析后http的内容格式其实就是字符回车分隔,再加上一些约定生成的分隔符bound完成的。

 

好了,言归正传,下面是我编写的windows 服务实现,请看:

 1         public HttpRequest(Stream stream)
 2         {
 3             this._dataStream = stream;
 4             var data = GetRequestData(_dataStream);
 5             var rows = Regex.Split(data, Environment.NewLine);
 6 
 7             //Request URL & Method & Version
 8             var first = Regex.Split(rows[0], @"(\s+)")
 9                 .Where(e => e.Trim() != string.Empty)
10                 .ToArray();
11             if (first.Length > 0) this.Method = first[0];
12             if (first.Length > 1)
13             {
14                 this.Query = first[1];
15 
16                 if (this.Query.Contains("?"))
17                 {
18                     var qarr = this.Query.Split("?");
19                     this.URL = qarr[0];
20                     this.Params = GetRequestParameters(qarr[1]);
21                 }
22                 else
23                 {
24                     this.URL = this.Query;
25                 }
26 
27                 var uarr = this.URL.Split("/");
28 
29                 if (long.TryParse(uarr[uarr.Length - 1], out long id))
30                 {
31                     this.URL = this.URL.Substring(0, this.URL.LastIndexOf("/"));
32                     this.Params.Set("id", id.ToString());
33                 }
34             }
35             if (first.Length > 2) this.Protocols = first[2];
36 
37             //Request Headers
38             this.Headers = GetRequestHeaders(rows);
39 
40             //Request "GET"
41             if (this.Method == "GET")
42             {
43                 this.Body = GetRequestBody(rows);
44             }
45 
46             //Request "POST"
47             if (this.Method == "POST")
48             {
49                 this.Body = GetRequestBody(rows);
50                 var contentType = GetHeader(RequestHeaderType.ContentType);
51                 var isUrlencoded = contentType == @"application/x-www-form-urlencoded";
52                 if (isUrlencoded) this.Params = GetRequestParameters(this.Body);
53             }
54         }
  1. 通过C#编写的windows服务进行数据库备份

  看到上面,有人肯定会说你这个传文件咋办?一个呢本人这个是针对webapi;另外一个,如真有这个场景,可以用Chrome的开发人员工具来查看相关network详情,也可以使用httpanalyzerstd、httpwatch等众多工具分析下,其实也就是使用了一些约定的分隔符bound完成,每个浏览器还不一样,有兴趣的完全可以自行扩展一个。

使用方法如下

  三、Reponse这个是webapi服务端相当重要的一个组件,本人也是尽可能方便并且按尽量按asp.net
mvc的命名来实现,另外这里加入支持js跨域所需大部分场景heads,如果还有特殊的heads,完全可以自已添加。

  • 通过 服务部署工具.bat 配置和安装windows服务

澳门微尼斯人手机版 3澳门微尼斯人手机版 4

没了,嘎嘎。。上图

  1 /****************************************************************************
  2 *Copyright (c) 2018 Microsoft All Rights Reserved.
  3 *CLR版本: 4.0.30319.42000
  4 *机器名称:WENLI-PC
  5 *公司名称:Microsoft
  6 *命名空间:SAEA.WebAPI.Http
  7 *文件名: HttpResponse
  8 *版本号: V1.0.0.0
  9 *唯一标识:2e43075f-a43d-4b60-bee1-1f9107e2d133
 10 *当前的用户域:WENLI-PC
 11 *创建人: yswenli
 12 *电子邮箱:wenguoli_520@qq.com
 13 *创建时间:2018/4/8 16:46:40
 14 *描述:
 15 *
 16 *=====================================================================
 17 *修改标记
 18 *修改时间:2018/4/8 16:46:40
 19 *修改人: yswenli
 20 *版本号: V1.0.0.0
 21 *描述:
 22 *
 23 *****************************************************************************/
 24 using SAEA.Commom;
 25 using SAEA.Sockets.Interface;
 26 using SAEA.WebAPI.Http.Base;
 27 using SAEA.WebAPI.Mvc;
 28 using System.Collections.Generic;
 29 using System.Net;
 30 using System.Text;
 31 
 32 namespace SAEA.WebAPI.Http
 33 {
 34     public class HttpResponse : BaseHeader
 35     {
 36         public HttpStatusCode Status { get; set; } = HttpStatusCode.OK;
 37 
 38         public byte[] Content { get; private set; }
 39 
 40 
 41 
 42         internal HttpServer HttpServer { get; set; }
 43 
 44         internal IUserToken UserToken { get; set; }
 45         /// <summary>
 46         /// 创建一个HttpRequest实例
 47         /// </summary>
 48         /// <param name="httpServer"></param>
 49         /// <param name="userToken"></param>
 50         /// <param name="stream"></param>
 51         /// <returns></returns>
 52         internal static HttpResponse CreateInstance(HttpServer httpServer, IUserToken userToken)
 53         {
 54             HttpResponse httpResponse = new HttpResponse("");
 55             httpResponse.HttpServer = httpServer;
 56             httpResponse.UserToken = userToken;
 57             return httpResponse;
 58         }
 59 
 60         /// <summary>
 61         /// 设置回复内容
 62         /// </summary>
 63         /// <param name="httpResponse"></param>
 64         /// <param name="result"></param>
 65         internal static void SetResult(HttpResponse httpResponse, ActionResult result)
 66         {
 67             httpResponse.Content_Encoding = result.ContentEncoding.EncodingName;
 68             httpResponse.Content_Type = result.ContentType;
 69             httpResponse.Status = result.Status;
 70 
 71             if (result is EmptyResult)
 72             {
 73                 return;
 74             }
 75 
 76             if (result is FileResult)
 77             {
 78                 var f = result as FileResult;
 79 
 80                 httpResponse.SetContent(f.Content);
 81 
 82                 return;
 83             }
 84 
 85             httpResponse.SetContent(result.Content);
 86         }
 87 
 88 
 89         public HttpResponse(string content) : this(content, "UTF-8", "application/json; charset=utf-8", HttpStatusCode.OK)
 90         {
 91 
 92         }
 93 
 94         public HttpResponse(string content, string encoding, string contentType, HttpStatusCode status)
 95         {
 96             this.Content_Encoding = encoding;
 97             this.Content_Type = contentType;
 98             this.Status = status;
 99             this.SetContent(content);
100         }
101 
102         internal HttpResponse SetContent(byte[] content, Encoding encoding = null)
103         {
104             this.Content = content;
105             this.Encoding = encoding != null ? encoding : Encoding.UTF8;
106             this.Content_Length = content.Length.ToString();
107             return this;
108         }
109 
110         internal HttpResponse SetContent(string content, Encoding encoding = null)
111         {
112             //初始化内容
113             encoding = encoding != null ? encoding : Encoding.UTF8;
114             return SetContent(encoding.GetBytes(content), encoding);
115         }
116 
117 
118         public string GetHeader(ResponseHeaderType header)
119         {
120             return base.GetHeader(header);
121         }
122 
123         public void SetHeader(ResponseHeaderType header, string value)
124         {
125             base.SetHeader(header, value);
126         }
127 
128         /// <summary>
129         /// 构建响应头部
130         /// </summary>
131         /// <returns></returns>
132         protected string BuildHeader()
133         {
134             StringBuilder builder = new StringBuilder();
135             builder.Append(Protocols + SPACE + Status.ToNVString() + ENTER);
136             builder.AppendLine("Server: Wenli's Server");
137             builder.AppendLine("Keep-Alive: timeout=20");
138             builder.AppendLine("Date: " + DateTimeHelper.Now.ToFString("r"));
139 
140             if (!string.IsNullOrEmpty(this.Content_Type))
141                 builder.AppendLine("Content-Type:" + this.Content_Type);
142 
143             //支持跨域
144             builder.AppendLine("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
145             builder.AppendLine("Access-Control-Allow-Origin: *");
146             builder.AppendLine("Access-Control-Allow-Headers: Content-Type,X-Requested-With,Accept,yswenli");//可自行增加额外的header
147             builder.AppendLine("Access-Control-Request-Methods: GET, POST, PUT, DELETE, OPTIONS");
148 
149             if (this.Headers != null && this.Headers.Count > 0)
150             {
151                 foreach (var key in Headers.Names)
152                 {
153                     builder.AppendLine($"{key}: {Headers[key]}");
154                 }
155             }
156 
157             return builder.ToString();
158         }
159 
160         /// <summary>
161         /// 生成数据
162         /// </summary>
163         private byte[] ToBytes()
164         {
165             List<byte> list = new List<byte>();
166             //发送响应头
167             var header = BuildHeader();
168             byte[] headerBytes = this.Encoding.GetBytes(header);
169             list.AddRange(headerBytes);
170 
171             //发送空行
172             byte[] lineBytes = this.Encoding.GetBytes(System.Environment.NewLine);
173             list.AddRange(lineBytes);
174 
175             //发送内容
176             list.AddRange(Content);
177 
178             return list.ToArray();
179         }
180 
181 
182         public void Write(string str)
183         {
184             SetContent(str);
185         }
186 
187         public void BinaryWrite(byte[] data)
188         {
189             SetContent(data);
190         }
191 
192         public void Clear()
193         {
194             this.Write("");
195         }
196 
197         public void End()
198         {
199             HttpServer.Replay(UserToken, this.ToBytes());
200             HttpServer.Close(UserToken);
201         }
202 
203 
204 
205     }
206 }

澳门微尼斯人手机版 5

View Code

图1 使用管理员,打开部署脚本

  四、HttpServer:这个就是承载webapi的容器;有人说不是有IIS和Apache么?本人想说的是:有self-host方便么?有无需安装,无需配置、随便高性能开跑好么?asp.net
core里面都有了这个,没这个就没有逼格….(此处省略一万字),前面还研究tcp、http这个当然不能少了

发表评论

电子邮件地址不会被公开。 必填项已用*标注