2013年3月13日

SuperSocket的研究(5)—— 内置的命令行协议

什么是协议

什么是协议?很多人也许会回答“TCP”或“UDP”。但构建一个网络应用仅靠TCP或者UDP是不够的。TCP和UDP都是传输层协议。如果你仅仅定义了传输层协议,是远不能满足让两个终端用户在网络上通信的。你需要定义你的应用层的协议以转换你接收到的二进制数据,使之成为你的应用能理解的请求。

内置的命令行协议

命令行协议是一种被广泛使用的协议,诸如Telnet,SMTP,POP3以及FTP协议等等都是基于命令行协议的。如果你没有自己定制的协议,SuperSocket将默认使用命令行协议,这能够简化这类协议的开发。
命令行协议定义了每一个请求都必须以回车换行符“\r\n”结束。
如果你在SuperSocket中使用命令行协议,所有的请求都将被转换成StringRequestInfo实例。
StringRequestInfo的定义如下:
public class StringRequestInfo
{
    public string Key { get; }

    public string Body { get; }

    public string[] Parameters { get; }

    /*
    其他属性和方法
    */
}
由于SuperSocket内置的命令行协议使用空格来分割请求的命令名和参数,所以当客户端向服务器发送如下的数据时:
"LOGIN kerry 123456" + 换行符
SuperSocket服务器会接收到一个StringRequestInfo实例,该请求信息实例的属性是这样的:
Key: "LOGIN"
Body: "kerry 123456";
Parameters: ["kerry", "123456"]
如果你已经定义了一个名为“LOGIN”的命令,该命令的ExecuteCommand方法就会将StringRequestInfo实例作为参数而被执行:
public class LOGIN : CommandBase<AppSession, StringRequestInfo>
{
    public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo)
    {
        //Implement your business logic
    }
}

定制命令行协议

部分用户可能会需要不同的请求格式,例如:
"LOGIN:kerry,123456" + NewLine
请求的命令名与消息体被“:”隔开,参数责备“,”分开。只需像这样扩展命令行协议,这类请求就能容易地得到支持:
public class YourServer : AppServer<YourSession>
{
    public YourServer()
        : base(new CommandLineReceiveFilterFactory(Encoding.Default, new BasicRequestInfoParser(":", ",")))
    {

    }
}
如果你想更深入地定制请求格式,可以实现继承IRequestInfoParser接口的RequestInfoParser类,然后把你自己的RequesetInfoParser实例在CommandLineReceiveFilterFactory实例初始化时传入:
public class YourServer : AppServer<YourSession>
{
    public YourServer()
        : base(new CommandLineReceiveFilterFactory(Encoding.Default, new YourRequestInfoParser()))
    {

    }
}

文本的编码

命令行协议的默认编码是ASCII,你可以在CommandLineReceiveFilterFactory初始化时改变为其他编码:
public class YourServer : AppServer<YourSession>
{
    public YourServer()
        : base(new CommandLineReceiveFilterFactory(Encoding.UTF8))
    {

    }
}

没有评论:

发表评论