C#Socket服务端框架之SuperSocket教程(二)

一.实现你的AppServer和AppSession

什么是AppSession?

AppSession 代表一个和客户端的逻辑连接,基于连接的操作应该定于在该类之中。你可以用该类的实例发送数据到客户端,接收客户端发送的数据或者关闭连接。

什么是AppServer?

AppServer 代表了监听客户端连接,承载TCP连接的服务器实例。理想情况下,我们可以通过AppServer实例获取任何你想要的客户端连接,服务器级别的操作和逻辑应该定义在此类之中。

创建你的AppSession

  1. 你可以重写基类的方法

    public class TelnetSession : AppSession<TelnetSession>
    {
        protected override void OnSessionStarted()
        {
            this.Send("Welcome to SuperSocket Telnet Server");
        }
    
        protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
        {
            this.Send("Unknow request");
        }
    
        protected override void HandleException(Exception e)
        {
            this.Send("Application error: {0}", e.Message);
        }
    
        protected override void OnSessionClosed(CloseReason reason)
        {
            //add you logics which will be executed after the session is closed
            base.OnSessionClosed(reason);
        }
    }
    

    在上面的代码中,当一个新的连接连接上时,服务器端立即向客户端发送欢迎信息。 这段代码还重写了其它AppSession的方法用以实现自己的业务逻辑。

  2. 你可以根据你的业务需求来给Session类增加新的属性,让我来创建一个将用在游戏服务器中的AppSession类:

    public class PlayerSession :AppSession<PlayerSession>
    {
        public int GameHallId { get; internal set; }
    
        public int RoomId { get; internal set; }
    }
    
  3. 和Command之间的关系

    在上一篇文档中,我们谈到了Command, 现在我们重新来回顾一下这个知识点:

    public class ECHO : CommandBase<AppSession, StringRequestInfo>
    {
        public override void ExecuteCommand(AppSession session, StringRequestInfo requestInfo)
        {
            session.Send(requestInfo.Body);
        }
    }
    

    在这个command代码中,你可以看到类ECHO的父类是CommandBase<AppSession, StringRequestInfo>, 它有一个泛型参数AppSession。 是的,它是默认的AppSession类。 如果你在你的系统中使用你自己建立的AppSession类,那么你必须将你自己定义的AppSession类传进去,否则你的服务器无法发现这个Command:

    public class ECHO : CommandBase<PlayerSession, StringRequestInfo>
    {
        public override void ExecuteCommand(PlayerSession session, StringRequestInfo requestInfo)
        {
            session.Send(requestInfo.Body);
        }
    }
    

创建你的AppServer类型

  1. 如果你想使用你的AppSession作为会话,你必须修改你的AppServer来使用它

    public class TelnetServer : AppServer<TelnetSession>
    {
    
    }
    

    现在 TelnetSession 将可以用在 TelnetServer 的会话中。

  2. 这里也有很多protected方法你可以重写

    public class TelnetServer : AppServer<TelnetSession>
    {
        protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
        {
            return base.Setup(rootConfig, config);
        }
    
        protected override void OnStartup()
        {
            base.OnStartup();
        }
    
        protected override void OnStopped()
        {
            base.OnStopped();
        }
    }
    

优点

实现你自己的AppSession和AppServer允许你根据你业务的需求来方便的扩展SuperSocket,你可以绑定session的连接和断开事件,服务器实例的启动和停止事件。你还可以在AppServer的Setup方法中读取你的自定义配置信息。总而言之,这些功能让你方便的创建一个你所需要的socket服务器成为可能。

二.通过配置启动SuperSocket

为什么要通过配置启动?

  1. 避免硬编码
  2. SuperSocket提供了很多有用的配置选项
  3. 可以充分利用SuperSocket提供的工具

如何使用Bootstrap来通过配置启动SuperSocket

  • SuperSocket配置section SuperSocket使用.NET自带的配置技术,SuperSocket有一个专门的配置Section:

    <configSections>
        <section name="superSocket"
             type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
    </configSections>
    
  • Server实例的配置

    <superSocket>
        <servers>
          <server name="TelnetServer"
              serverType="SuperSocket.QuickStart.TelnetServer_StartByConfig.TelnetServer, SuperSocket.QuickStart.TelnetServer_StartByConfig"
              ip="Any" port="2020">
          </server>
        </servers>
    </superSocket>
    

    现在,我在这里解释配置的服务器节点:

    name: 实例名称
    serverType: 实例运行的AppServer类型
    ip: 侦听ip
    port: 侦听端口
    

    我们将在下一份文档中有关于配置的更加完整的介绍。

  • 使用BootStrap启动SuperSocket

    static void Main(string[] args)
    {
        Console.WriteLine("Press any key to start the server!");
    
        Console.ReadKey();
        Console.WriteLine();
    
        var bootstrap = BootstrapFactory.CreateBootstrap();
    
        if (!bootstrap.Initialize())
        {
            Console.WriteLine("Failed to initialize!");
            Console.ReadKey();
            return;
        }
    
        var result = bootstrap.Start();
    
        Console.WriteLine("Start result: {0}!", result);
    
        if (result == StartResult.Failed)
        {
            Console.WriteLine("Failed to start!");
            Console.ReadKey();
            return;
        }
    
        Console.WriteLine("Press key 'q' to stop it!");
    
        while (Console.ReadKey().KeyChar != 'q')
        {
            Console.WriteLine();
            continue;
        }
    
        Console.WriteLine();
    
        //Stop the appServer
        bootstrap.Stop();
    
        Console.WriteLine("The server was stopped!");
        Console.ReadKey();
    }
    
  • 一些配置示例

  • Server types 节点:

        <superSocket>
            <servers>
              <server name="TelnetServer"
                  serverTypeName="TelnetServer"
                  ip="Any" port="2020">
              </server>
            </servers>
            <serverTypes>
                <add name="TelnetServer" type="SuperSocket.QuickStart.TelnetServer_StartByConfig.TelnetServer, SuperSocket.QuickStart.TelnetServer_StartByConfig"/>
            </serverTypes>
        </superSocket>
    
  • 多服务器实例:

        <superSocket>
            <servers>
              <server name="TelnetServerA"
                  serverTypeName="TelnetServer"
                  ip="Any" port="2020">
              </server>
              <server name="TelnetServerB"
                  serverTypeName="TelnetServer"
                  ip="Any" port="2021">
              </server>
            </servers>
            <serverTypes>
                <add name="TelnetServer" type="SuperSocket.QuickStart.TelnetServer_StartByConfig.TelnetServer, SuperSocket.QuickStart.TelnetServer_StartByConfig"/>
            </serverTypes>
          </superSocket>
    

SuperSocket.SocketService.exe, SuperSocket提供的运行容器

  • 直接使用SuperSocket.SocketService.exe

  • 务必使你的server所需要的所有程序集都和SuperSocket.SocketService.exe在同一目录

  • 将你的SuperSocket配置放置于SuperSocket.SocketService.exe.config文件之中
  • 直接运行"SuperSocket.SocketService.exe",你定义的服务器将会运行

  • 安装SuperSocket.SocketService.exe为Windows服务

通过在命令行下加参数"-i"运行SuperSocket.SocketService.exe,你可以安装它成为一个Windows服务:

SuperSocket.SocketService.exe -i

这个Windows服务的名字定义在配置文件之中,你可以根据你的需要修改它:

<appSettings>
    <add key="ServiceName" value="SuperSocketService" />
</appSettings>

你也可以通过参数"-u"来卸载该服务:

SuperSocket.SocketService.exe -u

三.SuperSocket 基本配置 

一个配置示例

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="superSocket"
                 type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
    </configSections>
    <appSettings>
        <add key="ServiceName" value="SupperSocketService" />
    </appSettings>
    <superSocket>
        <servers>
            <server name="TelnetServerA"
                    serverTypeName="TelnetServer"
                    ip="Any"
                    port="2020">
            </server>
            <server name="TelnetServerB"
                    serverTypeName="TelnetServer"
                    ip="Any"
                    port="2021">
            </server>
        </servers>
        <serverTypes>
            <add name="TelnetServer"
                 type="SuperSocket.QuickStart.TelnetServer_StartByConfig.TelnetServer, SuperSocket.QuickStart.TelnetServer_StartByConfig"/>
        </serverTypes>
    </superSocket>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>
</configuration>

根配置

配置节点 "superSocket" SuperSocket 配置的根节点,它定义了 SuperSocket 所需要的全局参数。 让我们先看下根节点的所有配置属性:

  • maxWorkingThreads: 线程池最大工作线程数量;
  • minWorkingThreads: 线程池最小工作线程数量;
  • maxCompletionPortThreads: 线程池最大完成端口线程数量;
  • minCompletionPortThreads: 线程池最小完成端口线程数量;
  • disablePerformanceDataCollector: 是否禁用性能数据采集;
  • performanceDataCollectInterval: 性能数据采集频率 (单位为秒, 默认值: 60);
  • isolation: SuperSocket 服务器实例隔离级别
    • None - 无隔离
    • AppDomain - 应用程序域级别的隔离,多个服务器实例运行在各自独立的应用程序域之中
    • Process - 进程级别的隔离,多个服务器实例运行在各自独立的进程之中
  • logFactory: 默认logFactory的名字, 所有可用的 log factories定义在子节点 "logFactories" 之中, 我们将会在下面的文档中介绍它;
  • defaultCulture: 整个程序的默认 thread culture,只在.Net 4.5中可用;

服务器实例配置

在根节点中,有一个名为 "servers" 的子节点,你可以定义一个或者多个server节点来代表服务器实例。 这些服务器实例可以是同一种 AppServer 类型, 也可以是不同的类型。

Server 节点的所有属性如下:

  • name: 服务器实例的名称;
  • serverType: 服务器实例的类型的完整名称;
  • serverTypeName: 所选用的服务器类型在 serverTypes 节点的名字,配置节点 serverTypes 用于定义所有可用的服务器类型,我们将在后面再做详细介绍;
  • ip: 服务器监听的ip地址。你可以设置具体的地址,也可以设置为下面的值 Any - 所有的IPv4地址 IPv6Any - 所有的IPv6地址
  • port: 服务器监听的端口;
  • listenBacklog: 监听队列的大小;
  • mode: Socket服务器运行的模式, Tcp (默认) 或者 Udp;
  • disabled: 服务器实例是否禁用了;
  • startupOrder: 服务器实例启动顺序, bootstrap 将按照此值的顺序来启动多个服务器实例;
  • sendTimeOut: 发送数据超时时间;
  • sendingQueueSize: 发送队列最大长度, 默认值为5;
  • maxConnectionNumber: 可允许连接的最大连接数;
  • receiveBufferSize: 接收缓冲区大小;
  • sendBufferSize: 发送缓冲区大小;
  • syncSend: 是否启用同步发送模式, 默认值: false;
  • logCommand: 是否记录命令执行的记录;
  • logBasicSessionActivity: 是否记录session的基本活动,如连接和断开;
  • clearIdleSession: true 或 false, 是否定时清空空闲会话,默认值是 false;
  • clearIdleSessionInterval: 清空空闲会话的时间间隔, 默认值是120, 单位为秒;
  • idleSessionTimeOut: 会话空闲超时时间; 当此会话空闲时间超过此值,同时clearIdleSession被配置成true时,此会话将会被关闭; 默认值为300,单位为秒;
  • security: Empty, Tls, Ssl3. Socket服务器所采用的传输层加密协议,默认值为空;
  • maxRequestLength: 最大允许的请求长度,默认值为1024;
  • textEncoding: 文本的默认编码,默认值是 ASCII;
  • defaultCulture: 此服务器实例的默认 thread culture, 只在.Net 4.5中可用而且在隔离级别为 'None' 时无效;
  • disableSessionSnapshot: 是否禁用会话快照, 默认值为 false.
  • sessionSnapshotInterval: 会话快照时间间隔, 默认值是 5, 单位为秒;
  • keepAliveTime: 网络连接正常情况下的keep alive数据的发送间隔, 默认值为 600, 单位为秒;
  • keepAliveInterval: Keep alive失败之后, keep alive探测包的发送间隔,默认值为 60, 单位为秒;
  • certificate: 这各节点用于定义用于此服务器实例的X509Certificate证书的信息

    它有两种用法:

    • 从文件加载证书

        <certificate filePath="localhost.pfx" password="supersocket" />
      
    • 从本地证书库加载证书

        <certificate storeName="My" storeLocation="LocalMachine" thumbprint="‎f42585bceed2cb049ef4a3c6d0ad572a6699f6f3"/>
      
  • connectionFilter: 定义该实例所使用的连接过滤器的名字,多个过滤器用 ',' 或者 ';' 分割开来。 可用的连接过滤器定义在根节点的一个子节点内,将会在下面的文档中做更多介绍;

  • commandLoader: 定义该实例所使用的命令加载器的名字,多个过滤器用 ',' 或者 ';' 分割开来。 可用的命令加载器定义在根节点的一个子节点内,将会在下面的文档中做更多介绍;

  • logFactory: 定义该实例所使用的日志工厂(LogFactory)的名字。 可用的日志工厂(LogFactory)定义在根节点的一个子节点内,将会在下面的文档中做更多介绍; 如果你不设置该属性,定义在根节点的日志工厂(LogFactory)将会被使用,如果根节点也未定义日志工厂(LogFactory),该实例将会使用内置的 log4net 日志工厂(LogFactory);

  • listeners: 此配置节点用于支持一个服务器实例监听多个IP/端口组合。 此配置节点应该包含一个或者多个拥有一下属性的listener节点:

    ip: the listening ip;
    port: the listening port;
    backlog: the listening back log size;
    security: the security mode (None/Default/Tls/Ssl/...);
    

    例如:

    <server name="EchoServer" serverTypeName="EchoService">
      <listeners>
        <add ip="Any" port="2012" />
        <add ip="IPv6Any" port="2012" />
      </listeners>
    </server>
    
  • receiveFilterFactory: 定义该实例所使用的接收过滤器工厂的名字;

服务器类型配置

服务器类型节点是一个在根节点下面的配置集合。你可以添加一个或者多个拥有属性'name'和'type'的配置元素:

    <serverTypes>
        <add name="TelnetServerType"
             type="SuperSocket.QuickStart.TelnetServer_StartByConfig.TelnetServer, SuperSocket.QuickStart.TelnetServer_StartByConfig"/>
    </serverTypes>

由于上面定一个服务器类型的名称为 "TelnetServerType",你可以将服务器实例节点的属性"serverTypeName"设置为 "TelnetServerType", 用于运行该类型的服务器:

    <server name="TelnetServerA"
            serverTypeName="TelnetServerType"
            ip="Any"
            port="2020">
    </server>

Log Factories 配置

和服务器类型配置节点相同, 一也可以定义一个或者多个L日志工厂(LogFatory) 然后再服务器实例中使用。 唯一的区别是它可以设置在根配置节点上:

<logFactories>
  <add name="ConsoleLogFactory"
       type="SuperSocket.SocketBase.Logging.ConsoleLogFactory, SuperSocket.SocketBase" />
</logFactories>

在根节点设置LogFactory:

<superSocket logFactory="ConsoleLogFactory">
    ...
    ...
</superSocket>

在服务器节点设置LogFactory:

<server name="TelnetServerA"
       logFactory="ConsoleLogFactory"
       ip="Any"
       port="2020">
</server>

配置智能感知提示

SuperSocket 提供了在线的 XSD (XML Schema Document) 来帮助你方便的进行配置。 你只需在你的SuperSocket 配置节中增加三行代码即可:

  <superSocket xmlns="http://schema.supersocket.net/supersocket"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://schema.supersocket.net/supersocket http://schema.supersocket.net/v1-6/supersocket.xsd">
    <!---->
  </superSocket>

然后你就可以在你更新 SuperSocket 配置的时候获得智能感知的自动提示功能:

SuperSocket Configuration Intellisense

SuperSocket Windows 服务的配置

你可能知道, SuperSocket提供了一个可以Windows服务形式运行的容器 "SuperSocket.SocketService.exe".

你可以通过配置来定义此Windows服务的名字:

<appSettings>
    <add key="ServiceName" value="SuperSocketService" />
</appSettings>

它还支持其它针对Windows服务的配置属性:

ServiceDescription: 此Windows服务的描述
ServicesDependedOn: 此服务依赖的其他服务; 此服务价格会在其依赖的服务启动之后再启动; 多个依赖服务用 ',' 或者 ';' 分割

ps:以上内容均转自http://www.supersocket.net/ 

猜你喜欢

转载自blog.csdn.net/a462575515/article/details/93462623
今日推荐