樓主從12年畢業大部分時間一直從事於通訊網關的開發,剛剛學那會連C#是啥都不知道,就直接入手網關開發,前前後後到現在也算是弄了5、6個通訊協議,後來看到北風之神的socket框架和supersocket也是研究了很久,就在想著去自己搭建一個通訊網關框架。
這個框架原形當然是微軟的高性能服務器框架,其中封裝了一些業務邏輯等處理。
1 /// <summary> 2 /// 服務接口 3 /// </summary> 4 public interface IServer 5 { 6 string Name { get; } 7 void Start(int port); 8 void Start(EndPoint localPoint); 9 void Stop(); 10 }
/// <summary> /// 請求接口 /// </summary> public interface IRequestInfo { /// <summary> /// 唯一編號 /// </summary> string Key { get; set; } }
每種協議都有特定的格式,這個類就就是按特定命令格式生成的請求
1 /// <summary> 2 /// 消息過濾器 3 /// </summary> 4 /// <typeparam name="TRequestInfo">請求接口</typeparam> 5 public interface IReceiveFilter<TRequestInfo> 6 where TRequestInfo : IRequestInfo 7 { 8 /// <summary> 9 /// 消息解析 10 /// </summary> 11 /// <param name="message"></param> 12 /// <returns></returns> 13 List<TRequestInfo> Filter(ref byte[] message); 14 }
消息的過濾器,處理tcp連接中的粘包斷包等問題
1 /// <summary> 2 /// 網關接口 3 /// </summary> 4 /// <typeparam name="TRequestInfo">請求數據</typeparam> 5 /// <typeparam name="TReceiveFilter">消息過濾器</typeparam> 6 /// <typeparam name="TCommandFactory">命令工廠</typeparam> 7 public interface IGater<TRequestInfo, TReceiveFilter, out TCommandFactory> 8 where TRequestInfo : IRequestInfo 9 where TReceiveFilter : IReceiveFilter<TRequestInfo> 10 { 11 /// <summary> 12 /// 配置 13 /// </summary> 14 BaseConfig Config { get; } 15 /// <summary> 16 /// 命令工廠 17 /// </summary> 18 TCommandFactory CommandFactory { get; } 19 /// <summary> 20 /// 服務程序 21 /// </summary> 22 TcpServer<TReceiveFilter, TRequestInfo> Server { get; } 23 }
網關接口層
1 /// <summary> 2 /// 基礎網關 3 /// </summary> 4 /// <typeparam name="TRequestInfo">請求數據接口</typeparam> 5 /// <typeparam name="TCommand">客戶端命令接口</typeparam> 6 /// <typeparam name="TReceiveFilter">消息過濾器接口</typeparam> 7 /// <typeparam name="TCommandFactory">客戶端命令解析工廠</typeparam> 8 public abstract class BaseGate<TRequestInfo, TCommand, TReceiveFilter, TCommandFactory> : IGater<TRequestInfo, TReceiveFilter, TCommandFactory> 9 where TRequestInfo : IRequestInfo 10 where TCommand : ICommand<TRequestInfo> 11 where TReceiveFilter : IReceiveFilter<TRequestInfo>, new() 12 where TCommandFactory : ICommandFactory<TRequestInfo, TCommand> 13 { 14 /// <summary> 15 /// 配置 16 /// </summary> 17 public BaseConfig Config { get; private set; } 18 /// <summary> 19 /// 命令工廠 20 /// </summary> 21 public TCommandFactory CommandFactory { get; private set; } 22 /// <summary> 23 /// 服務 24 /// </summary> 25 public TcpServer<TReceiveFilter, TRequestInfo> Server { get; private set; } 26 27 /// <summary> 28 /// 構造函數 29 /// </summary> 30 /// <param name="server">socekt服務</param> 31 /// <param name="commandFactory">命令工廠</param> 32 /// <param name="config">服務配置</param> 33 /// <param name="clientEvent">客戶端事件處理</param> 34 protected BaseGate(TcpServer<TReceiveFilter, TRequestInfo> server, TCommandFactory commandFactory, BaseConfig config, IClientEvent clientEvent) 35 { 36 CommandFactory = commandFactory; 37 Server = server; 38 Config = config; 39 server.ClientOnClosed += clientEvent.ClientOnClosed; 40 server.ClientOnConnected += clientEvent.ClientOnConnected; 41 server.ReceiveNewData += ReceiveNewData; 42 } 43 44 /// <summary> 45 /// 新數據處理 46 /// </summary> 47 /// <param name="request"></param> 48 private void ReceiveNewData(TRequestInfo request) 49 { 50 var item = CommandFactory.CreateCommand(request); 51 if (item != null) 52 { 53 item.ExcuteCommand(request); 54 } 55 } 56 57 /// <summary> 58 /// 初始化網關 59 /// </summary> 60 public void Init() 61 { 62 63 Server.Init(Config.MaxClientCounts, Config.BufferSize); 64 Server.InitFilter(new TReceiveFilter()); 65 } 66 /// <summary> 67 /// 啟動網關 68 /// </summary> 69 public void Start() 70 { 71 Server.Start(Config.Port); 72 } 73 }
網關的基本實現
1 /// <summary> 2 /// 客戶端連接處理接口 3 /// </summary> 4 public interface IClientEvent 5 { 6 /// <summary> 7 /// 新連接 8 /// </summary> 9 /// <param name="sender"></param> 10 /// <param name="e"></param> 11 void ClientOnConnected(object sender, ClientEventArgs e); 12 /// <summary> 13 /// 連接斷開 14 /// </summary> 15 /// <param name="sender"></param> 16 /// <param name="e"></param> 17 void ClientOnClosed(object sender, ClientEventArgs e); 18 }
這個是客戶端的連接處理,是根據requestinfo中key來標識唯一id,也可以在網關中實現,我是單獨摘開的,因為可能架構多個服務器的話,多種協議
這裡其實是封裝了命令的處理,提供工廠接口以及命令接口,根據request請求生成
1 /// <summary> 2 /// 命令接口 3 /// </summary> 4 /// <typeparam name="TRequestInfo">請求接口</typeparam> 5 public interface ICommand<in TRequestInfo> 6 where TRequestInfo : IRequestInfo 7 { 8 /// <summary> 9 /// 客戶端標識 10 /// </summary> 11 string Key { get; set; } 12 /// <summary> 13 /// 執行命令 14 /// </summary> 15 /// <param name="request"></param> 16 void ExcuteCommand(TRequestInfo request); 17 }
1 /// <summary> 2 /// 客戶端命令工廠 3 /// </summary> 4 /// <typeparam name="TRequestInfo">請求接口</typeparam> 5 /// <typeparam name="TCommand">命令接口</typeparam> 6 public interface ICommandFactory<in TRequestInfo, out TCommand> 7 where TRequestInfo : IRequestInfo 8 where TCommand : ICommand<TRequestInfo> 9 { 10 /// <summary> 11 /// 構造命令 12 /// </summary> 13 /// <param name="request"></param> 14 /// <returns></returns> 15 TCommand CreateCommand(TRequestInfo request); 16 }
大家只要繼承上面的接口,基本就可以實現了。
這是下載地址,大家都看看,順便給點意見
http://pan.baidu.com/s/1dDIOkyH
左移運算符(<<)
將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)。
例:a = a << 2 將a的二進制位左移2位,右補0,
左移1位後a = a * 2;
若左移時捨棄的高位不包含1,則每左移一位,相當於該數乘以2。
右移運算符(>>)
將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
操作數每右移一位,相當於該數除以2。
例如:a = a >> 2 將a的二進制位右移2位,
左補0 or 補1 得看被移數是正還是負。
左移運算符(<<)
將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)。
例:a = a << 2 將a的二進制位左移2位,右補0,
左移1位後a = a * 2;
若左移時捨棄的高位不包含1,則每左移一位,相當於該數乘以2。
右移運算符(>>)
將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
操作數每右移一位,相當於該數除以2。
例如:a = a >> 2 將a的二進制位右移2位,
左補0 or 補1 得看被移數是正還是負。