APM测试
俗话说麻雀虽小,五脏俱全。apm虽然简单,但是可以实现单机高性能消息推送(可以采用redis、kafka等改造成大型分布式消息推送服务器)。
测试demo:
![](https://yqfile.alicdn.com/img_1c53668bcee393edac0d7b3b3daff1ae.gif?x-oss-process=image/resize,w_1400/format,webp)
![](https://yqfile.alicdn.com/img_405b18b4b6584ae338e0f6ecaf736533.gif?x-oss-process=image/resize,w_1400/format,webp)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Text; 6 using System.Threading; 7 using System.Threading.Tasks; 8 9 namespace APM.ConsoleDemo 10 { 11 class Program 12 { 13 14 static void Main(string[] args) 15 { 16 Console.Title = "APM.Core test"; 17 18 Console.WriteLine("输入1测试APM tcp通讯"); 19 20 Console.WriteLine("输入2测试APM转发"); 21 22 var str = Console.ReadLine(); 23 24 if (!string.IsNullOrEmpty(str) && str != "1") 25 { 26 APMServer(); 27 APMClient(); 28 APMClient(); 29 } 30 else 31 { 32 Task.Factory.StartNew(() => 33 { 34 Thread.Sleep(2000); 35 ClientProcess(); 36 }); 37 ServerProcess(true); 38 } 39 Console.ReadLine(); 40 } 41 42 private static APM.Core.Server server; 43 static void ServerProcess(bool falg = false) 44 { 45 Console.WriteLine("server test"); 46 server = new APM.Core.Server(8889, 500); 47 server.OnAccepted += Server_OnAccepted; 48 server.OnMessage += Server_OnReceived; 49 server.OnDisConnected += Server_OnDisConnected; 50 server.OnOnError += Server_OnOnError; 51 server.Start(); 52 Console.WriteLine("server is running..."); 53 if (falg) 54 { 55 while (true) 56 { 57 Console.ReadLine(); 58 Console.WriteLine(string.Format("serverinfo[ClientCount:{0},ReceiveCount:{1},SendCount:{2}]", server.ClientCount, server.ReceiveCount, server.SendCount)); 59 } 60 } 61 62 } 63 64 65 private static APM.Core.Client client; 66 static void ClientProcess() 67 { 68 69 Console.WriteLine("Client test"); 70 71 var localIP = GetLocalIp() + ":8889"; 72 73 Console.WriteLine("Client send test"); 74 client = new APM.Core.Client(Guid.NewGuid().ToString("N"), 10, localIP); 75 client.OnConnected += Client_OnConnected; 76 client.OnMessage += Client_OnMessage; 77 client.OnDisConnected += Client_OnDisConnected; 78 client.OnError += Client_OnError; 79 client.Connect(); 80 81 Console.Title = "APM Server & Client"; 82 Console.WriteLine("MutiClients test"); 83 for (int i = 0; i < 10000; i++) 84 { 85 new APM.Core.Client(Guid.NewGuid().ToString("N"), 10, localIP).Connect(); 86 } 87 88 } 89 90 #region server events 91 private static void Server_OnAccepted(APM.Core.UserToken remote) 92 { 93 Console.WriteLine("收到客户端连接:" + remote.Client.RemoteEndPoint); 94 95 } 96 private static void Server_OnReceived(APM.Core.UserToken remote, byte[] data) 97 { 98 if (server.ClientCount <= 10) 99 { 100 Console.WriteLine("收到客户端消息:" + remote.Client.RemoteEndPoint + " " + Encoding.UTF8.GetString(data)); 101 } 102 server.SendMsg(remote, "server:hello " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); 103 } 104 105 private static void Server_OnDisConnected(APM.Core.UserToken remote, Exception ex) 106 { 107 Console.WriteLine(string.Format("客户端{0}已断开连接,断开消息:{1}", remote.ID, ex.Message)); 108 } 109 110 private static void Server_OnOnError(APM.Core.UserToken remote, Exception ex) 111 { 112 Console.WriteLine(string.Format("操作客户端{0}异常,断开消息:{1}", remote.ID, ex.Message)); 113 } 114 115 116 #endregion 117 118 #region client events 119 120 static string msg = "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohelloh"; 121 private static void Client_OnConnected(APM.Core.Client c) 122 { 123 if (c != null) 124 c.SendMsg(string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); 125 126 } 127 128 private static void Client_OnMessage(byte[] data) 129 { 130 Console.WriteLine("收到服务器信息:" + Encoding.UTF8.GetString(data)); 131 if (client != null) 132 client.SendMsg(string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); 133 } 134 135 private static void Client_OnDisConnected(Exception ex) 136 { 137 Console.WriteLine(string.Format("客户端断开连接,断开消息:{0}", ex.Message)); 138 } 139 140 private static void Client_OnError(Exception ex) 141 { 142 Console.WriteLine(string.Format("客户端异常,异常消息:{0}", ex.Message)); 143 } 144 145 146 #endregion 147 148 #region MyRegion 149 static string GetLocalIp() 150 { 151 string hostname = Dns.GetHostName();//得到本机名 152 //IPHostEntry localhost = Dns.GetHostByName(hostname);//方法已过期,只得到IPv4的地址 153 IPHostEntry localhost = Dns.GetHostEntry(hostname); 154 IPAddress localaddr = localhost.AddressList.Where(b => b.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Last(); 155 return localaddr.ToString(); 156 } 157 #endregion 158 159 160 #region APM转发 161 public static void APMServer() 162 { 163 Console.WriteLine("APMServer test"); 164 APM.Server.APMServer server = new Server.APMServer(8890, 1024); 165 server.OnAccepted += Server_OnAccepted; 166 server.OnDisConnected += Server_OnDisConnected; 167 server.OnError += Server_OnOnError; 168 server.OnMessage += Server_OnMessage; 169 server.Start(); 170 Console.WriteLine("APMServer 已启动..."); 171 } 172 173 private static void Server_OnMessage(Core.Extention.Message msg) 174 { 175 Console.WriteLine("APMServer 收到并转发消息:ID {0},Sender {1},SessionID {2},SendTick {3}", msg.ID, msg.Sender, msg.SessionID, msg.SendTick); 176 } 177 178 public static void APMClient() 179 { 180 Console.WriteLine("APMClient test"); 181 var userID = "张三" + new Random((int)DateTime.Now.Ticks).Next(10000, 99999); 182 APM.Client.APMClient apmClient = new Client.APMClient(userID, GetLocalIp(), 8890); 183 apmClient.OnConnected += ApmClient_OnConnected; 184 apmClient.OnDisConnected += Client_OnDisConnected; 185 apmClient.OnError += Client_OnError; 186 apmClient.OnMessage += APMClient_OnMessage; 187 apmClient.Connect(); 188 Task.Factory.StartNew(() => 189 { 190 while (true) 191 { 192 if (apmClient.Connected) 193 { 194 apmClient.SendChannelMsg("all", string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); 195 } 196 Thread.Sleep(0); 197 } 198 }); 199 Console.WriteLine("APMClient:{0} 已连接到服务器", userID); 200 } 201 202 private static void ApmClient_OnConnected(Client.APMClient c) 203 { 204 c.Subscribe("all"); 205 } 206 207 private static void APMClient_OnMessage(Core.Extention.Message msg) 208 { 209 Console.WriteLine("APMClient 收到消息:ID {0},Sender {1},SessionID {2},SendTick {3}", msg.ID, msg.Sender, msg.SessionID, msg.SendTick); 210 } 211 #endregion 212 } 213 }
github地址:https://github.com/yswenli/APM
异步tcp通信——APM.Core 服务端概述
异步tcp通信——APM.Core 解包
异步tcp通信——APM.Server 消息推送服务的实现
异步tcp通信——APM.ConsoleDemo
转载请标明本文来源:http://www.cnblogs.com/yswenli/
更多内容欢迎star作者的github:https://github.com/yswenli/APM
如果发现本文有什么问题和任何建议,也随时欢迎交流~