异步tcp通信——APM.ConsoleDemo
APM测试
俗话说麻雀虽小,五脏俱全。apm虽然简单,但是可以实现单机高性能消息推送(可以采用redis、kafka等改造成大型分布式消息推送服务器)。
测试demo:
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 }
View Code
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
如果发现本文有什么问题和任何建议,也随时欢迎交流~
感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是yswenli 。
异步tcp通信——APM.ConsoleDemo相关推荐
- 异步tcp通信——APM.Core 服务端概述
为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...
- 使用NIO实现异步非阻塞Socket tcp通信
使用NIO实现异步非阻塞Socket tcp通信 一.BIO与NIO IO(BIO)和NIO区别:其本质就是阻塞和非阻塞的区别 阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,就会一直等 ...
- qt tcp通信_Qt之网络编程TCP通信
点击上方"Qt学视觉",选择"星标"公众号重磅干货,第一时间送达 想要学习的同学们还请认真阅读每篇文章,相信你一定会有所收获 TCP通信概述 TCP(Trans ...
- java aio socket_java核心学习(三十三) 网络编程---AIO实现异步Socket通信
AIO需要操作系统的支持,在linux内核2.6版本中加入了对真正异步IO的支持,java从jdk1.7开始支持AIO 核心类有AsynchronousSocketChannel .Asynchron ...
- 基于QT的TCP通信
一.简介 TCP通信必须先建立TCP链接,通信端分为客户端和服务器端.QT提供了QTcpServer类和QTcpSocket类用于建立TCP通信应用程序.QTcpServer用于端口监听,建立服务器: ...
- 【Linux】网络编程三:TCP通信和UDP通信介绍及代码编写
参考连接:https://www.nowcoder.com/study/live/504/2/16. [Linux]网络编程一:网络结构模式.MAC/IP/端口.网络模型.协议及网络通信过程简单介绍 ...
- Qt TCP通信(QTcpSocket)
1. 用法 下面以初始化.连接.写.读.断开连接这几个部分来介绍QTcpSocket的用法. 假设在xxx类实现tcp通信. 初始化 /* 初始化 */ void xxx::init() {m_soc ...
- boost:asio与 TCP通信
asio支持TCP.UDP.ICMP等通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好的封装了Socket API TCP 类ip::tcp是asio网络 ...
- 网络编程 UDP通信的过程 TCP通信过程 多线程文件上传
网络概述 协议 在网络之间传出数据时需要按照指定的标准来传输,标准中规定了数据的格式.大小.传输的方式.传输速率.形成统一规范->按照规范开发的代码->协议(应用层.传输层.网络层.链路层 ...
最新文章
- 整图下沉,MindSpore图引擎详解
- BERT入门讲解(内附源码)【自然语言处理NLP-100例】
- 云端的SRE发展与实践
- macbook所有型号大全_苹果笔记本型号大全
- 三年级下册计算机全册教案,小学信息技术三年级下册全册教案.doc
- 初试Octave软件
- 最新QQ邮箱滑块JS逆向教程
- StringUtils一些常用方法
- 分支程序设计05 - 零基础入门学习C语言14
- php实现事件监听与触发的方法
- GStreamer 简化 Linux 多媒体开发
- 以太坊存储项目Swarm (代币bzz)1.0 主网正式上线
- CKEditor与CKFinder学习--安全的使用CKFinder与权限控制
- 网页版python编辑器-史上超强 Python 编辑器,竟然是张网页?!
- Maven分模块管理时com.xx.xx.service等找不到
- 带时间轴的文章归档的html页面,WordPress纯CSS打造时间轴归档页面
- Android SIM卡联系人操作总结
- 简单好用的树莓派磁盘空间管理工具
- 竞态条件(race condition)
- webman apidoc安装、生成接口文档
热门文章
- C++编程问题--glibc detected *** ./a.out: munmap_chunk(): invalid pointer: xxxxxx
- Java基础篇:加入带自变量的方法
- Mobile端Catalog下面Category的配置步骤
- 8月30日学习内容整理:命名空间,作用域,函数名本质,闭包
- C++ STL 学习笔记__(6)优先级队列priority_queue基本操作
- phoenixframework自动化测试平台webUI代码示例
- IOS 学习笔记 2015-03-24 OC-API-不可变字符串
- 简单的重定义一下NSLOG
- 备忘--简单比较SPSS、RapidMiner、KNIME以及Kettle四款数据分析工具
- 【数据科学】什么是数据分析