异步tcp通信——APM.ConsoleDemo
APM测试
俗话说麻雀虽小,五脏俱全。apm虽然简单,但是可以实现单机高性能消息推送(可以采用redis、kafka等改造成大型分布式消息推送服务器)。
测试demo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace APM.ConsoleDemo
{
class Program
{ static void Main(string[] args)
{
Console.Title = "APM.Core test"; Console.WriteLine("输入1测试APM tcp通讯"); Console.WriteLine("输入2测试APM转发"); var str = Console.ReadLine(); if (!string.IsNullOrEmpty(str) && str != "")
{
APMServer();
APMClient();
APMClient();
}
else
{
Task.Factory.StartNew(() =>
{
Thread.Sleep();
ClientProcess();
});
ServerProcess(true);
}
Console.ReadLine();
} private static APM.Core.Server server;
static void ServerProcess(bool falg = false)
{
Console.WriteLine("server test");
server = new APM.Core.Server(, );
server.OnAccepted += Server_OnAccepted;
server.OnMessage += Server_OnReceived;
server.OnDisConnected += Server_OnDisConnected;
server.OnOnError += Server_OnOnError;
server.Start();
Console.WriteLine("server is running...");
if (falg)
{
while (true)
{
Console.ReadLine();
Console.WriteLine(string.Format("serverinfo[ClientCount:{0},ReceiveCount:{1},SendCount:{2}]", server.ClientCount, server.ReceiveCount, server.SendCount));
}
} } private static APM.Core.Client client;
static void ClientProcess()
{ Console.WriteLine("Client test"); var localIP = GetLocalIp() + ":8889"; Console.WriteLine("Client send test");
client = new APM.Core.Client(Guid.NewGuid().ToString("N"), , localIP);
client.OnConnected += Client_OnConnected;
client.OnMessage += Client_OnMessage;
client.OnDisConnected += Client_OnDisConnected;
client.OnError += Client_OnError;
client.Connect(); Console.Title = "APM Server & Client";
Console.WriteLine("MutiClients test");
for (int i = ; i < ; i++)
{
new APM.Core.Client(Guid.NewGuid().ToString("N"), , localIP).Connect();
} } #region server events
private static void Server_OnAccepted(APM.Core.UserToken remote)
{
Console.WriteLine("收到客户端连接:" + remote.Client.RemoteEndPoint); }
private static void Server_OnReceived(APM.Core.UserToken remote, byte[] data)
{
if (server.ClientCount <= )
{
Console.WriteLine("收到客户端消息:" + remote.Client.RemoteEndPoint + " " + Encoding.UTF8.GetString(data));
}
server.SendMsg(remote, "server:hello " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
} private static void Server_OnDisConnected(APM.Core.UserToken remote, Exception ex)
{
Console.WriteLine(string.Format("客户端{0}已断开连接,断开消息:{1}", remote.ID, ex.Message));
} private static void Server_OnOnError(APM.Core.UserToken remote, Exception ex)
{
Console.WriteLine(string.Format("操作客户端{0}异常,断开消息:{1}", remote.ID, ex.Message));
} #endregion #region client events static string msg = "hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohelloh";
private static void Client_OnConnected(APM.Core.Client c)
{
if (c != null)
c.SendMsg(string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); } private static void Client_OnMessage(byte[] data)
{
Console.WriteLine("收到服务器信息:" + Encoding.UTF8.GetString(data));
if (client != null)
client.SendMsg(string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
} private static void Client_OnDisConnected(Exception ex)
{
Console.WriteLine(string.Format("客户端断开连接,断开消息:{0}", ex.Message));
} private static void Client_OnError(Exception ex)
{
Console.WriteLine(string.Format("客户端异常,异常消息:{0}", ex.Message));
} #endregion #region MyRegion
static string GetLocalIp()
{
string hostname = Dns.GetHostName();//得到本机名
//IPHostEntry localhost = Dns.GetHostByName(hostname);//方法已过期,只得到IPv4的地址
IPHostEntry localhost = Dns.GetHostEntry(hostname);
IPAddress localaddr = localhost.AddressList.Where(b => b.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Last();
return localaddr.ToString();
}
#endregion #region APM转发
public static void APMServer()
{
Console.WriteLine("APMServer test");
APM.Server.APMServer server = new Server.APMServer(, );
server.OnAccepted += Server_OnAccepted;
server.OnDisConnected += Server_OnDisConnected;
server.OnError += Server_OnOnError;
server.OnMessage += Server_OnMessage;
server.Start();
Console.WriteLine("APMServer 已启动...");
} private static void Server_OnMessage(Core.Extention.Message msg)
{
Console.WriteLine("APMServer 收到并转发消息:ID {0},Sender {1},SessionID {2},SendTick {3}", msg.ID, msg.Sender, msg.SessionID, msg.SendTick);
} public static void APMClient()
{
Console.WriteLine("APMClient test");
var userID = "张三" + new Random((int)DateTime.Now.Ticks).Next(, );
APM.Client.APMClient apmClient = new Client.APMClient(userID, GetLocalIp(), );
apmClient.OnConnected += ApmClient_OnConnected;
apmClient.OnDisConnected += Client_OnDisConnected;
apmClient.OnError += Client_OnError;
apmClient.OnMessage += APMClient_OnMessage;
apmClient.Connect();
Task.Factory.StartNew(() =>
{
while (true)
{
if (apmClient.Connected)
{
apmClient.SendChannelMsg("all", string.Format("client:{0} {1}", msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
}
Thread.Sleep();
}
});
Console.WriteLine("APMClient:{0} 已连接到服务器", userID);
} private static void ApmClient_OnConnected(Client.APMClient c)
{
c.Subscribe("all");
} private static void APMClient_OnMessage(Core.Extention.Message msg)
{
Console.WriteLine("APMClient 收到消息:ID {0},Sender {1},SessionID {2},SendTick {3}", msg.ID, msg.Sender, msg.SessionID, msg.SendTick);
}
#endregion
}
}
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
如果发现本文有什么问题和任何建议,也随时欢迎交流~
异步tcp通信——APM.ConsoleDemo的更多相关文章
- 异步tcp通信——APM.Server 消息推送服务的实现
消息推送服务 服务器推送目前流行就是私信.发布/订阅等模式,基本上都是基于会话映射,消息对列等技术实现的:高性能.分布式可以如下解决:会话映射可采用redis cluster等技术实现,消息对列可使用 ...
- 异步tcp通信——APM.Core 服务端概述
为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...
- 异步tcp通信——APM.Core 解包
TCP通信解包 虽说这是一个老生长谈的问题,不过网上基本很少见完整业务:或多或少都没有写完或者存在bug.接收到的数据包可以简单分成:小包.大包.跨包三种情况,根据这三种情况作相对应的拆包处理,示例如 ...
- c#之异步Socket通信
0.基于上一篇的c#之Socket(同步)通信,在几个大神评论之后,发现是有挺多地方不足的,所以写了一个改进版本的基于c#的异步Socket通信.再加深一下对Socket的使用和理解.其中客户端和服务 ...
- C#网络编程TCP通信实例程序简单设计
C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试 ...
- 【Java TCP/IP Socket】基于NIO的TCP通信(含代码)
NIO主要原理及使用 NIO采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的I/O,即在等待连接.读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候, ...
- C# TCP应用编程三 异步TCP应用编程
利用TcpListener和TcpClient类在同步方式下接收.发送数据以及监听客户端连接时,在操作没有完成之前一直处于阻塞状态,这对于接受.发送数据量不大的情况或者操作勇士较短的情况下是比较方便的 ...
- TCP通信
//网络套接字编程实例,服务器端,TCP通信. #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #inc ...
- 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版
目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...
随机推荐
- 认识Web和HTTP
一:了解Web. 首先,Web应用的产生起源于1989年,当时CERN(欧洲核子研究组织)的蒂姆·伯纳斯-李(Time BernersLee)博士提出了一种能让远隔两地的研究者们共享知识的设想.借 ...
- 在MAC下 Python+Django+mysql配置
今天在搭建Django+mysql环境的时候遇到了一点问题,记录下来. 安装环境:OS X 10.10操作系统,Python 2.7. MySQLdb其实包含在MySQL-python包中,因此无论下 ...
- 《C和指针》章节后编程练习解答参考——6.1
<C和指针>——6.1 6.1 题目: 编写一个函数,在一个字符串中进行搜索,查找另一子字符串中出现的字符. 函数原型如下: char *find_char(char const *sou ...
- 使用jQuery UI方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Unity3d shader内置矩阵
内置矩阵 支持的矩阵(float4x4):UNITY_MATRIX_MVP 当前模型视图投影矩阵UNITY_MATRIX_MV 当前模型视图矩阵UNITY_MATRI ...
- J2EE开源项目
这篇文章写在我研究J2SE.J2EE近三年后.前3年我研究了J2SE的Swing.Applet.Net.RMI.Collections.IO.JNI……研究了J2EE的JDBC.Sevlet.JSP. ...
- html中混入的特殊字符
从设计那里拿来的psd中常常会有全角的单双引号. 如果只是拷贝这些字符到做好的html里面,顶多看到乱码再加以改正. 但是,如果是通篇的doc,需要加上各种html语义标签,在拷贝来的doc文字之间加 ...
- QS Network
zoj1586:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1586 题目大意:最小生成树,不只算两点之间的费用,还要算点 ...
- Borg Maze poj 3026
Description The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of ...
- linux配置端口转发
一.使用rinted进行端口转发 将10.50.13.13 80请求转到10.50.13.11 80上 1.安装rinetd $ tar zxf rinetd.tar.gz $ cd rinetd $ ...