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,你的连接过滤器就生效了。

posted @ 2011-05-14 11:48  江大渔  阅读(2879)  评论(5编辑  收藏  举报