使用 IRequestInfo 和 IReceiveFilter 等等其他对象来实现自定义协议

关键字: IRequestInfo, IReceiveFilter, 自定义协议, 请求, 接收过滤器

为什么你要使用自定义协议?

通信协议用于将接收到的二进制数据转化成您的应用程序可以理解的请求。 SuperSocket提供了一个内置的通信协议“命令行协议”定义每个请求都必须以回车换行"\r\n"结尾。

但是一些应用程序无法使用命令行协议由于不同的原因。 这种情况下,你需要使用下面的工具来实现你的自定义协议:

* RequestInfo
* ReceiveFilter
* ReceiveFilterFactory
* AppServer and AppSession

请求(RequestInfo)

RequestInfo 是表示来自客户端请求的实体类。 每个来自客户端的请求都能应该被实例化为 RequestInfo 类型。 RequestInfo 类必须实现接口 IRequestInfo,该接口只有一个名为"Key"的字符串类型的属性:

public interface IRequestInfo
{
    string Key { get; }
}

上面文档提到了, 请求类型 StringRequestInfo 用在 SuperSocket 命令行协议中。

你也可以根据你的应用程序的需要来定义你自己的请求类型。 例如, 如果所有请求都包含 DeviceID 信息,你可以在RequestInfo类里为它定义一个属性:

public class MyRequestInfo : IRequestInfo
{
     public string Key { get; set; }

     public int DeviceId { get; set; }

     /*
     // Other properties
     */
}

SuperSocket 还提供了另外一个请求类 "BinaryRequestInfo" 用于二进制协议:

public class BinaryRequestInfo
{
    public string Key { get; }

    public byte[] Body { get; }
}

你可以直接使用此类型 BinaryRequestInfo, 如果他能满足你的需求的话。

接收过滤器(ReceiveFilter)

接收过滤器(ReceiveFilter)用于将接收到的二进制数据转化成请求实例(RequestInfo)。

实现一个接收过滤器(ReceiveFilter), 你需要实现接口 IReceiveFilter:

public interface IReceiveFilter<TRequestInfo>
    where TRequestInfo : IRequestInfo
{
    /// <summary>
    /// Filters received data of the specific session into request info.
    /// </summary>
    /// <param name="readBuffer">The read buffer.</param>
    /// <param name="offset">The offset of the current received data in this read buffer.</param>
    /// <param name="length">The length of the current received data.</param>
    /// <param name="toBeCopied">if set to <c>true</c> [to be copied].</param>
    /// <param name="rest">The rest, the length of the data which hasn't been parsed.</param>
    /// <returns></returns>
    TRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest);

    /// <summary>
    /// Gets the size of the left buffer.
    /// </summary>
    /// <value>
    /// The size of the left buffer.
    /// </value>
    int LeftBufferSize { get; }

    /// <summary>
    /// Gets the next receive filter.
    /// </summary>
    IReceiveFilter<TRequestInfo> NextReceiveFilter { get; }

    /// <summary>
    /// Resets this instance to initial state.
    /// </summary>
    void Reset();
}

这儿有很多种情况需要你处理:

接收过滤器工厂(ReceiveFilterFactory)

接收过滤器工厂(ReceiveFilterFactory)用于为每个会话创建接收过滤器. 定义一个过滤器工厂(ReceiveFilterFactory)类型, 你必须实现接口 IReceiveFilterFactory. 类型参数 "TRequestInfo" 是你要在整个程序中使用的请求类型

/// <summary>
/// Receive filter factory interface
/// </summary>
/// <typeparam name="TRequestInfo">The type of the request info.</typeparam>
public interface IReceiveFilterFactory<TRequestInfo> : IReceiveFilterFactory
    where TRequestInfo : IRequestInfo
{
    /// <summary>
    /// Creates the receive filter.
    /// </summary>
    /// <param name="appServer">The app server.</param>
    /// <param name="appSession">The app session.</param>
    /// <param name="remoteEndPoint">The remote end point.</param>
    /// <returns>
    /// the new created request filer assosiated with this socketSession
    /// </returns>
    IReceiveFilter<TRequestInfo> CreateFilter(IAppServer appServer, IAppSession appSession, IPEndPoint remoteEndPoint);
}

你也可以直接使用默认的过滤器工厂(ReceiveFilterFactory)

DefaultReceiveFilterFactory<TReceiveFilter, TRequestInfo>

, 当工厂的CreateFilter方法被调用时,它将会调用TReceiveFilter类型的无参构造方法来创建并返回TReceiveFilter.

和 AppSession,AppServer 配合工作

现在, 你已经有了 RequestInfo, ReceiveFilter 和 ReceiveFilterFactory, 但是你还没有正式使用它们. 如果你想让他们在你的程序里面可用, 你需要定义你们的 AppSession 和 AppServer 来使用他们.

完成上面两件事情,你的自定义协议就应该可以工作了。