使用SuperSocket打造逾10万长连接的Socket服务

使用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[0] * 256) + header[1]).ToString();

Data = bodyBuffer;

}

///

/// 协议号对应自定义命令Name,会触摸自定义命令

///

public string Key { get; set; }

///

/// 正文字节码

///

public byte[] Data { get; set; }

///

/// 正文文本,大部分协议都不是这么玩的

///

public string Body

{

get

{

return Encoding.UTF8.GetString(Data);

}

}

}

2、 FixedHeaderReceiveFilter(数据包的解析)

public class MyReceiveFilter : FixedHeaderReceiveFilter

{

/// +-------+---+-------------------------------+

/// |request| l | |

/// | name | e | request body |

/// | (2) | n | |

/// | |(2)| |

/// +-------+---+-------------------------------+

public MyReceiveFilter()

: base(4)

{

}

protected override int GetBodyLengthFromHeader(byte[] header, int offset, int length)

{

return (int)header[offset + 2] * 256 + (int)header[offset + 3];

}

protected override MyRequestInfo ResolveRequestInfo(ArraySegment header, byte[] bodyBuffer, int offset, int length)

{

var body = bodyBuffer.Skip(offset).Take(length).ToArray();

return new MyRequestInfo(header.Array, body);

}

}

3、 AppSession(Session会话,服务端管理客户端的连接、信息)

public class MySession : AppSession

{

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(监听服务)

public class MyServer : AppServer

{

///

/// 通过配置文件安装服务从这里启动

///

public MyServer()

: base(new DefaultReceiveFilterFactory())

{

this.NewSessionConnected += MyServer_NewSessionConnected;

this.SessionClosed += MyServer_SessionClosed;

}

///

/// winform启动,不使用这里的事件

///

public MyServer(SessionHandler NewSessionConnected, SessionHandler SessionClosed)

: base(new DefaultReceiveFilterFactory())

{

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 = 60,

IdleSessionTimeOut = 90,

MaxRequestLength = 2048, //最大包长度

Ip = "Any",

Port = 18888,

MaxConnectionNumber = 100000,

};

app = new MyServer(app_NewSessionConnected, app_SessionClosed);

LogHelper.SetOnLog(new LogHelper.LogEvent((m) =>

{

txtAll.Text = string.Join(" ", m, "\r\n");

txtAll.Select(txtAll.TextLength, 0);

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

相关推荐

上海到武汉顺丰快递要多久,顺丰上海到武汉几天
2022年世界盃女子籃球賽
365体育是正规的吗

2022年世界盃女子籃球賽

06-27 773
槩五笔怎么打
英国365bet官网

槩五笔怎么打

06-28 602