Пример #1
0
        // Initializes the server by preallocating reusable buffers and
        // context objects.  These objects do not need to be preallocated
        // or reused, but it is done this way to illustrate how the API can
        // easily be used to create reusable objects to increase server performance.
        //
        public void Initialize()
        {
            // receive버퍼만 할당해 놓는다.
            // send버퍼는 보낼때마다 할당하든 풀에서 얻어오든 하기 때문에.
            int           pre_alloc_count = 1;
            var           totalBytes      = ServerOpt.MaxConnectionCount * ServerOpt.ReceiveBufferSize * pre_alloc_count;
            BufferManager buffer_manager  = new BufferManager(totalBytes, ServerOpt.ReceiveBufferSize);

            // Allocates one large byte buffer which all I/O operations use a piece of.  This gaurds
            // against memory fragmentation
            buffer_manager.InitBuffer();


            ReceiveEventArgsPool = new SocketAsyncEventArgsPool();
            SendEventArgsPool    = new SocketAsyncEventArgsPool();

            // preallocate pool of SocketAsyncEventArgs objects
            SocketAsyncEventArgs arg;

            for (int i = 0; i < ServerOpt.MaxConnectionCount; i++)
            {
                // 더이상 UserToken을 미리 생성해 놓지 않는다.
                // 다수의 클라이언트에서 접속 -> 메시지 송수신 -> 접속 해제를 반복할 경우 문제가 생김.
                // 일단 on_new_client에서 그때 그때 생성하도록 하고,
                // 소켓이 종료되면 null로 세팅하여 오류 발생시 확실히 드러날 수 있도록 코드를 변경한다.

                // receive pool
                {
                    //Pre-allocate a set of reusable SocketAsyncEventArgs
                    arg            = new SocketAsyncEventArgs();
                    arg.Completed += new EventHandler <SocketAsyncEventArgs>(ReceiveCompleted);
                    arg.UserToken  = null;

                    // assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
                    buffer_manager.SetBuffer(arg);

                    // add SocketAsyncEventArg to the pool
                    ReceiveEventArgsPool.Push(arg);
                }


                // send pool
                {
                    //Pre-allocate a set of reusable SocketAsyncEventArgs
                    arg            = new SocketAsyncEventArgs();
                    arg.Completed += new EventHandler <SocketAsyncEventArgs>(SendCompleted);
                    arg.UserToken  = null;

                    // send버퍼는 보낼때 설정한다. SetBuffer가 아닌 BufferList를 사용.
                    arg.SetBuffer(null, 0, 0);

                    // add SocketAsyncEventArg to the pool
                    SendEventArgsPool.Push(arg);
                }
            }


            ReserveClosingProc.Start(ServerOpt.ReserveClosingWaitMilliSecond);
        }
Пример #2
0
        public void OnSessionClosed(Session token)
        {
            SessionMgr.Remove(token);

            // Free the SocketAsyncEventArg so they can be reused by another client
            // 버퍼는 반환할 필요가 없다. SocketAsyncEventArg가 버퍼를 물고 있기 때문에
            // 이것을 재사용 할 때 물고 있는 버퍼를 그대로 사용하면 되기 때문이다.
            if (ReceiveEventArgsPool != null)
            {
                ReceiveEventArgsPool.Push(token.ReceiveEventArgs);
            }

            if (SendEventArgsPool != null)
            {
                SendEventArgsPool.Push(token.SendEventArgs);
            }

            token.SetEventArgs(null, null);
        }