zoukankan      html  css  js  c++  java
  • C#SuperSocket的搭建--通过配置启动

    之前我们借助一个SuperSocket实现了一个简易版的服务器, 但是不管是Server还是Session都是使用框架的,本篇博客我们要实现自己的Server和Session,来重写框架原生的Server或Session的方法,或添加自己所需的属性,来实现自己的业务逻辑,并且也不在使用事件来绑定接收,连接,或关闭事件,全部交给Bootstrap来执行,(这个Bootstrap并不是指前端框架的Bootstrap ,而是指的SuperSocket框架的一个引导程序或说是辅助程序),就是这里我们会使用Bootstrap 来配置启动SuperSocket;

    本篇文章皆为我阅读官方文档后总结实现,所以很多代码是直接搬的官方文档的,我的主要目的是为了能实现并运行SuperSocket服务器,所以建议优先阅读官方文档

    官方文档:http://docs.supersocket.net/v1-6/zh-CN

    SuperSocket 是一个轻量级, 跨平台而且可扩展的 .Net/Mono Socket 服务器程序框架。你无须了解如何使用 Socket, 如何维护 Socket 连接和 Socket 如何工作,但是你却可以使用 SuperSocket 很容易的开发出一款 Socket 服务器端软件,例如游戏服务器,GPS 服务器, 工业控制服务和数据采集服务器等等。

    怎么从NuGet安装SuperSocket就不再赘述了,我们直接看实现

    首先我们可以按自己需求定义自己APPSession(因为我也不知道我自己定义的Session中应该有什么方法,什么属性,所以照搬官方文档了~~~)

     1 using SuperSocket.SocketBase;
     2 using SuperSocket.SocketBase.Protocol;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.Linq;
     6 using System.Text;
     7 using System.Threading.Tasks;
     8 
     9 namespace SuperSocket2.Session
    10 {
    11     public class MySession : AppSession<MySession>
    12     {
    13         protected override void OnSessionStarted()
    14         {
    15             this.Send("Welcome to SuperSocket Telnet Server");
    16         }
    17 
    18         protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
    19         {
    20             this.Send("Unknow request");
    21         }
    22 
    23         protected override void HandleException(Exception e)
    24         {
    25             this.Send("Application error: {0}", e.Message);
    26         }
    27 
    28         protected override void OnSessionClosed(CloseReason reason)
    29         {
    30             //add you logics which will be executed after the session is closed
    31             base.OnSessionClosed(reason);
    32         }
    33     }
    34 }
    View Code

    接着按自己需求定义自己APPServer,

     1 using SuperSocket.SocketBase;
     2 using SuperSocket.SocketBase.Config;
     3 using SuperSocket.SocketBase.Protocol;
     4 using SuperSocket2.Session;
     5 using System;
     6 using System.Collections.Generic;
     7 using System.Linq;
     8 using System.Text;
     9 using System.Threading.Tasks;
    10 
    11 namespace SuperSocket2.Server
    12 {
    13     public class MyServer : AppServer<MySession>
    14     {
    15 
    16         public MyServer()
    17             : base(new CommandLineReceiveFilterFactory(Encoding.Default, new BasicRequestInfoParser(":", ",")))
    18         {
    19 
    20         }
    21 
    22         protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
    23         {
    24             return base.Setup(rootConfig, config);
    25         }
    26 
    27         protected override void OnStartup()
    28         {
    29             base.OnStartup();
    30         }
    31 
    32         protected override void OnStopped()
    33         {
    34             base.OnStopped();
    35         }
    36     }
    37 }
    View Code

    自定义的APPserver,在继承APPServer是的Session泛型,记得要更改为我们自定义的Session上一篇文章我们也说道,它默认的请求的 key 和 body 通过字符 ' '  空格分隔, 因需求不同 我们可以将它改为 ':' 分隔 ,而且多个参数被字符 ',' 分隔,所以我们在修改了无参构造函数,来实现拓展命令行协议;

    接下来要做的

    所以我们来自己写一个命令类

     1 using SuperSocket.SocketBase.Command;
     2 using SuperSocket.SocketBase.Protocol;
     3 using SuperSocket2.Session;
     4 using System;
     5 using System.Collections.Generic;
     6 using System.Linq;
     7 using System.Text;
     8 using System.Threading.Tasks;
     9 using System.Windows.Forms;
    10 using System.Threading;
    11 
    12 namespace SuperSocket2.Command
    13 {
    14      /// <summary>
    15      /// 处理请求头为6003的命令
    16      /// </summary>
    17     public class CommandOne : CommandBase<MySession, StringRequestInfo>
    18     {
    19         public override string Name
    20         {
    21             get
    22             {
    23                 return "6003";
    24             }
    25         }
    26 
    27         public override void ExecuteCommand(MySession session, StringRequestInfo requestInfo)
    28         {
    29             //向客户端返回信息,已接受到6003命令
    30             s.Send("Order 6003 received");
    31          }
    32 
    33      }
    34 }
    35     
    View Code

    请求处理代码必须被放置于方法 "ExecuteCommand(TAppSession session, TRequestInfo requestInfo)" 之中,并且属性 "Name" 的值用于匹配接收到请求实例(requestInfo)的Key。当一个请求实例(requestInfo) 被收到时,SuperSocket 将会通过匹配请求实例(requestInfo)的Key和命令的Name的方法来查找用于处理该请求的命令

    但是由于类名的命名必须有字母数字下划线组成,且数字不能开头,如果要接收请求的Key为6003,我们就需要做一些修改

    所以这里我重写了Name方法,这样,请求的Key是6003 也能触发CommandOne命令

    好了,我们的自定义Server,Session,命令都写完了,接下来需要我们使用Bootstrap来配置启动,我们这里只为了保证SuperSocket能正常启动,所以不做多余的配置(☞配置示例)

    修改App.config文件,添加<configuration>节点和<superSocket>节点

     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <configuration>
     3   <configSections>
     4     <section name="superSocket"
     5          type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine" />
     6   </configSections>
     7   <superSocket>
     8     <servers>
     9       <!--serverType中,逗号左边的是你自定义的server在项目中的位置,逗号右边是项目名,ip就是服务器ip,port端口号-->
    10       <server name="TelnetServer"
    11           serverType="SuperSocket2.Server.MyServer,SuperSocket2"
    12           ip="Any" port="3666">
    13       </server>
    14     </servers>
    15   </superSocket>
    16   <startup>
    17     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    18   </startup>
    19 </configuration>

    配置完毕,我们启动程序,在Form_load中实例化bootstrap,启动服务(原谅我懒,实在不愿意对这个Form美化了,就加了一个Richtextbox,显示一下是否初始化成功,启动成功)

     1 using SuperSocket.SocketBase;
     2 using SuperSocket.SocketEngine;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.ComponentModel;
     6 using System.Data;
     7 using System.Drawing;
     8 using System.Linq;
     9 using System.Text;
    10 using System.Threading.Tasks;
    11 using System.Windows.Forms; 
    12 
    13 
    14 
    15 namespace SuperSocket2
    16 {
    17     public partial class Form1 : Form
    18     {
    19         public Form1()
    20         {
    21             InitializeComponent();
    22         }
    23         private void Form1_Load(object sender, EventArgs e)
    24         {   
    25             //声明bootStrap实例
    26             var bootstrap = BootstrapFactory.CreateBootstrap();
    27             //初始化
    28             if (!bootstrap.Initialize())
    29             {
    30                 SetMessage("Failed to initialize!");
    31                 return;
    32             }
    33             //开启服务
    34             var result = bootstrap.Start();
    35 
    36             if (result == StartResult.Failed)
    37             {
    38                 SetMessage("Failed to start!");
    39                
    40                 return;
    41             }
    42             else
    43             {
    44                 SetMessage("服务器启动成功");
    45             }
    46             //bootstrap.Stop();
    47 
    48         }
    49 
    50         public void SetMessage(string msg)
    51         {
    52             this.richTextBox1.Invoke(new Action(() => { this.richTextBox1.AppendText(msg + "
    "); }));
    53         }
    54 
    55     }
    56 }
    View Code

    好,一个简单的,完整的自定义SuperSocket就完成了,我们运行,借助TCP/UDP Socket调试工具执行6003命令试一下

    这里说明一下,SuperSocket框架的命令行协议定义了每个请求必须以回车换行结尾 " ";

    所以我们输完6003:hello命令后,记得加回车;

    测试完成,简易SuperSocket框架搭建成功

    以上为我自己学习总结并实现,有错误之处,希望大家不吝赐教,感谢(抱拳)!

  • 相关阅读:
    记第一场省选
    POJ 2083 Fractal 分形
    CodeForces 605A Sorting Railway Cars 思维
    FZU 1896 神奇的魔法数 dp
    FZU 1893 内存管理 模拟
    FZU 1894 志愿者选拔 单调队列
    FZU 1920 Left Mouse Button 简单搜索
    FZU 2086 餐厅点餐
    poj 2299 Ultra-QuickSort 逆序对模版题
    COMP9313 week4a MapReduce
  • 原文地址:https://www.cnblogs.com/pandefu/p/10911347.html
Copyright © 2011-2022 走看看