Modularizing SuperSocket Deployment in C#

Wrapping SuperSocket within a dedicated class library enables broader application compatibility, extending functionality beyond simple console utilities to support diverse deployment scenarios. The following guide demonstrates how to implement a reusable Telnet server wrapper.

Project Initialization

Create a new C# Class Libray project named ModularSocketLib. Integrate the necessary SuperSocket dependencies (SuperSocket.Common, SuperSocket.SocketBase, SuperSocket.SocketEngine) and a logging framework such as log4net. Ensure the log4net.config file is configured in the build process: set Build Action to "Content" and Copy Behavior to "Copy if newer". Place the config file in a directory designated for configurations.

Core Service Components

To define the communication logic, create the session handler and server implementations. These classes manage connection states and request processing.

namespace ModularSocketLib.Sockets { public class CustomSession : AppSession<CustomSession> { protected override void OnSessionStarted() { Console.WriteLine($"New Connection Established: {RemoteEndPoint.Address} : {RemoteEndPoint.Port}."); Send("Welcome to the Modular Socket Service."); }

    protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
    {
        Console.WriteLine($"Received unrecognized command key: {requestInfo.Key}.");
        Send("Request not recognized.");
    }

    protected override void HandleException(Exception e)
    {
        Console.WriteLine($"Runtime error detected: {e.Message}.");
        Send($"Error encountered: {e.Message}.");
    }

    protected override void OnSessionClosed(CloseReason reason)
    {
        Console.WriteLine($"Connection terminated: {RemoteEndPoint.Address}:{RemoteEndPoint.Port} Reason: {reason}.");
        base.OnSessionClosed(reason);
    }
}

}


</div><div>```
<code>using System;
using SuperSocket.SocketBase;
using SuperSocket.SocketBase.Config;

namespace ModularSocketLib.Sockets
{
    public class TcpServerInstance : AppServer<CustomSession>
    {
        protected override bool Setup(IRootConfig rootConfig, IServerConfig config)
        {
            Console.WriteLine("Initializing Server Instance...");
            return base.Setup(rootConfig, config);
        }

        protected override void OnStarted()
        {
            Console.WriteLine("Server instance active.");
            base.OnStarted();
        }

        protected override void OnStopped()
        {
            Console.WriteLine("Server instance terminated.");
            base.OnStopped();
        }
    }
}</code>

Implement specific commands to process incoming data strings. Here we define two commands: one for calculation and another for response.

namespace ModularSocketLib.Commands { public class SumCommand : CommandBase<CustomSession, StringRequestInfo> { public override string Name => "TOTAL";

    public override void ExecuteCommand(CustomSession session, StringRequestInfo requestInfo)
    {
        Console.WriteLine($"Executing TOTAL: {requestInfo.Body}.");
        var numbers = requestInfo.Parameters.Select(p => Convert.ToInt32(p)).ToList();
        session.Send(numbers.Sum().ToString());
    }
}

}


</div><div>```
<code>using System;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using ModularSocketLib.Sockets;

namespace ModularSocketLib.Commands
{
    public class MirrorCommand : CommandBase<CustomSession, StringRequestInfo>
    {
        public override string Name => "REPLY";

        public override void ExecuteCommand(CustomSession session, StringRequestInfo requestInfo)
        {
            Console.WriteLine($"Processing REPLY: {requestInfo.Body}.");
            session.Send(requestInfo.Body);
        }
    }
}</code>

The most critical element for packaging is the manager class controlling the Bootstrap lifecycle. Using the Singleton pattern ensures a single active instance across the application domain.

namespace ModularSocketLib { public class SocketHostManager { private readonly IBootstrap _hostBootstrap;

    public bool Initialize(int targetPort)
    {
        if (!_hostBootstrap.Initialize())
        {
            Console.WriteLine("Bootstrap initialization failed.");
            return false;
        }

        var status = _hostBootstrap.Start();
        Console.WriteLine($"Startup Status: {status}.");

        return status == StartResult.Success;
    }

    public void Terminate()
    {
        _hostBootstrap.Stop();
    }

    #region Singleton Implementation

    private static SocketHostManager _singleton;
    private static readonly object SyncRoot = new object();

    private SocketHostManager()
    {
        var assemblyPath = Assembly.GetExecutingAssembly().Location;
        var configPath = $"{assemblyPath}.config";
        _hostBootstrap = BootstrapFactory.CreateBootstrapFromConfigFile(configPath);
    }

    public static SocketHostManager GetInstance()
    {
        if (_singleton != null)
            return _singleton;

        lock (SyncRoot)
        {
            _singleton ??= new SocketHostManager();
        }

        return _singleton;
    }

    #endregion
}

}


</div>Configuration Settings
----------------------

Include an `App.config` file in the library to define server bindings and type mappings.

<div>```
<code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;configuration&gt;
	&lt;configSections&gt;
		&lt;section name="superSocket"
		         type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/&gt;
	&lt;/configSections&gt;

	&lt;!-- Root superSocket node --&gt;
	&lt;superSocket&gt;
		&lt;!-- Server instances --&gt;
		&lt;servers&gt;
			&lt;server name="CustomTelnet" serverTypeName="ServerTypeMap" ip="Any" port="2021"&gt;&lt;/server&gt;
		&lt;/servers&gt;

		&lt;!-- Registered Server Types --&gt;
		&lt;serverTypes&gt;
			&lt;add name="ServerTypeMap" type="ModularSocketLib.Sockets.TcpServerInstance, ModularSocketLib" /&gt;
		&lt;/serverTypes&gt;
	&lt;/superSocket&gt;
&lt;/configuration&gt;</code>

In a separate console application, reference ModularSocketLib. Use the manager to start and stop the service.

namespace SocketDemoApp { class Program { static void Main(string[] args) { try { // Launch service if (!SocketHostManager.GetInstance().Initialize(2021)) { Console.WriteLine("Service launch failure."); Console.ReadLine(); return; }

            Console.WriteLine("Listening on port 2021.");
            Console.WriteLine("Press 'q' to exit.");
            
            char input;
            do
            {
                input = Console.ReadKey().KeyChar;
            } while (input.ToString().ToUpper() != "Q");

            // Stop service
            SocketHostManager.GetInstance().Terminate();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Fatal error: {ex.Message}");
        }

        Console.WriteLine("Process completed.");
        Console.ReadLine();
    }
}

}


</div>

Tags: SuperSocket C# Socket Programming Library Architecture .NET

Posted on Sat, 17 Oct 2026 16:37:03 +0000 by THW