zoukankan      html  css  js  c++  java
  • SuperSocket封装成C#类库

    将SuperSocket封装成类库之后可以将其集成进各种类型的应用,而不仅仅局限于控制台应用程序了,从而应用于不同的场景。这里以TelnetServer为例说明如何进行操作。

    首先,创建一个C#类库项目LibSocketServer,添加SuperSocket引用(SuperSocket.Common.dll,SuperSocket.SocketBase.dll,SuperSocket.SocketEngine.dll),添加默认的日志框架log4net.dll引用。将log4net.config拷贝到项目文件夹的“Config”文件夹,然后设置它的“生成操作”为“内容”,设置它的“复制到输出目录”为“如果较新则复制”。

    其次,添加SuperSocket完整的TelnetServer服务相关类,Socket服务管理类SocketServerManager。其中SocketServerManager对Bootstrap的设置是SuperSocket封装为类库的关键。

    TelnetSession.cs

    using System;
    using SuperSocket.SocketBase;
    using SuperSocket.SocketBase.Protocol;
    
    namespace LibSocketServer.Server
    {
        public class TelnetSession : AppSession<TelnetSession>
        {
            protected override void OnSessionStarted()
            {
                Console.WriteLine($"New Session Connected: {RemoteEndPoint.Address} " +
                                  $"@ {RemoteEndPoint.Port}.");
                Send("Welcome to SuperSocket Telnet Server.");
            }
    
            protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
            {
                Console.WriteLine($"Unknown request {requestInfo.Key}.");
                Send("Unknown request.");
            }
    
            protected override void HandleException(Exception e)
            {
                Console.WriteLine($"Application error: {e.Message}.");
                Send($"Application error: {e.Message}.");
            }
    
            protected override void OnSessionClosed(CloseReason reason)
            {
                Console.WriteLine($"Session {RemoteEndPoint.Address} @ {RemoteEndPoint.Port} " +
                                  $"Closed: {reason}.");
                base.OnSessionClosed(reason);
            }
        }
    }
    

    TelnetServer.cs

    using System;
    using SuperSocket.SocketBase;
    using SuperSocket.SocketBase.Config;
    
    namespace LibSocketServer.Server
    {
        public class TelnetServer : AppServer<TelnetSession>
        {
            protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
            {
                Console.WriteLine("TelnetServer Setup");
                return base.Setup(rootConfig, config);
            }
    
            protected override void OnStarted()
            {
                Console.WriteLine("TelnetServer OnStarted");
                base.OnStarted();
            }
    
            protected override void OnStopped()
            {
                Console.WriteLine();
                Console.WriteLine("TelnetServer OnStopped");
                base.OnStopped();
            }
        }
    }
    

    AddCommand.cs

    using System;
    using System.Linq;
    using LibSocketServer.Server;
    using SuperSocket.SocketBase.Command;
    using SuperSocket.SocketBase.Protocol;
    
    namespace LibSocketServer.Command
    {
        public class AddCommand : CommandBase<TelnetSession, StringRequestInfo>
        {
            public override string Name => "ADD";
            public override void ExecuteCommand(TelnetSession session, StringRequestInfo requestInfo)
            {
                Console.WriteLine($"{Name} command: {requestInfo.Body}.");
                session.Send(requestInfo.Parameters.Select(p => Convert.ToInt32(p)).Sum().ToString());
            }
        }
    }
    

    EchoCommand.cs

    using System;
    using LibSocketServer.Server;
    using SuperSocket.SocketBase.Command;
    using SuperSocket.SocketBase.Protocol;
    
    namespace LibSocketServer.Command
    {
        public class EchoCommand : CommandBase<TelnetSession, StringRequestInfo>
        {
            public override string Name => "ECHO";
            public override void ExecuteCommand(TelnetSession session, StringRequestInfo requestInfo)
            {
                Console.WriteLine($"{Name} command: {requestInfo.Body}.");
                session.Send(requestInfo.Body);
            }
        }
    }
    

    SocketServerManager.cs

    using System;
    using System.Reflection;
    using SuperSocket.SocketBase;
    using SuperSocket.SocketEngine;
    
    namespace LibSocketServer
    {
        public class SocketServerManager
        {
            private readonly IBootstrap _bootstrap;
    
            public bool Startup(int port)
            {
                if (!_bootstrap.Initialize())
                {
                    Console.WriteLine("SuperSocket Failed to initialize!");
                    return false;
                }
    
                var ret = _bootstrap.Start();
                Console.WriteLine($"SuperSocket Start result: {ret}.");
    
                return ret == StartResult.Success;
            }
    
            public void Shutdown()
            {
                _bootstrap.Stop();
            }
    
            #region Singleton
    
            private static SocketServerManager _instance;
            private static readonly object LockHelper = new object();
    
            private SocketServerManager()
            {
                var location = Assembly.GetExecutingAssembly().Location;
                var configFile = $"{location}.config";
                _bootstrap = BootstrapFactory.CreateBootstrapFromConfigFile(configFile);
            }
    
            public static SocketServerManager Instance
            {
                get
                {
                    if (_instance != null)
                    {
                        return _instance;
                    }
    
                    lock (LockHelper)
                    {
                        _instance = _instance ?? new SocketServerManager();
                    }
    
                    return _instance;
                }
            }
    
            #endregion
        }
    }
    

    再次,添加配置文件App.config到类库中,并设置其配置参数。

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    	<configSections>
    		<section name="superSocket"
    		         type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/>
    	</configSections>
    
    	<!-- SuperSocket配置的根节点 -->
    	<superSocket>
    		<!-- 服务器实例 -->
    		<servers>
    			<server name="TelnetServer" serverTypeName="TelnetServerType" ip="Any" port="2021"></server>
    		</servers>
    
    		<!-- 服务器类型 -->
    		<serverTypes>
    			<add name="TelnetServerType" type="LibSocketServer.Server.TelnetServer, LibSocketServer" />
    		</serverTypes>
    	</superSocket>
    </configuration>
    

    最后,创建控制台项目TelnetServerSample,添加项目引用LibSocketServer,然后在Program类中使用SocketServerManager进行SuperSocket的调用。

    Program.cs

    using System;
    using LibSocketServer;
    
    namespace TelnetServerSample
    {
        class Program
        {
            static void Main()
            {
                try
                {
                    //启动SuperSocket
                    if (!SocketServerManager.Instance.Startup(2021))
                    {
                        Console.WriteLine("Failed to start TelnetServer!");
                        Console.ReadKey();
                        return;
                    }
    
                    Console.WriteLine("TelnetServer is listening on port 2021.");
                    Console.WriteLine();
                    Console.WriteLine("Press key 'q' to stop it!");
                    Console.WriteLine();
                    while (Console.ReadKey().KeyChar.ToString().ToUpper() != "Q")
                    {
                        Console.WriteLine();
                    }
    
                    //关闭SuperSocket
                    SocketServerManager.Instance.Shutdown();
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                }
    
                Console.WriteLine();
                Console.WriteLine("TelnetServer was stopped!");
                Console.WriteLine("Press any key to exit...");
                Console.ReadKey();
            }
        }
    }
    

    GitHub Sample

  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/xhubobo/p/14118764.html
Copyright © 2011-2022 走看看