[C# - Development] Jolt Environment

Page 3 of 3 FirstFirst 123
Results 31 to 45 of 45
  1. #31
    :-) s-p-n is offline
    DeveloperRank
    Jun 2007 Join Date
    Next DoorLocation
    2,098Posts

    Re: [C# - Development] Jolt Environment

    Nicely Done! Looks like it was thought through very well, head-to-toe ;)

  2. #32
    Ginger by design. jMerliN is offline
    MemberRank
    Feb 2007 Join Date
    2,497Posts

    Re: [C# - Development] Jolt Environment

    Try to avoid equitable division etc. Just pool all the resources together and design your system so that ACTIVE threads go through as few context switches as possible, meaning if 1 thread is active from a thread pool, before it goes back to sleep, it grabs another job if anything is available (assuming the thread pool is powered by a semaphore or something to pick up tasks etc).

    Similarly, if you can assign thread affinity in C# (not sure), it's more efficient if your management scheme is setup this way. Windows may decide that your thread runs on a different core when it wakes up from a blocking state to do something, which causes a context switch. Additionally, your thread pool efficiency only goes down when # of available worker threads exceeds the # of CPUs in the system, so the above mention design choice was accurate.

    And I still say re-design any networking component to use IOCP, with your own thread pool. It can be setup to flow in a wait-free manner which gives a great deal of speed with no resource contention which is perfect for emulator design (though it doesn't scale as well on lots of cores, a more direct thread pool of workers and job queue idea where your IOCP thread simply pulls jobs out of the IOCP's queue and enters them into your internal queue, then waits for more allows for much more async I/O, though it can make the framework much, much more complex to accompany things like async db queries, as it violates the idea of program flow).

  3. #33
    The next don TheAJ is offline
    DeveloperRank
    May 2007 Join Date
    Toronto, CanadaLocation
    3,946Posts

    Re: [C# - Development] Jolt Environment

    Yeah i plan on changing the pooling a bit, I've only tested a single thread on each core, so i don't know how powerful it is yet.

    I plan to change it up a bit, here's an example of how i want it to work:

    there are 50 players
    one thread worker has a minimum player value of 15, a max of 25, and a overload of 50, so right now, when the servers starts up the first thread will doesn't have a minimum value (else wise there'd be errors up my ass), so right now the thread has 50 players, and is overloaded, and now 1 more players logs in, a new worker thread is added, 26 players are now moved to the thread2, and the first thread is now locked until it reaches the minimum player value again, i'm probably not going to transfer the 26 players all at once, but probably one by one via a slave thread or so

    ---------- Post added at 03:41 PM ---------- Previous post was at 01:47 PM ----------

    oh btw

    i also added commands, doesn't interupt the server in any way, unless you use the shutdown command or something


  4. #34
    Enthusiast Splitter is offline
    MemberRank
    Dec 2007 Join Date
    37Posts

    Re: [C# - Development] Jolt Environment

    Nice job man!
    I'm really waiting to see this project finished.

  5. #35
    Mako is insane. ThePhailure772 is offline
    MemberRank
    Sep 2007 Join Date
    1,115Posts

    Re: [C# - Development] Jolt Environment

    Quote Originally Posted by TheAJ View Post
    Yeah i plan on changing the pooling a bit, I've only tested a single thread on each core, so i don't know how powerful it is yet.

    I plan to change it up a bit, here's an example of how i want it to work:

    there are 50 players
    one thread worker has a minimum player value of 15, a max of 25, and a overload of 50, so right now, when the servers starts up the first thread will doesn't have a minimum value (else wise there'd be errors up my ass), so right now the thread has 50 players, and is overloaded, and now 1 more players logs in, a new worker thread is added, 26 players are now moved to the thread2, and the first thread is now locked until it reaches the minimum player value again, i'm probably not going to transfer the 26 players all at once, but probably one by one via a slave thread or so

    ---------- Post added at 03:41 PM ---------- Previous post was at 01:47 PM ----------

    oh btw

    i also added commands, doesn't interupt the server in any way, unless you use the shutdown command or something

    If you're doing C# why not use the Asynchronous built in framework? BeginAccept, BeginSend, BeginRecieve, etc. I have ran a nice server with close to 400 players with no issues using those callbacks. Also, for your log (I didn't look through it much) why are you passing a reference for a string. Is it intended to be edited?

  6. #36
    The next don TheAJ is offline
    DeveloperRank
    May 2007 Join Date
    Toronto, CanadaLocation
    3,946Posts

    Re: [C# - Development] Jolt Environment

    Quote Originally Posted by Theoretical View Post
    If you're doing C# why not use the Asynchronous built in framework? BeginAccept, BeginSend, BeginRecieve, etc. I have ran a nice server with close to 400 players with no issues using those callbacks.
    I'm already using Asynchronous I/O

    Quote Originally Posted by Theoretical View Post
    Also, for your log (I didn't look through it much) why are you passing a reference for a string. Is it intended to be edited?
    No clue what you mean

  7. #37
    Mako is insane. ThePhailure772 is offline
    MemberRank
    Sep 2007 Join Date
    1,115Posts

    Re: [C# - Development] Jolt Environment

    /// <summary>
    /// Prints out a log to the console depending on loglevel.
    /// </summary>
    private void PrintLog(StackFrame sf, LogLevel logLevel, ref string message)

    you're passing a reference.

  8. #38
    The next don TheAJ is offline
    DeveloperRank
    May 2007 Join Date
    Toronto, CanadaLocation
    3,946Posts
    Yeah i thought i needed it since i was editing the next (adding date stamp, etc), i guess not

    Updates:
    - Sends update keys the client if needed
    - Partial login server (only up to check for player in database)

    http://img197.imageshack.us/img197/5609/77701690.jpg

    The logs in gray are debug logs, they will be removed after i'm done with login

    LoginWorker.cs (Thread running the process):
    Code:
    /* ######################################## *\
     * ### Copyright (C) 2009 AJ Ravindiran ### *
    \* ######################################## */
    using System;
    using System.Threading;
    
    using AJRavindiran.Jolt.RuneScape.Models.Characters;
    
    namespace AJRavindiran.Jolt.RuneScape.Workers
    {
        /// <summary>
        /// Represents a worker.
        /// </summary>
        public class LoginWorker
        {
            #region Fields
            private Thread loginWorkerThread;
            #endregion Fields
    
            #region Constructors
            public LoginWorker()
            {
                Jolt.GetLog().WriteInfo("Constructing login worker...");
    
                // Initialize the worker thread, set the normal priority, and start it.
                this.loginWorkerThread = new Thread(new ThreadStart(Run));
                this.loginWorkerThread.Priority = ThreadPriority.Normal;
                this.loginWorkerThread.Start();
            }
            #endregion Constructors
    
            #region Destructors
            #endregion Destructors
    
            #region Methods
            /// <summary>
            /// A thread which runs the login server processor every second.
            /// </summary>
            private void Run()
            {
                while (true)
                {
                    Character[] queuedCharactersArray = new Character[
                        RuneScape.GetLoginServer().GetQueuedCharacters().Count];
                    RuneScape.GetLoginServer().GetQueuedCharacters().CopyTo(queuedCharactersArray);
    
                    foreach (Character c in queuedCharactersArray)
                    {
                        if (c.Online)
                            continue;
    
                        RuneScape.GetLoginServer().Process(c);
    
                        if (c.LoginStage == -1 || (Utilities.TimeUtilities.GetCurrentMilliseconds() - c.LoginTimeout) >= 15000)
                        {
                            RuneScape.GetLoginServer().GetQueuedCharacters().Remove(c);
    
                            if (!c.Online)
                            {
                                RuneScape.GetCharacterManager().UnRegister(c);
                            }
                        }
                    }
    
                    try
                    {
                        Thread.Sleep(100);
                    } 
                    catch (Exception ex) 
                    { 
                        Jolt.GetLog().WriteException(ex); 
                    }
                }
            }
            #endregion Methods
        }
    }
    LoginServer.cs:
    Code:
    /* ######################################## *\
     * ### Copyright (C) 2009 AJ Ravindiran ### *
    \* ######################################## */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using AJRavindiran.Jolt.RuneScape.Models.Characters;
    
    namespace AJRavindiran.Jolt.RuneScape.Network.Login
    {
        /// <summary>
        /// Represents a login server.
        /// </summary>
        public class LoginServer
        {
            #region Fields
            /// <summary>
            /// Container for all queued characters.
            /// </summary>
            private HashSet<Character> queuedCharacters;
    
            private LoginUpdateServer loginUpdateServer;
            private LoginStreamBuffer loginStreamBuffer;
            #endregion Fields
    
            #region Constructors
            /// <summary>
            /// Constructs a new login server class.
            /// </summary>
            public LoginServer()
            {
                Jolt.GetLog().WriteInfo("Constructing login server...");
                // Initialize the container.
                this.queuedCharacters = new HashSet<Character>();
    
                // Initialize sister clases.
                this.loginUpdateServer = new LoginUpdateServer();
                this.loginStreamBuffer = new LoginStreamBuffer();
            }
            #endregion Constructors
    
            #region Methods
            /// <summary>
            /// Attempts to login all the users queued in the container.
            /// </summary>
            /// <param name="character"></param>
            public void Process(Character character)
            {
                try
                {
                    character.ServerSessionKey = ((long)(new Random().NextDouble() * 99999999D) << 32) + (long)(new Random().NextDouble() * 99999999D);
                    character.ClientSessionKey = 0;
                    LoginCodesEnumeration returnCode = LoginCodesEnumeration.LoginOK;
    
                    if (character.LoginStage < -1)
                    {
                        this.loginUpdateServer.SendUpdateKeys(character);
                        Jolt.GetLog().WriteDebug("Sending update keys (login stage -1)");
                    }
                    else if (character.LoginStage == 0)
                    {
                        Jolt.GetLog().WriteDebug("Login stage == 0");
                        try
                        {
                            if (!this.loginStreamBuffer.FillStream(character, 2))
                            {
                                Jolt.GetLog().WriteDebug("FillStream(2) failed.");
                                return;
                            }
                        }
                        catch (Exception) { return; }
    
                        byte connectionType = character.GetStreamReader().ReadByte();
    
                        Jolt.GetLog().WriteDebug("conection type: " + connectionType.ToString());
                        if (connectionType == 15)
                        {
                            this.loginUpdateServer.SendUpdateKeys(character);
                            character.LoginStage = -5;
                            return;
                        }
    
                        if (connectionType != 14)
                        {
                            character.LoginStage = -1;
                            return;
                        }
    
                        byte longPlayerName = character.GetStreamReader().ReadByte();
                        Jolt.GetLog().WriteDebug("Long player name: " + longPlayerName.ToString());
                        character.GetStreamWriter().WriteByte(0);
                        character.GetStreamWriter().WriteLong(character.ServerSessionKey);
                        this.loginStreamBuffer.DirectFlushStream(character);
                        character.LoginStage++;
                    }
                    else if (character.LoginStage == 1)
                    {
                        Jolt.GetLog().WriteDebug("login stage == 1");
                        try
                        {
                            if (!this.loginStreamBuffer.FillStream(character, 3))
                            {
                                Jolt.GetLog().WriteDebug("Fillstream(3) failed.");
                                return;
                            }
                        }
                        catch (Exception) { return; }
    
                        int loginType = character.GetStreamReader().ReadByte();
                        Jolt.GetLog().WriteDebug("login type: " + loginType.ToString());
                        if (loginType != 16 && loginType != 18 && loginType != 14)
                        {
                            character.LoginStage = -1;
                            return;
                        }
    
                        character.LoginStage++;
                    }
                    else if (character.LoginStage == 2)
                    {
                        Jolt.GetLog().WriteDebug("login stage == 2");
                        int loginPacketSize = character.GetStreamReader().ReadUShort();
                        Jolt.GetLog().WriteDebug("login packet size: " + loginPacketSize.ToString());
                        int loginEncryptPacketSize = loginPacketSize - (36 + 1 + 1 + 2);
                        Jolt.GetLog().WriteDebug("login encrypted size: " + loginEncryptPacketSize.ToString());
                        if (loginEncryptPacketSize <= 0)
                        {
                            character.LoginStage = -1;
                            return;
                        }
    
                        try
                        {
                            if (!this.loginStreamBuffer.FillStream(character, loginPacketSize))
                            {
                                Jolt.GetLog().WriteDebug("fillstream(packetsize) failed.");
                                return;
                            }
                        }
                        catch (Exception ex) 
                        {
                            Jolt.GetLog().WriteException(ex);
                            return;
                        }
    
                        int clientVersion = character.GetStreamReader().ReadInt();
                        Jolt.GetLog().WriteDebug("client version: " + clientVersion.ToString());
                        if (clientVersion != 508)
                        {
                            character.LoginStage = -1;
                            return;
                        }
    
                        character.GetStreamReader().ReadByte();
                        character.GetStreamReader().ReadUShort();
                        character.GetStreamReader().ReadUShort();
                        for (int i = 0; i < 24; i++)
                        {
                            int cacheIndex = character.GetStreamReader().ReadByte();
                        }
    
                        string junk = character.GetStreamReader().ReadString();
                        for (int i = 0; i < 29; i++)
                        {
                            int junk2 = character.GetStreamReader().ReadInt();
                        }
    
                        loginEncryptPacketSize--;
                        byte junk29 = character.GetStreamReader().ReadByte();
                        byte encryption = character.GetStreamReader().ReadByte();
                        if (encryption != 10 & encryption != 64)
                        {
                            character.LoginStage = -1;
                            return;
                        }
    
                        character.ClientSessionKey = character.GetStreamReader().ReadLong();
                        character.ServerSessionKey = character.GetStreamReader().ReadLong();
                        character.Username = Utilities.MathUtilities.LongToString(character.GetStreamReader().ReadLong()).ToLower().Trim();
                        if (character.Username == null)
                        {
                            character.LoginStage = -1;
                            character.Username = "null";
                            return;
                        }
                        Jolt.GetLog().WriteDebug("username: " + character.Username);
    
                        for (int i = 0; i < character.Username.Length; i++)
                        {
                            char c = character.Username[i];
                            if (!char.IsLetterOrDigit(c) && !char.IsWhiteSpace(c))
                            {
                                character.LoginStage = -1;
                                character.Username = "null";
                                return;
                            }
                        }
    
                        if (RuneScape.GetCharacterManager().IsOnline(character))
                            returnCode = LoginCodesEnumeration.AlreadyOnline;
                        if (RuneScape.GetOffenceManager().GetBans().IsBanned(character))
                            returnCode = LoginCodesEnumeration.AccountDisabled;
                        if (RuneScape.GetOffenceManager().GetIPBans().IsBanned(character))
                            returnCode = LoginCodesEnumeration.AccountDisabled;
                        if (RuneScape.GetOffenceManager().GetMutes().IsMuted(character))
                            character.Muted = true;
    
                        string password = character.GetStreamReader().ReadString();
                        if (password == null)
                        {
                            character.LoginStage = -1;
                            return;
                        }
                        bool isValid = RuneScape.GetCharacterManager().GetLoader().Execute(character);
                        try
                        {
                            password = Utilities.Security.Cryptography.MD5[password];
                        }
                        catch (Exception ex)
                        {
                            Jolt.GetLog().WriteException(ex);
                            password = "null";
                        }
    
                        if (password != null && character.Password != null && character.Password != "null" && !character.Password.Equals(password) || !isValid)
                            returnCode = LoginCodesEnumeration.InvalidPassword;
    
                        // Set player online database.
    
                        character.GetStreamWriter().WriteByte((int)returnCode);
                        character.GetStreamWriter().WriteByte(character.Rights);
                        character.GetStreamWriter().WriteByte(0);
                        character.GetStreamWriter().WriteByte(0);
                        character.GetStreamWriter().WriteByte(0);
                        character.GetStreamWriter().WriteByte(1);
                        character.GetStreamWriter().WriteByte(0);
                        character.GetStreamWriter().WriteByte(character.ConnectionID);
                        character.GetStreamWriter().WriteByte(0);
                        this.loginStreamBuffer.DirectFlushStream(character);
                    }
                    
                }
                catch (Login.Exceptions.InvalidLoginException ile)
                {
                    throw ile;
                }
            }
    
            /// <summary>
            /// Add a character to the login queue.
            /// </summary>
            /// <param name="character">The player to queue in for login.</param>
            public void AddToLoginQueue(Character character)
            {
                queuedCharacters.Add(character);
            }
    
            /// <summary>
            /// Remove a player from the login queue.
            /// </summary>
            /// <param name="character">The player to queue out from the login.</param>
            public void RemoveFromLoginQueue(Character character)
            {
                queuedCharacters.Remove(character);
            }
    
            /// <summary>
            /// Accessor for the queued players hashset.
            /// </summary>
            /// <returns></returns>
            public HashSet<Character> GetQueuedCharacters()
            {
                return this.queuedCharacters;
            }
    
            /// <summary>
            /// Accessor for the update server class.
            /// </summary>
            /// <returns></returns>
            public LoginUpdateServer GetUpdateServer()
            {
                return this.loginUpdateServer;
            }
    
            /// <summary>
            /// Accessor for the stream buffer class.
            /// </summary>
            /// <returns></returns>
            public LoginStreamBuffer GetStreamBuffer()
            {
                return this.loginStreamBuffer;
            }
            #endregion
        }
    }
    LoginCodeEnumeration.cs:
    Code:
    /* ######################################## *\
     * ### Copyright (C) 2009 AJ Ravindiran ### *
    \* ######################################## */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace AJRavindiran.Jolt.RuneScape.Network.Login
    {
        /// <summary>
        /// Represents the login return codes.
        /// </summary>
        public enum LoginCodesEnumeration : byte
        {
            LoginOK = 2,
            InvalidPassword = 3,
            AccountDisabled = 4,
            AlreadyOnline = 5,
            WorldFull = 6,
            TryAgain = 11
        }
    }
    LoginStreamBuffer.cs:
    Code:
    /* ######################################## *\
     * ### Copyright (C) 2009 AJ Ravindiran ### *
    \* ######################################## */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace AJRavindiran.Jolt.RuneScape.Network.Login
    {
        /// <summary>
        /// Represents a login stream buffer.
        /// </summary>
        public class LoginStreamBuffer
        {
            #region Methods
            /// <summary>
            /// Check and read any incoming bytes.
            /// </summary>
            public bool FillStream(Models.Characters.Character character, int forceRead)
            {
                try
                {
                    if (forceRead >= 500)
                        return false;
                    if (character.GetPlayerSocket().Availible < forceRead)
                        return false;
    
                    character.GetStreamReader().ReadOffset = 0;
                    character.GetPlayerSocket().Read(forceRead);
                    return true;
                }
                catch (StreamException se)
                {
                    Jolt.GetLog().WriteException(se);
                    throw se;
                }
            }
    
            /// <summary>
            /// Send the bytes in the stream's outBuffer directly to the client.
            /// </summary>
            public void DirectFlushStream(Models.Characters.Character character)
            {
                try
                {
                    character.GetPlayerSocket().Write(
                        character.GetStreamWriter().OutBuffer, 0, 
                        character.GetStreamWriter().WriteOffset);
                    character.GetStreamWriter().WriteOffset = 0;
                }
                catch (StreamException se)
                {
                    Jolt.GetLog().WriteException(se);
                    throw se;
                }
            }
            #endregion Methods
        }
    }
    LoginUpdateServer.cs:
    Code:
    /* ######################################## *\
     * ### Copyright (C) 2009 AJ Ravindiran ### *
    \* ######################################## */
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace AJRavindiran.Jolt.RuneScape.Network.Login
    {
        /// <summary>
        /// Represents a login update server.
        /// </summary>
        public class LoginUpdateServer
        {
            #region Fields
            /// <summary>
            /// The update keys needed to update the r508 client.
            /// </summary>
            private int[] updateKeys =
            {            
                0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd8, 
                0x84, 0xa1, 0xa1, 0x2b, 0x00, 0x00, 0x00, 0xba, 
                0x58, 0x64, 0xe8, 0x14, 0x00, 0x00, 0x00, 0x7b, 
                0xcc, 0xa0, 0x7e, 0x23, 0x00, 0x00, 0x00, 0x48, 
                0x20, 0x0e, 0xe3, 0x6e, 0x00, 0x00, 0x01, 0x88, 
                0xec, 0x0d, 0x58, 0xed, 0x00, 0x00, 0x00, 0x71, 
                0xb9, 0x4c, 0xc0, 0x50, 0x00, 0x00, 0x01, 0x8b, 
                0x5b, 0x61, 0x79, 0x20, 0x00, 0x00, 0x00, 0x0c, 
                0x0c, 0x69, 0xb1, 0xc8, 0x00, 0x00, 0x02, 0x31, 
                0xc8, 0x56, 0x67, 0x52, 0x00, 0x00, 0x00, 0x69, 
                0x78, 0x17, 0x7b, 0xe2, 0x00, 0x00, 0x00, 0xc3, 
                0x29, 0x76, 0x27, 0x6a, 0x00, 0x00, 0x00, 0x05, 
                0x44, 0xe7, 0x75, 0xcb, 0x00, 0x00, 0x00, 0x08, 
                0x7d, 0x21, 0x80, 0xd5, 0x00, 0x00, 0x01, 0x58, 
                0xeb, 0x7d, 0x49, 0x8e, 0x00, 0x00, 0x00, 0x0c, 
                0xf4, 0xdf, 0xd6, 0x4d, 0x00, 0x00, 0x00, 0x18, 
                0xec, 0x33, 0x31, 0x7e, 0x00, 0x00, 0x00, 0x01, 
                0xf7, 0x7a, 0x09, 0xe3, 0x00, 0x00, 0x00, 0xd7, 
                0xe6, 0xa7, 0xa5, 0x18, 0x00, 0x00, 0x00, 0x45, 
                0xb5, 0x0a, 0xe0, 0x64, 0x00, 0x00, 0x00, 0x75, 
                0xba, 0xf2, 0xa2, 0xb9, 0x00, 0x00, 0x00, 0x5f, 
                0x31, 0xff, 0xfd, 0x16, 0x00, 0x00, 0x01, 0x48, 
                0x03, 0xf5, 0x55, 0xab, 0x00, 0x00, 0x00, 0x1e, 
                0x85, 0x03, 0x5e, 0xa7, 0x00, 0x00, 0x00, 0x23, 
                0x4e, 0x81, 0xae, 0x7d, 0x00, 0x00, 0x00, 0x18, 
                0x67, 0x07, 0x33, 0xe3, 0x00, 0x00, 0x00, 0x14, 
                0xab, 0x81, 0x05, 0xac, 0x00, 0x00, 0x00, 0x03, 
                0x24, 0x75, 0x85, 0x14, 0x00, 0x00, 0x00, 0x36
            };
            #endregion Fields
    
            #region Methods
            /// <summary>
            /// If the connection is the client's update server than send the keys.
            /// </summary>
            public void SendUpdateKeys(Models.Characters.Character character)
            {
                try
                {
                    if (character.LoginStage == 0)
                    {
                        if (!RuneScape.GetLoginServer().GetStreamBuffer().FillStream(character, 3))
                            return;
                        character.GetStreamWriter().WriteByte(0);
                        RuneScape.GetLoginServer().GetStreamBuffer().DirectFlushStream(character);
                    }
                    else if (character.LoginStage == -5)
                    {
                        if (!RuneScape.GetLoginServer().GetStreamBuffer().FillStream(character, 8))
                            return;
                        for (int i = 0; i < updateKeys.Length; i++)
                            character.GetStreamWriter().WriteByte(updateKeys[i]);
                        RuneScape.GetLoginServer().GetStreamBuffer().DirectFlushStream(character);
                        character.LoginStage = -1;
                    }
                }
                catch (Login.Exceptions.UpdateServerException use)
                {
                    Jolt.GetLog().WriteException(use);
                    throw use;
                }
            }
            #endregion Methods
        }
    }
    Jolt Environment 1.0.2000: http://jolte.codeplex.com/Release/Pr...eleaseId=32148


    Did a bench mark on the server, it's pretty good at handling multiple cores, spreads out evenly:



    Dev blog: http://ajravindiran.com/projects/jolt/

    more login:
    Last edited by CrashOveride; 03-09-09 at 07:06 AM.

  9. #39
    Banned Monsta. is offline
    BannedRank
    Jun 2008 Join Date
    England - MerseLocation
    1,221Posts

    Re: [C# - Development] Jolt Environment

    Uhh.. shouldn't this be in the RS section?

  10. #40
    WowIwasSuperCringeB4 XZeenon is offline
    MemberRank
    Jun 2008 Join Date
    CanadaLocation
    1,405Posts

    Re: [C# - Development] Jolt Environment

    Nice Aj, I've seen you progress a lot, you're doing such a great job! :P

    Quote Originally Posted by Monsta. View Post
    Uhh.. shouldn't this be in the RS section?
    No, because it's in it's development process, and it's being programmed.

  11. #41
    Venture Adventure Tyler is offline
    LegendRank
    Nov 2008 Join Date
    United KingdomLocation
    4,443Posts

    Re: [C# - Development] Jolt Environment

    Quote Originally Posted by Monsta. View Post
    Uhh.. shouldn't this be in the RS section?
    No. As he's focusing on C# and not the game.
    He chose to code the game in C#, but not only RuneScape can be run using this if you read more thoroughly.

  12. #42
    Banned heyhowareya is offline
    BannedRank
    Sep 2009 Join Date
    290Posts

    Re: [C# - Development] Jolt Environment

    yeh! what he said!

  13. #43
    Mako is insane. ThePhailure772 is offline
    MemberRank
    Sep 2007 Join Date
    1,115Posts

    Re: [C# - Development] Jolt Environment

    Why are you doing asynchronous accept and synchronous data sending/reading? You should use asynchronous sending/receiving. Just look into BeginSend and BeginRecieve. Also for backup proof of my statement:
    "The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode." So you should fix that ;3.

  14. #44
    The next don TheAJ is offline
    DeveloperRank
    May 2007 Join Date
    Toronto, CanadaLocation
    3,946Posts

    Re: [C# - Development] Jolt Environment

    Quote Originally Posted by Theoretical View Post
    Why are you doing asynchronous accept and synchronous data sending/reading? You should use asynchronous sending/receiving. Just look into BeginSend and BeginRecieve. Also for backup proof of my statement:
    "The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode." So you should fix that ;3.
    Been working on this since yesterday - I only did synchronous socketing so i can get an accurate result as my older emulator.

  15. #45
    Ginger by design. jMerliN is offline
    MemberRank
    Feb 2007 Join Date
    2,497Posts

    Re: [C# - Development] Jolt Environment

    Quote Originally Posted by Theoretical View Post
    Why are you doing asynchronous accept and synchronous data sending/reading? You should use asynchronous sending/receiving. Just look into BeginSend and BeginRecieve. Also for backup proof of my statement:
    "The TcpClient class provides simple methods for connecting, sending, and receiving stream data over a network in synchronous blocking mode." So you should fix that ;3.
    Sending doesn't really have to be asynchronous, but receiving should be. Async sending doesn't have a performance advantage until you're dealing with a huge number of connections, and even then it's a sore for memory consumption.

    With 10000 connected users (yes, this is EASILY possible in a good emulator), assuming lots of activity, let's say 2-3 packets are queued for each user outgoing.

    If your system isn't really smart with resource usage, you've got ~25,000 buffers dedicated to async operations until they all complete. Depending on how this is setup, that could be quite a lot of memory, and further, if your memory management system isn't top notch, those memory buffers might stick around for a bit before a garbage collector cleans them up (assuming a managed system), or they could be leaked.



Page 3 of 3 FirstFirst 123

Advertisement