Search code examples
c#socketstcpsystem.net.socketssupersocket.net

C# SuperSocket without protocol


The question is simple: I've read the whole SuperSocket documentation but I don't understand if there is a way to use it without implement a protocol.

I don't need to send specific commands but only bytes which might be one or hundreds, depending by many factors. I need to renew an old TCP server that uses simple sockets, it was made by me using System.Net.Sockets libs more than 4 years ago and I'd like to realize a stronger solution using a well note library as SuperSocket is.

Is it a good idea?

Thank you in advance.


Solution

  • You don't have to implement a protocol, you can simply create a ReceiveFilter by implementing the interface: IReceiveFilter.

    So first create a custom RequestInfo class like the one below:

    public class MyRequestInfo : IRequestInfo
    {
        public string Key { get; set; }
        public string Unicode { get; set; }
    
        // You can add more properties here
    }
    

    Then create the ReceiveFilter - the ReceiveFilter is basically the class which filters all incoming messages. This is what you need if you don't want to implement a protocol.

    public class MyReceiveFilter: IReceiveFilter<MyRequestInfo>
    {
    
    // This Method (Filter) is called whenever there is a new request from a connection/session 
    //- This sample method will convert the incomming Byte Array to Unicode string
    
        public MyRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest)
        {
            rest = 0;
    
            try
            {
                var dataUnicode = Encoding.Unicode.GetString(readBuffer, offset, length);
                var deviceRequest = new MyRequestInfo { Unicode = dataUnicode };
                return deviceRequest;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    
        public void Reset()
        {
            throw new NotImplementedException();
        }
    
        public int LeftBufferSize { get; }
        public IReceiveFilter<MyRequestInfo> NextReceiveFilter { get; }
        public FilterState State { get; }
    }
    

    Next Step is to create a custom AppSession. Session is like when a client connects the server creates a session for it, and is destroyed when the client disconnects or when the server closes the connection. This is good for situations when you need the client to connect and then the server has to send ACKnowledgment for the client to send the next message.

    public class MyAppSession : AppSession<MyAppSession, MyRequestInfo>
    {
        // Properties related to your session.
    
        public int ClientKey { get; set; }
    
        public string SomeProperty { get; set; }
    
    }
    

    And the Final Step is to create your custom AppServer

    // Here you will be telling the AppServer to use MyAppSession as the default AppSession class and the MyRequestInfo as the defualt RequestInfo
    
    public class MyAppServer : AppServer<MyAppSession, MyRequestInfo>
    {
    // Here in constructor telling to use MyReceiveFilter and MyRequestInfo
    
        protected MyAppServer() : base(new DefaultReceiveFilterFactory<MyReceiveFilter, MyRequestInfo>())
        {
            NewRequestReceived += ProcessNewMessage;
        }
    
        // This method/event will fire whenever a new message is received from the client/session
        // After passing through the filter
        // the requestInfo will contain the Unicode string
        private void ProcessNewMessage(MyAppSession session, MyRequestInfo requestinfo)
        {
            session.ClientKey = SessionCount;
    
            // Here you can access the Unicode strings that where generated in the MyReceiveFilter.Filter() Method.
    
            Console.WriteLine(requestinfo.Unicode );
    
            // Do whatever you want
    
            session.Send("Hello World");
    
    
            session.Close();
        }
    }
    

    You can also override other methods of the AppServer class like: OnSessionClosed or OnNewSessionConnected

    That's it - then you just have to initialise and start the server:

                var myAppServer = new MyAppServer();
    
                if (!myAppServer.Setup(2012))
                {
                    _logger.LogMessage(MessageType.Error, string.Format("Failed to setup server"));
                    return;
                }
                if (!myAppServer.Start())
                {
                    _logger.LogMessage(MessageType.Error, string.Format("Failed to start server"));
                    return;
                }