SuperSocket教程C#/.Net core/.Net 5使用SuperSocket2.0开发Socket服务附带代码实例 net core supersocket
最近看到SuperSocket2.0已经发布了多个预览版了,于是用.Net core 5学习了一下SuperSocket2.0的使用方法,并且编写了一个例子,本例程用到了自定义数据包和自定义过滤器实现将收到的客户端数据返回给客户端,在此分享出来与大家交流学习一下。
首先使用Nuget下载包SuperSocket到你的项目中,注意要勾选预览版,版本选择2.0
1.先简单定义一个数据包类,大家可以根据实际需求修改字段
/// <summary>
/// 自定义数据包
/// </summary>
public class DataPackage
{
/// <summary>
/// 功能码
/// </summary>
public int FCode { get; set; } = -1;
/// <summary>
/// 数据
/// </summary>
public byte[] Datas { get; set; }
}
2.再简单定义一个过滤器,这里是将原始数据转化成数据包类型,这里仅仅是将原始数据取出来,大家可以在Filter方法中根据实际需求修改
/// <summary>
/// 自定义数据过滤器
/// </summary>
public class DataFilter : IPipelineFilter<DataPackage>
{
public IPackageDecoder<DataPackage> Decoder { get; set; }
public object Context { get; set; }
public IPipelineFilter<DataPackage> NextFilter => this;
public DataPackage Filter(ref SequenceReader<byte> reader)
{
DataPackage txtPackage = new DataPackage { Datas = reader.Sequence.ToArray() };
while (reader.TryRead(out _)) ;
return txtPackage;
}
public void Reset() { }
}
3.再定义我们的服务帮助类使用上面的数据包和过滤器启动服务,只要调用里面的RunServer方法就可以启动服务了
/// <summary>
/// 服务帮助类
/// </summary>
public class ServerHelper
{
/// <summary>
/// 使用自定义的数据包和过滤器创建的服务宿主
/// </summary>
private readonly ISuperSocketHostBuilder<DataPackage> host = SuperSocketHostBuilder.Create<DataPackage, DataFilter>();
/// <summary>
/// 会话集合
/// </summary>
private readonly ConcurrentDictionary<string, IAppSession> SessionsDict = new ConcurrentDictionary<string, IAppSession>();
/// <summary>
/// 启动Socket服务(只须调用此方法即可启动)
/// </summary>
/// <returns></returns>
public bool RunServer()
{
bool isSuccess = true;
//配置参数
host.ConfigureSuperSocket(options =>
{
options.Name = "PxIotServer";
options.MaxPackageLength = 1024 * 1024;
options.ReceiveBufferSize = 4 * 1024;
options.SendBufferSize = 4 * 1024;
options.ReceiveTimeout = 0;
options.SendTimeout = 500 * 1000;
options.Listeners = new[] { new ListenOptions { Ip = "Any", Port = 7010, BackLog = 1024 } }.ToList();
});
//使用会话的连接和断开事件
host.UseSessionHandler(OnConnectedAsync, OnClosedAsync);
//使用会话的数据接收时间
host.UsePackageHandler(OnPackageAsync);
//启动
host.RunConsoleAsync();
return isSuccess;
}
/// <summary>
/// 停止服务
/// </summary>
/// <returns></returns>
public bool StopServer()
{
bool isSuccess = false;
foreach (var v in SessionsDict)
{
v.Value.CloseAsync(CloseReason.ServerShutdown);
}
SessionsDict.Clear();
return isSuccess;
}
/// <summary>
/// 会话的连接事件
/// </summary>
/// <param name="session"></param>
/// <returns></returns>
private async ValueTask OnConnectedAsync(IAppSession session)
{
await Task.Run(() =>
{
while (!SessionsDict.ContainsKey(session.SessionID))
{
//添加不成功则重复添加
if (!SessionsDict.TryAdd(session.SessionID, session))
Thread.Sleep(1);
}
});
}
/// <summary>
/// 会话的断开事件
/// </summary>
/// <param name="session"></param>
/// <param name="e"></param>
/// <returns></returns>
private async ValueTask OnClosedAsync(IAppSession session, CloseEventArgs e)
{
await Task.Run(() =>
{
while (SessionsDict.ContainsKey(session.SessionID))
{
//移除不成功则重复移除
if (!SessionsDict.TryRemove(session.SessionID, out _))
Thread.Sleep(1);
}
});
}
/// <summary>
/// 数据接收事件
/// </summary>
/// <param name="session"></param>
/// <param name="package"></param>
/// <returns></returns>
private async ValueTask OnPackageAsync(IAppSession session, DataPackage package)
{
await Task.Run(() =>
{
//发送收到的数据
session.SendAsync(package.Datas);
});
}
}
4.最后再调用ServerHelper中的启动函数就可以了
ServerHelper socketApi = new ServerHelper();
socketApi.RunServer();