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的更多相关文章

  1. 异步tcp通信——APM.Server 消息推送服务的实现

    消息推送服务 服务器推送目前流行就是私信.发布/订阅等模式,基本上都是基于会话映射,消息对列等技术实现的:高性能.分布式可以如下解决:会话映射可采用redis cluster等技术实现,消息对列可使用 ...

  2. 异步tcp通信——APM.Core 服务端概述

    为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...

  3. 异步tcp通信——APM.Core 解包

    TCP通信解包 虽说这是一个老生长谈的问题,不过网上基本很少见完整业务:或多或少都没有写完或者存在bug.接收到的数据包可以简单分成:小包.大包.跨包三种情况,根据这三种情况作相对应的拆包处理,示例如 ...

  4. c#之异步Socket通信

    0.基于上一篇的c#之Socket(同步)通信,在几个大神评论之后,发现是有挺多地方不足的,所以写了一个改进版本的基于c#的异步Socket通信.再加深一下对Socket的使用和理解.其中客户端和服务 ...

  5. C#网络编程TCP通信实例程序简单设计

    C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服务端测试 ...

  6. 【Java TCP/IP Socket】基于NIO的TCP通信(含代码)

    NIO主要原理及使用 NIO采取通道(Channel)和缓冲区(Buffer)来传输和保存数据,它是非阻塞式的I/O,即在等待连接.读写数据(这些都是在一线程以客户端的程序中会阻塞线程的操作)的时候, ...

  7. C# TCP应用编程三 异步TCP应用编程

    利用TcpListener和TcpClient类在同步方式下接收.发送数据以及监听客户端连接时,在操作没有完成之前一直处于阻塞状态,这对于接受.发送数据量不大的情况或者操作勇士较短的情况下是比较方便的 ...

  8. TCP通信

    //网络套接字编程实例,服务器端,TCP通信. #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") #inc ...

  9. 清晰易懂TCP通信原理解析(附demo、简易TCP通信库源码、解决沾包问题等)C#版

    目录 说明 TCP与UDP通信的特点 TCP中的沾包现象 自定义应用层协议 TCPLibrary通信库介绍 Demo演示 未完成功能 源码下载 说明 我前面博客中有多篇文章讲到了.NET中的网络编程, ...

随机推荐

  1. 简单的贴图显示shander

    Shader "ztq/Diffuse" {    Properties {           _Color ("Main Color", Color) =  ...

  2. 生成mif文件的几种方法总结

    mif文件就是存储器初始化文件,即memory initialization file,用来配置RAM或ROM中的数据.生成QuartusII11.0可用的mif文件,有如下几种方式: 方法1:利用Q ...

  3. Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二)

    Solr4.8.0源码分析(21)之SolrCloud的Recovery策略(二) 题记:  前文<Solr4.8.0源码分析(20)之SolrCloud的Recovery策略(一)>中提 ...

  4. JavaScript DES 加密

    最近做网页数据加密工作, 使用CryptoJS v3.1.2 这个JavaScript脚本,网上比较有质量的文章实在太少,经验证加密结果与Asp.net DES加密结果一致 参考文章 https:// ...

  5. 【Java】Java垃圾回收机制

    Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给 ...

  6. 【HDOJ】3459 Rubik 2×2×2

    模拟+DFS. /* 3459 */ #include <cstdio> #include <cstring> #include <cstdlib> #define ...

  7. 【HDOJ】1903 Exchange Rates

    水DP.精度很坑. /* hdoj 1903 */ #include <cstdio> #include <cstring> #include <cstdlib> ...

  8. <未测>源码升级安装glibc和rpm升级glibc

    源码升级安装glibc和rpm升级glibc http://jacklin9.spaces.live.com/blog/cns!A891B52E1182AFB2!346.entry http://bl ...

  9. 高效算法——J 中途相遇法,求和

    ---恢复内容开始--- J - 中途相遇法 Time Limit:9000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Su ...

  10. 对MMU段式转换的理解

    本文将详细介绍MMU段式转换的过程,并在文末附上一篇讲MMU比较详细的文章.具体什么是MMU,什么时段是转换就不在本文讲了,直接戳文末的链接. 首先,进行段式转换的条件.我们要拥有一个虚拟地址,还有一 ...