SuperSocket 1.4系列文档(13) 连接过滤器(Connection Filter)
SuperSocket中连接过滤器(Connection Filter)是用与对客户端连接进行过滤的接口。通过连接过滤器, 你可以允许或者禁止指定来源的客户端对服务器进行连接。
连接过滤器(Connection Filter)接口:
/// <summary>
/// The basic interface of connection filter
/// </summary>
public interface IConnectionFilter
{
/// <summary>
/// Initializes the connection filter
/// </summary>
/// <param name="name">The name.</param>
/// <param name="options">The options.</param>
/// <returns></returns>
bool Initialize(string name, NameValueCollection options);
/// <summary>
/// Gets the name of the filter.
/// </summary>
string Name { get; }
/// <summary>
/// Whether allows the connect according the remote endpoint
/// </summary>
/// <param name="remoteAddress">The remote address.</param>
/// <returns></returns>
bool AllowConnect(IPEndPoint remoteAddress);
}
bool Initialize(string name, NameValueCollection options);
此方法用于初始化连接过滤器, name是Filter的名称, options是配置文件中此connection filter元素的属性。
string Name { get; }
返回Filter的名称
bool AllowConnect(IPEndPoint remoteAddress);
此方法需要实现通过客户端的endpoint来判断是否允许连接服务器。
下面是一个实现了只允许来自某些IP地址段的客户端的连接的连接过滤器:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Text;
using SuperSocket.Common;
using SuperSocket.SocketBase;
namespace SuperSocket.QuickStart.ConnectionFilter
{
public class IPConnectionFilter : IConnectionFilter
{
private Tuple<long, long>[] m_IpRanges;
public bool Initialize(string name, NameValueCollection options)
{
Name = name;
var ipRange = options.GetValue("ipRange");
string[] ipRangeArray;
if (string.IsNullOrEmpty(ipRange)
|| (ipRangeArray = ipRange.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)).Length <= 0)
{
throw new ArgumentException("The ipRange doesn't exist in configuration!");
}
m_IpRanges = new Tuple<long, long>[ipRangeArray.Length];
for (int i = 0; i < ipRangeArray.Length; i++)
{
var range = ipRangeArray[i];
m_IpRanges[i] = GenerateIpRange(range);
}
return true;
}
private Tuple<long, long> GenerateIpRange(string range)
{
var ipArray = range.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
if(ipArray.Length != 2)
throw new ArgumentException("Invalid ipRange exist in configuration!");
return new Tuple<long, long>(ConvertIpToLong(ipArray[0]), ConvertIpToLong(ipArray[1]));
}
private long ConvertIpToLong(string ip)
{
var points = ip.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
if(points.Length != 4)
throw new ArgumentException("Invalid ipRange exist in configuration!");
long value = 0;
long unit = 1;
for (int i = points.Length - 1; i >= 0; i--)
{
value += unit * points[i].ToInt32();
unit *= 256;
}
return value;
}
public string Name { get; private set; }
public bool AllowConnect(IPEndPoint remoteAddress)
{
var ip = remoteAddress.Address.ToString();
var ipValue = ConvertIpToLong(ip);
for (var i = 0; i < m_IpRanges.Length; i++)
{
var range = m_IpRanges[i];
if (ipValue > range.Item2)
return false;
if (ipValue < range.Item1)
return false;
}
return true;
}
}
}
然后你需要更新配置文件来使用这个连接过滤器:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="socketServer" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/>
</configSections>
<appSettings>
<add key="ServiceName" value="EchoService"/>
</appSettings>
<socketServer loggingMode="IndependantFile">
<servers>
<server name="EchoServer"
serviceName="EchoService" ip="Any" port="911" mode="Async"
connectionFilters="IpRangeFilter">
</server>
</servers>
<services>
<service name="EchoService"
type="SuperSocket.QuickStart.EchoService.EchoServer, SuperSocket.QuickStart.EchoService" />
</services>
<connectionFilters>
<connectionFilter name="IpRangeFilter"
type="SuperSocket.QuickStart.ConnectionFilter.IPConnectionFilter, SuperSocket.QuickStart.ConnectionFilter"
ipRange="127.0.1.0-127.0.1.255"/>
</connectionFilters>
</socketServer>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>
在配置文件中启用连接过滤器需要注意两点:
1) 在SuperSocket配置节点中增加connectionFilters子节点,然后添加你新增的connection filter的相应的配置到connectionFilters到节点之中。
2) 在服务器实例节点中增加connectionFilters属性,属性值为你想为该服务器实例启用的connection filter的名称,多个connection filter用逗号隔开。
完成上面的配置,然后启动SuperSocket,你的连接过滤器就生效了。