介绍,介绍我的底层支持库 Net.Sz.CFramework

Net.Sz.CFramework  是我自己的底层库,是经过验证的底层库。

包含:

socket tcp协议,
socket http协议线程池,
线程模型,
任务模型,
定时器模型,
日志模块
脚本模块
一些辅助类

接下来一一介绍

这里是华丽丽的分割线

辅助类功能块

 1         // 摘要: 
 2         //     获取当前时间和 1970-01-01 00:00:00 的时间差
 3         //     为了和java一致使用的是 UTC 时间
 4         public static long CurrentTimeMillis();
 5         //
 6         // 摘要: 
 7         //     获取当前时间所表示的毫秒数
 8         public static long CurrentTimeMillis(DateTime dt);
 9         public static long CurrentTimeMillis_Java();
10         //
11         // 摘要: 
12         //     获取当前时间所表示的毫秒数
13         public static long CurrentTimeMillis_Java(DateTime dt);
14         //
15         // 摘要: 
16         //     将毫秒数转化成当前时间
17         public static DateTime DateNow(long milliseconds);
18         public static DateTime DateNow_Java(long milliseconds);
19         //
20         // 摘要: 
21         //     yyyy-MM-dd HH:mm:ss:fff:
22         //
23         // 参数: 
24         //   d:
25         public static string NowString(DateTime d);
后面java函数是输出和java一直的时间函数
 1         //
 2         // 摘要: 
 3         //     验证活动是否结束 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
 4         //     第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,
 5         //     每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015
 6         //     或者 2017
 7         public static bool VerifyConfigEndTimeStr(DateTime date, string timeStr);
 8 
 9         //
10         // 摘要: 
11         //     获取活动结束时间倒计时 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
12         //     第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,
13         //     每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015
14         //     或者 2017
15         //     返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时
16         public static long VerifyDateEndTime(string timeStr);
17 
18         //
19         // 摘要: 
20         //     获取开始倒计时 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
21         //     第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,
22         //     每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015
23         //     或者 2017
24         //     返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时
25         public static long VerifyDateTime(string timeStr);
时间匹配函数,看到这里后,请不要给我提quartz 因为我只会回答你不同的需求,不同的环境会有不同的使用情况

位运算辅助函数

1 Net.Sz.CFramework.Struct.EnumStatus status2 = new Net.Sz.CFramework.Struct.EnumStatus(1 << 1, 1 << 0);

使用方式和详解请看 状态机

接下来介绍日志组建

本日志组建支持大约输出日志信息的文件名函数名和行号
方法是异步处理的支持写入文件,文件写入格式是每天一个文件。
 1             //是否显示控制台打印
 2             Net.Sz.CFramework.Log.Logger.LOGCONSOLE = true;
 3             //只支持三种格式。控制台输出,info级别和error级别
 4             Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.DEBUG;
 5 
 6             Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test");
 7             Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test");
 8             Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test");
 9 
10             //只显示info
11             Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.INFO;
12 
13             Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test");
14             Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test");
15             Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test");

大约信息如下

[2016-03-30 15:03:13:9706: Debug:CApp1.Program, Main, 26] 55->test
[2016-03-30 15:03:14:0496: Info :CApp1.Program, Main, 27] 55->test
[2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 30] 55->test
[2016-03-30 15:03:14:0536: Info :CApp1.Program, Main, 34] 55->test
[2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 36] 55->test

线程模型.

这里包含了线程模型,任务模型和定时器任务模型
 1             //是以一个线程执行任务的线程模型
 2             long t1 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 1);
 3 
 4             //是以十个线程执行任务的线程模型
 5             long t10 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 10);
 6 
 7             //创建一个简单任务
 8             Net.Sz.CFramework.Threading.ThreadPool.AddTask(t1, new Net.Sz.CFramework.Threading.TaskModel_Action(() =>
 9             {
10                 Net.Sz.CFramework.Log.Logger.Debug("TaskModel_Action 简单任务");
11 
12             }));
13 
14             //创建一个简单的定时器任务,创建一个执行3次,每个2秒执行一次的任务
15             Net.Sz.CFramework.Threading.ThreadPool.AddTimerTask(t1, new Net.Sz.CFramework.Threading.TimerTask_Action(3, 2000, () =>
16             {
17                 Net.Sz.CFramework.Log.Logger.Debug("TimerTask_Action 简单任务");
18 
19             }));

输出

 1 [2016-03-30 15:16:43:2129: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局线程线程 >
 2 [2016-03-30 15:16:43:3249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_1 >
 3 [2016-03-30 15:16:43:3299: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_2 >
 4 [2016-03-30 15:16:43:3439: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定时器任务 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent
 5 [2016-03-30 15:16:43:3589: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 线程 >
 6 [2016-03-30 15:16:43:3719: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < test线程 >
 7 [2016-03-30 15:16:43:3849: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_1 >
 8 [2016-03-30 15:16:43:3899: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_2 >
 9 [2016-03-30 15:16:43:4059: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_3 >
10 [2016-03-30 15:16:43:4099: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_4 >
11 [2016-03-30 15:16:43:4159: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_5 >
12 [2016-03-30 15:16:43:4249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_6 >
13 [2016-03-30 15:16:43:4359: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_7 >
14 [2016-03-30 15:16:43:4399: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_8 >
15 [2016-03-30 15:16:43:4469: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_9 >
16 [2016-03-30 15:16:43:4559: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_10 >
17 [2016-03-30 15:16:43:4649: Debug:CApp1.Program, <Main>b__0, 23] TaskModel_Action 简单任务
18 [2016-03-30 15:16:43:4659: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] test 接手定时器任务 Net.Sz.CFramework.Threading.TimerTask_Action
19 [2016-03-30 15:16:43:4729: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务
20 [2016-03-30 15:16:45:4820: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务
21 [2016-03-30 15:16:47:4921: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务

 

Socket Tcp组建

tcp监听需要实现IIOSessionHandler接口

 1     // 摘要: 
 2     //     http监听处理
 3     //     @author 失足程序员
 4     //     @Blog http://www.cnblogs.com/ty408/
 5     //     @mail 492794628@qq.com
 6     //     @phone 13882122019
 7     public interface IIOSessionHandler
 8     {
 9         // 摘要: 
10         //     新建链接
11         //
12         // 参数: 
13         //   session:
14         void channelActive(IOSession session);
15         //
16         // 摘要: 
17         //     链接闲置状态
18         //
19         // 参数: 
20         //   session:
21         void channelInactive(IOSession session);
22         //
23         // 摘要: 
24         //     有消息,请注意消息是多线程处理的。也许你前一个消息没有处理完成,后一个消息已经来了
25         //
26         // 参数: 
27         //   session:
28         //
29         //   buffer:
30         void channelRead(IOSession session, byte[] buffer);
31         //
32         // 摘要: 
33         //     链接断开
34         //
35         // 参数: 
36         //   session:
37         void channelUnregistered(IOSession session, params string[] obj);
38         //
39         // 摘要: 
40         //     链接发送异常
41         //
42         // 参数: 
43         //   session:
44         //
45         //   ex:
46         void exceptionCaught(IOSession session, Exception ex);
47     }
1             //客户端和服务器都需要这个处理接口实现
2             Net.Sz.CFramework.Netty.NettyPool.SessionHandler = new MySessionHandler();
3             //创建对ip127.0.0.1端口9527的tcp监听,使用一个线程处理这个监听的io信息
4             Net.Sz.CFramework.Netty.NettyPool.AddTcpBind("127.0.0.1", 9527, 1);
5             //创建对服务器连接
6             Net.Sz.CFramework.Netty.Tcp.NettyClient client = new Net.Sz.CFramework.Netty.Tcp.NettyClient("127.0.0.1", 9527);
7             client.Connect();
需要特别注意public void channelRead(Net.Sz.CFramework.Netty.IOSession session, byte[] buffer)
这个函数收到的消息的字节数组是一个完整的独立包

  1 #pragma once
  2 #include "stdafx.h"
  3 #include "BufferReader.h"
  4 #include "BufferWriter.h"
  5 
  6 
  7 using namespace System;
  8 
  9 namespace Net{
 10     namespace Sz{
 11         namespace CFramework{
 12             namespace Netty{
 13                 namespace Buffer{
 14                     
 15                     using namespace System::IO;
 16                     using namespace System::Collections::Generic;
 17 
 18                     /// <summary>
 19                     /// 字节流书写器
 20                     /// <para>@author 失足程序员</para>
 21                     /// <para>@Blog http://www.cnblogs.com/ty408/</para>
 22                     /// <para>@mail 492794628@qq.com</para>
 23                     /// <para>@phone 13882122019</para>
 24                     /// </summary>
 25                     ref class DefaultMarshalEndian
 26                     {
 27                         //用于存储剩余未解析的字节数
 28                     private:
 29                         List<Byte>^ _LBuff = gcnew List<Byte>(2);
 30 
 31                         //字节数常量一个消息id4个字节
 32                         const long ConstLenght = 8L;
 33                         const short ConstStart1 = 0xaa;
 34                         const short ConstStart2 = 0xbb;
 35 
 36                     public:
 37                         List<array<Byte>^>^ Decoder(array<Byte>^ buff)
 38                         {
 39                             if (this->_LBuff->Count > 0)
 40                             {
 41                                 //拷贝之前遗留的字节
 42                                 this->_LBuff->AddRange(buff);
 43                                 buff = this->_LBuff->ToArray();
 44                                 this->_LBuff = gcnew List<Byte>(2);
 45                             }
 46                             List<array<Byte>^>^ list = gcnew List<array<Byte>^>();
 47 
 48                             BufferReader^ buffers = gcnew BufferReader(buff);
 49 
 50                             try
 51                             {
 52                                 array<Byte>^ _buff;
 53                             Label_0073:
 54 
 55                                 //判断本次解析的字节是否满足常量字节数 
 56                                 if ((buffers->BaseStream->Length - buffers->BaseStream->Position) < ConstLenght)
 57                                 {
 58                                     _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position));
 59                                     this->_LBuff->AddRange(_buff);
 60                                 }
 61                                 else
 62                                 {
 63                                     short tmpStart1 = buffers->ReadInt16();
 64                                     if (ConstStart1 == tmpStart1)//自定义头相同
 65                                     {
 66                                         short tmpStart2 = buffers->ReadInt16();
 67                                         if (ConstStart2 == tmpStart2)//自定义头相同
 68                                         {
 69                                             long offset = buffers->ReadInt32();
 70                                             //剩余字节数大于本次需要读取的字节数
 71                                             if (offset <= (buffers->BaseStream->Length - buffers->BaseStream->Position))
 72                                             {
 73                                                 _buff = buffers->ReadBytes((int)(offset));
 74                                                 list->Add(_buff);
 75                                                 goto Label_0073;
 76                                             }
 77                                             else
 78                                             {
 79                                                 //剩余字节数刚好小于本次读取的字节数 存起来,等待接受剩余字节数一起解析
 80                                                 buffers->BaseStream->Seek(ConstLenght, System::IO::SeekOrigin::Current);
 81                                                 _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position));
 82                                                 this->_LBuff->AddRange(_buff);
 83                                             }
 84                                         }
 85                                         else
 86                                         {
 87                                             //往前推三个字节
 88                                             buffers->BaseStream->Seek(-3, System::IO::SeekOrigin::Current);
 89                                             goto Label_0073;
 90                                         }
 91                                     }
 92                                     else
 93                                     {
 94                                         //往前推一个字节
 95                                         buffers->BaseStream->Seek(-1, System::IO::SeekOrigin::Current);
 96                                         goto Label_0073;
 97                                     }
 98                                 }
 99                             }
100                             catch (Exception^){}
101                             finally
102                             {
103                                 buffers->Close();
104                                 delete buffers;
105                             }
106                             return list;
107                         }
108 
109                         void Encoder(array<Byte>^ msgBuffer, BufferWriter^ %outBuf)
110                         {
111                             outBuf->Write(ConstStart1);
112                             outBuf->Write(ConstStart2);
113                             if (msgBuffer != nullptr)
114                             {
115                                 outBuf->Write((Int32)(msgBuffer->Length));
116                                 outBuf->Write(msgBuffer);
117                             }
118                             else
119                             {
120                                 outBuf->Write((Int32)0);
121                             }
122                         }
123 
124                     };
125                 }
126             }
127         }
128     }
129 }

解码和编码器

 1 [2016-03-30 15:28:55:5178: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, .ctor, 61] Start Listen Tcp Socket -> 127.0.0.1:9527
 2 [2016-03-30 15:28:55:6028: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局线程线程 >
 3 [2016-03-30 15:28:55:6258: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_1 >
 4 [2016-03-30 15:28:55:6318: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_2 >
 5 [2016-03-30 15:28:55:6458: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定时器任务 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent
 6 [2016-03-30 15:28:55:6648: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 线程 >
 7 [2016-03-30 15:28:55:6798: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread:127.0.0.1:9527线程 >
 8 [2016-03-30 15:28:55:7078: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread线程 >
 9 [2016-03-30 15:28:55:7098: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Netty Session Pool Thread 接手定时器任务 Net.Sz.CFramework.Netty.CheckIOSessionTimerTask
10 [2016-03-30 15:28:55:7188: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 48] Try Connect Tcp Socket Remote:127.0.0.1:9527
11 [2016-03-30 15:28:55:7388: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 51] Connect Tcp Socket Remote Socket RemoteEndPoint:127.0.0.1:9527 LocalEndPoint:127.0.0.1:17669
12 [2016-03-30 15:28:55:7468: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, AcceptAsync_Async, 43] Create Tcp Socket Remote Socket LocalEndPoint:127.0.0.1:9527 RemoteEndPoint:127.0.0.1:17669

 

Socket Http监听

需要实现

 1     // 摘要: 
 2     //     http监听处理
 3     //     @author 失足程序员
 4     //     @Blog http://www.cnblogs.com/ty408/
 5     //     @mail 492794628@qq.com
 6     //     @phone 13882122019
 7     public interface IHttpHandler : IBaseScript
 8     {
 9         // 摘要: 
10         //     并发处理的
11         //
12         // 参数: 
13         //   session:
14         //     连接对象
15         void Action(HttpSession session);
16     }
 1     class Program
 2     {
 3 
 4         static void Main(string[] args)
 5         {
 6             //创建login目录的监听,处理程序是LoginHttpHandler,单线程处理请求
 7             Net.Sz.CFramework.Netty.NettyPool.AddHttpBind("127.0.0.1", 9527, "login", new LoginHttpHandler(), 1);
 8             Console.ReadLine();
 9         }
10     }
11     class LoginHttpHandler : Net.Sz.CFramework.Netty.Http.IHttpHandler
12     {
13         public void Action(Net.Sz.CFramework.Netty.Http.HttpSession session)
14         {
15             session.WriteSuccess();
16             session.AddBody("Login OK");
17             session.WriteFlush();
18         }
19     }

脚步使用功能

使用脚步功能,C#的文件类,*.cs文件类
如果是实现IBaseScript可以放到脚步管理器里面进行查找
如果实现IInitBaseScript接口执行初始化函数;如果没有只实现IInitBaseScript不会放到脚步管理,
    // 摘要: 
    //     脚本基类
    //     @author 失足程序员
    //     @Blog http://www.cnblogs.com/ty408/
    //     @mail 492794628@qq.com
    //     @phone 13882122019
    public interface IBaseScript

    // 摘要: 
    //     脚本基类
    //     执行init初始化信息
    //     PS:实现这个接口不会放到脚步缓存集合中,如果需要请实现 IBaseScript
    //     @author 失足程序员
    //     @Blog http://www.cnblogs.com/ty408/
    //     @mail 492794628@qq.com
    //     @phone 13882122019
    public interface IInitBaseScript
    {
        // 摘要: 
        //     卸载脚本
        void InitScript();
    }
            //传入文件路径,可以是相对路径也可以是绝对路径,后面可以传入需要引入的dll文件或者exe文件用于编译和加载
            ScriptManager.LoadCSharpFile(new String[] { "" }, "");

这里以我的游戏程序距离

        public static List<string> LoadScript()
        {
            return ScriptManager.LoadCSharpFile(new string[] { "../../../../Net.Sz.Game.MMOGame.GameServer.Scripts/Src" },
                   "protobuf-net.dll",
                   "EntityFramework.dll",
                   "MySql.Data.dll",
                   "Net.Sz.Framework.DB.dll",
                   "MySql.Data.Entity.EF6.dll",
                   "Net.Sz.Game.MMOGame.GameMessages.dll",
                   "Net.Sz.Game.MMOGame.GameModel.dll"
                   );
        }

        public static Net.Sz.CFramework.Script.ScriptPool ScriptManager { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        public static void Start()
        {

            Net.Sz.CFramework.Struct.SzExtensions.Console_Show("Server", false, true);

            try
            {
                LoadScript();
            }
            catch (Exception)
            {
                throw;
            }
        }

 

这是我的底层库支持。望各位大仙多多指教!

对应提供下载.

Net.Sz.CFramework.Release.zip

java 版本的源码下载

net.sz.java.code.zip

posted on 2016-03-30 15:58  無心道(失足程序员)  阅读(3880)  评论(5编辑  收藏  举报