使用SuperSocket打造逾10万长连接的Socket服务
SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,但是你却可以使用 SuperSocket 很容易的开发出一款 Socket 服务器端软件,例如游戏服务器,GPS 服务器, 工业控制服务和数据采集服务器等等。
PS:上面这句话复制官网的,好了,总之告诉大家SuperSocket已经很强大、很稳定、方便。
如果你没有Socket基础,首先要了解协议;本人两年都在做智能穿戴,接触大量硬件厂商,发现大部分是“带起止符的协议”(BeginEndMarkReceiveFilter)或者“头部格式固定并且包含内容长度的协议”(FixedHeaderReceiveFilter)
我简单介绍这两种协议。

代码上我就二选一介绍FixedHeaderReceiveFilter吧
首先新建项目,在Nuget管理器上搜索“SuperSocket”安装“SuperSocket”和“SuperSocket.Engine”
接下来你需要实现
1、 IRequestInfo(请求信息,一次数据包)
public class MyRequestInfo : IRequestInfo
{
public MyRequestInfo(byte[] header, byte[] bodyBuffer)
{
Key = ((header[] * ) + header[]).ToString();
Data = bodyBuffer;
}
/// <summary>
/// 协议号对应自定义命令Name,会触摸自定义命令
/// </summary>
public string Key { get; set; }
/// <summary>
/// 正文字节码
/// </summary>
public byte[] Data { get; set; }
/// <summary>
/// 正文文本,大部分协议都不是这么玩的
/// </summary>
public string Body
{
get
{
return Encoding.UTF8.GetString(Data);
}
}
}
2、 FixedHeaderReceiveFilter<IRequestInfo>(数据包的解析)
public class MyReceiveFilter : FixedHeaderReceiveFilter<MyRequestInfo>
{
/// +-------+---+-------------------------------+
/// |request| l | |
/// | name | e | request body |
/// | (2) | n | |
/// | |(2)| |
/// +-------+---+-------------------------------+
public MyReceiveFilter()
: base()
{ } protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)
{
return (int)header[offset + ] * + (int)header[offset + ];
} protected override MyRequestInfo ResolveRequestInfo(ArraySegment<byte> header, byte[] bodyBuffer, int offset, int length)
{
var body = bodyBuffer.Skip(offset).Take(length).ToArray();
return new MyRequestInfo(header.Array, body);
}
}
3、 AppSession<TAppSession, TRequestInfo>(Session会话,服务端管理客户端的连接、信息)
public class MySession : AppSession<MySession, MyRequestInfo>
{
public MySession()
{ }protected override void OnSessionStarted()
{ } protected override void OnInit()
{
base.OnInit();
} protected override void HandleUnknownRequest(MyRequestInfo requestInfo)
{ } protected override void HandleException(Exception e)
{ } protected override void OnSessionClosed(CloseReason reason)
{
base.OnSessionClosed(reason);
}
}
4、 AppServer<TAppSession, TRequestInfo>(监听服务)
public class MyServer : AppServer<MySession, MyRequestInfo>
{
/// <summary>
/// 通过配置文件安装服务从这里启动
/// </summary>
public MyServer()
: base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>())
{
this.NewSessionConnected += MyServer_NewSessionConnected;
this.SessionClosed += MyServer_SessionClosed;
}
/// <summary>
/// winform启动,不使用这里的事件
/// </summary>
public MyServer(SessionHandler<MySession> NewSessionConnected, SessionHandler<MySession, CloseReason> SessionClosed)
: base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>())
{
this.NewSessionConnected += NewSessionConnected;
this.SessionClosed += SessionClosed;
} protected override void OnStarted()
{
//启动成功
LogHelper.WriteLog(string.Format("Socket启动成功:{0}:{1}", this.Config.Ip, this.Config.Port));
} void MyServer_NewSessionConnected(MySession session)
{
//连接成功
} void MyServer_SessionClosed(MySession session, CloseReason value)
{ }
}
好了,你可以跑起来
var config = new SuperSocket.SocketBase.Config.ServerConfig()
{
Name = "SSServer",
ServerTypeName = "SServer",
ClearIdleSession= true, //60秒执行一次清理90秒没数据传送的连接
ClearIdleSessionInterval = ,
IdleSessionTimeOut = ,
MaxRequestLength = , //最大包长度
Ip = "Any",
Port = ,
MaxConnectionNumber = ,
};
app = new MyServer(app_NewSessionConnected, app_SessionClosed);
LogHelper.SetOnLog(new LogHelper.LogEvent((m) =>
{
txtAll.Text = string.Join(" ", m, "\r\n");
txtAll.Select(txtAll.TextLength, );
txtAll.ScrollToCaret();
}));
app.Setup(config);
if (!app.Start())
{
LogHelper.WriteLog(string.Format("Socket {0}:{1}启动失败,请检查权限或端口是否被占用!", config.Ip, config.Port));
}

有关性能,本人在本地(笔记本i5 4200H/12G)测试10万连接同时在线,没有问题;当然啦,跟业务有关,比如你要做的是IM群聊,数据到服务端需要频繁计算。
最后我还有一些提示
1、 尽可能使用安装成windows服务,这样性能、稳定性更好;如果前期连接数不大也可用winform中启动
2、 如果终端可选.net,那使用SuperSocket.ClientEngine比自己又重新敲更稳健
3、 心跳包应在终端向服务端发送,服务端响应即可,切勿在服务端向终端发心跳(服务端拥有超时机制,若超时终端重连即可)
4、 如果需要支持WebSocket,参考SuperWebScoket;有的网友直接在WebSocket直接连接SuperSocket立即断开
5、 有的人问怎么传JSON,参照本文图1先把数据转JSON再转byte[]放到正文内容部分
6、 做Socket开发,可能经常需要在十进制、十六进制、256进制之间转换(尤其是在省流量的仅支持2G网络的硬件)
7、如果你在做硬件开发,你所处的电脑又没有外网IP,可使用ngrok反向代理TCP,让别人代理访问你的电脑
有关其他协议或介绍请参考官方文档
http://docs.supersocket.net/v1-6/zh-CN
有关客户端或本例子代码(可直接运行),如果你想先运行看看结果,再自己敲一遍
链接: https://pan.baidu.com/s/1hs09vb2 密码: 4ntg
使用SuperSocket打造逾10万长连接的Socket服务的更多相关文章
- NGINX轻松管理10万长连接 --- 基于2GB内存的CentOS 6.5 x86-64
http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=190176&id=4234854 一 前言 当管理大量连接时,特别 ...
- NGINX轻松管理10万长连接
先说说服务为什么使用HTTPs长连接技术?有如下几个原因:对响应时间要求较高:服务走的是公网,客户端与服务端的TCP建立的三次握手和断开的四次握手都需要40ms左右(真实数据包计算出来的),共需要80 ...
- [NewLife.Net]单机400万长连接压力测试
目标 对网络库NewLife.Net进行单机百万级长连接测试,并持续收发数据,检测网络库稳定性. [2020年8月1日晚上22点] 先上源码:https://github.com/NewLifeX/N ...
- Erlang C1500K长连接推送服务-内存
上篇 Erlang C1500K长连接推送服务-性能 提到:150w连接,使用了23GB内存,每个连接占用15KB,约一半是内核使用. 大概分析一下: 1. Erlang 节点 12GB,内部因为有内 ...
- Erlang C1500K长连接推送服务-性能
Whatsapp已经使用Erlang在生产环境跑到96GB内存单机 3M长连接,参加:WhatsApp的Erlang世界.毕竟业务级别能达到Whatsapp那样极少,现在只有千万级,单机太多挂一台影响 ...
- 轮询、长轮询、长连接、socket连接、WebSocket
轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接. 优点:后端程序编写比较容易. 缺点:请求中有大半是无用,浪费带宽和服务器资源.(而每一次的 HTTP 请求和应答 ...
- 问题追查:QA压测工具http长连接总是被服务端close情况
1. 背景 最近QA对线上单模块进行压测(非全链路压测),http客户端 与 thrift服务端的tcp链接总在一段时间被close. 查看服务端日志显示 i/o timeout. 最后的结果是: q ...
- MarioTCP:一个单机可日30亿的百万并发长连接服务器
原文:http://blog.csdn.net/everlastinging/article/details/10894493 注:如果用此服务器做变长data的传输,请在业务处理函数中为input ...
- 基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器(转)
原文地址:http://www.jt808.com/?p=1282 在开发一个大规模的部标GPS监控平台的时候,就算我们花费再多的时间设计和规划,我们也并不能准确的预测出自己未来的车载终端接入量有多大 ...
随机推荐
- spring 内部工作机制(二)
本章节讲Spring容器从加载配置文件到创建出一个完整Bean的作业流程及参与的角色. Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表, ...
- windows无法启动MySQL服务 错误1067
启动wampmysqld 出现 1067 错误 解决方法:删除在MySQL安装目录下的Data目录中的ib_logfile0和ib_logfile1这两个文件. 重新启动MySQL服务
- Access-Control-Allow-Origin与Ajax跨域
问题 在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题.另一个域名必须在response中添加 Access-Control-Allow-Origin 的header,才能让前者成功 ...
- 改变ListBoxItem选中的颜色
改变ListBoxItem主要是改变的style 下面直接看代码吧!!! <Style TargetType="{x:Type ListBoxItem}"> <S ...
- Linux基础命令讲解(二)
Linux命令基本格式: 命令 [参数] [路径文件] 方括号内容可省略 查看命令帮助手段: 1 man 命令名 (man 还可以获取配置文件,函数的帮助) 2 命令 --help 3 help 命令 ...
- Linux“体检”指标
* { color: #3e3e3e } body { font-family: "Helvetica Neue", Helvetica, "Hiragino Sans ...
- 牛顿插值法及其C++实现
h1 { margin-bottom: 0.21cm } h1.western { font-family: "Liberation Sans", sans-serif; font ...
- 【ASP.NET MVC 学习笔记】- 10 Controller和Action(1)
本文参考:http://www.cnblogs.com/willick/p/3331521.html 1.继承IController接口,示例代码将当前请求的Controller和Action打印到浏 ...
- php+Mysql页面注册代码
页面设置代码:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF- ...
- JAVA基础知识总结:七
一.面向对象编程 1.什么是面向对象? 万物皆对象 案例一:我想吃大盘鸡 面向过程 面向对象 1.我自己去买一只鸡 1.委托一个会砍价的人去帮忙买鸡 2.我自己宰鸡 2.委托一个胆大的人宰鸡 3.我自 ...