⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxservercore.pas

📁 Well known and usefull component for delphi 7
💻 PAS
📖 第 1 页 / 共 4 页
字号:
// Due to the design of our ancestor servercore, this property
// allows you to control the low-level socket communications to
// either UDP/IP or TCP/IP. This allows you to design either
// solution from a single design instance unlike all of our
// competitors.
// ============================================================
      property ProtocolToBind: TWhichProtocol read fWhichprotocol
         write fWhichprotocol;
      // =============================================================
      // This property provides a mechanism that allows you to specify
      // a specific IP for this instance of TDXSock to accept
      // connections on.
      //
      // Note
      // The default is blank, which allows the server to listen to
      // all IP addresses found to the current NIC.
      // =============================================================
      property BindTo: string read fsBindTo
         write fsBindTo;
      // ============================================================
// All servers listen on a port for incomming connection
// requests. By default our ancestor servercore sets this to
// zero, so you do not make a mistake in your final application
// build you must set this to a non-zero port number. If you
// leave this value at zero, the operating system will
// dynamically use the next available port number over 1024 for
// the current instance of the listener. This number is
// dynamically picked between 1024 and 65536 on most windows
// \operating systems if you forget to set the serverport to a
// non-zero value.
// ============================================================
      property ServerPort: Integer read fiServerPort
         write fiServerPort;
      // ==========================================================
// This property provides you with a mechanism to verify that
// the listener thread is running.
// ==========================================================
      property IsActive: Boolean read fbActive;
      // =========================================================================================
// This property <LINK TDXServerCore.Pause, pauses> and <LINK TDXServerCore.Resume, resumes>
// the listener thread.
// =========================================================================================
      property Suspend: Boolean read fbSuspend
         write SetSuspend;
      property UseSSL: Boolean read fbSSL
         write fbSSL;
      // ========================================================
      // This routine provides a mechanism for toggling the Nagel
      // algorithm on or off for the socket layer.
      //
      // Note
      // By default it is enabled in the DXSock suite.
      // ========================================================
      property UseNagle: Boolean read fbNagle
         write fbNagle;
      // ============================================================
// If this property is true, the listener thread will create a
// threadpool of ThreadCacheSize suspended client threads. If
// this property is false then ThreadCacheSize is the number of
// maximum conncurrent client sessions.
// ============================================================
      property UseThreadPool: TDXThreePointBoolean{Boolean} read fbBufferCreates
         write fbBufferCreates;
      // =============================================================
      // Internally all output routines use a chunking technique, this
      // property allows you to specify how much data per output call
      // to send to the actual socket layer buffer.
      //
      //
      // <CODE>
      // bsfRealSmall=128
      // bsfSmall=256
      // bsfNormal=512
      // bsfBigger2048
      // bsfBiggest=4096
      // else use the gloabl constant TDXHugeSize
      // </CODE>
      // =============================================================
      property SocketOutputBufferSize: TDXBlockSizeFlags read fBlockSizeFlags
         write fBlockSizeFlags;
      // ===========================================================
// This is the number of pending client connections that the
// socket layer will hold waiting for the listener thread to
// accept. In Windows 2000 SP3 and older operating systems the
// value range is zero to 10. Later windows operating systems
// and Linux this value can be as large as 100.
//
//
//
// When a client application sends a connect (SYN_CONNECT)
// packet, the socket layer has a queue for pending connection
// requests that the listener thread has not actually accepted
// yet. Unless your application is poorly designed this number
// can be set to 10 (the socket layer default) without ever
// losing an inbound connection.
// ===========================================================
      property SocketQueueSize: Integer read fiListenerQueueSize
         write fiListenerQueueSize;
      // =============================================================
      // TDXSock supports both blocking and non-blocking socket
      // communications. This property was introduced to help
      // developers moving from the Borland sockets to our suite.
      //
      // Note
      // In testing we have found the blocking sockets can transfer
      // more data in less time but having a negative affect on the
      // GUI VCL thread. So if you are developing a GUI based
      // application, we have found that non-blocking sockets are more
      // VCL thread friendly. Also for servers like HTTP, GOPHER and
      // TIME non-blocking sockets are actually faster to accept,
      // receive, send, and disconnect than doing the same process
      // with blocking sockets.
      // =============================================================
      property ServerType: TServerType read fServerType
         write fServerType;
      property Service: string read fDummy
         write fDummy;
      // ============================================================
// This property is actually the maximum number of concurrent
// connections that your application wishes to handle. We used
// the term ThreadCacheSize to avoid implying "ThreadPoolSize".
// This is only the threadpoolsize when UseThreadPool is true,
// \otherwise this is just the number of maximum concurrent
// connections.
// ============================================================
      property ThreadCacheSize: Integer read GetThreadCacheSize
         write SetThreadCacheSize;
      property Timeout: Cardinal read fiTimeout
         write fiTimeout;

      // ===========================================================================================================
      // After the listener thread accepts a new connection, based
      // upon the threading model you have selected the listener
      // assigns the new instance of TDXSock for the current client
      // session to the TDXClientThread and fires this event with the
      // client thread as the parameter for the communication requests
      // and responses to the new client.
      //
      //
      //
      // This allows you to develop your host application more like a
      // single-threaded application, as this event is the starting
      // point for the actual server processes for the client.
      // Descendants to TDXServerCore implement our dynamic command
      // set processor which uses the client thread as a parameter to
      // start negotiations of requests and replies through events.<B>
      //
      //
      //
      // If you are building your own protocol your loop would look
      // something like this:</B>
      // <CODE>
      // While ClientThread.Socket.<LINK TDXSock.Connected, connected> do begin
      //    if ClientThread.Socket.<LINK TDXSock.Readable, readable> then begin
      //       if ClientThread.Socket.<LINK TDXSock.CharactersToRead, CharactersToRead>=0 then Exit; // disconnected
      //       {.. do your read here ..}
      //    end
      //    else begin
      //       DXString.DoSleepEx(1);
      //       DXString.ProcessWindowsMessageQueue;
      //    end;
      // End;
      // </CODE>
      // <B>
      //
      // If you are using one of our existing protocol implementation
      // your code would look like this:</B>
      // <CODE>
      //    DX\<protocolname\>ServerCore.ProcessSession(ClientThread);
      // </CODE>
      //
      // See Also
      // TDXSock, OnMaxConnects, OnWakeUp, OnGoingIdle, OnAsleep
      // ===========================================================================================================
      property OnNewConnect: TDX_NewConnect read feNewConnect
         write feNewConnect;
      // =============================================================
      // This event is only implemented if your host is accepting
      // UDP/IP datagrams in place of TCP/IP, and you do not want to
      // leverage the OnNewConnect design.
      //
      // Note
      // This event is more low-level and provides you with a
      // single-threaded listener design. So all data received from
      // this event should be queued for a background thread to handle
      // as the listener thread can not accept new connections while
      // this event is processing. This is why we provide access to
      // the SocketQueueSize for your server to allow the socket layer
      // to compensate for any delays this event may introduce.
      // =============================================================
      property OnUDPDataNoPool: TDX_UDPData read feUDPData
         write feUDPData;
      // =============================================================
// Based upon the ThreadCacheSize event, if your listener has a
// pending inbound connection request but currently has too many
// concurrent connections running this event will fire. Allowing
// you to implement logic to temporarially increase the number
// \of concurrent connections, or to accept the connection and
// respond with a message that the server is currently too busy
// \- or redirect to another server if your are implementing
// load-balancing techniques in your application.
// =============================================================
      property OnMaxConnects: TDX_MaxConnects read feMaxConnects
         write feMaxConnects;
      // =============================================================================================
      // When the listener thread has not received a new client
      // connection request for a small period of time, this event
      // fires to inform your host application that the listener
      // thread is not doing anything so it is about to go into a <LINK TDXServerCore.OnAsleep, sleep>
      // mode. This event is provided as a notification only.
      // =============================================================================================
      property OnGoingIdle: TDX_Idle read feIdle
         write feIdle;
      // =============================================================
      // If the listener thread has not received any client connection
      // requests for a long time, and the OnGoingIdle event has
      // already fired, this event fires to inform your application
      // that the listener is not going to poll for new client
      // connections every 10 milliseconds but slower at every 100
      // milliseconds. The benefit to this design is our servercore
      // produces lower CPU burden when there have not been any new
      // client connections for a while.
      // =============================================================
      property OnAsleep: TDX_Sleep read feSleep
         write feSleep;
      // ===========================================================
// The listener thread will fire this event only after it has
// fired OnAsleep and a new client connection request has been
// detected.
// ===========================================================
      property OnWakeUp: TDX_WakeUp read feWakeUp
         write feWakeUp;
      // ============================================================
      // If you .<LINK TDXServerCore.Start, Start> the listener but
      // for one reason or another the listener can not start, this
      // event fires to provide a mechanism to interrogate the reason
      // and either handle it or notify the operator of the problem.
      // ============================================================
      property OnListenerFailed: TDX_ListenerFailed read feListenerFailed
         write feListenerFailed;
      // =========================================================
// If the listener successfully started this event fires for
// notification purposes.
// =========================================================
      property OnListenerStarted: TNotifyEvent read fListenerStarted
         write fListenerStarted;
      // =======================================================
// If the listener successfully stops this event fires for
// notification purposes.
// =======================================================
      property OnListenerStopped: TNotifyEvent read fListenerStopped
         write fListenerStopped;
      // =============================================================
      // When a new connection is accepted by the listener thread this
      // event can be implemented to do a deny or accept before the
      // connection information is handed to a client thread.
      //
      // Note
      // The listener thread can not accept new connections while this
      // event is processing, so your implementation of this event
      // must return as fast as possible so your server does not miss
      // inbound connection requests. This is why we provide access to
      // the SocketQueueSize for your server to allow the socket layer
      // to compensate for any delays this event may introduce.
      // =============================================================
      property OnAccept: TDX_OnAccept read feAccept write feAccept;
   end;

implementation

uses
   SysUtils,
   DXSocket;

{$WARNINGS OFF}
constructor TDXClientThread.Create(CreateSuspended: Boolean);
begin
   inherited Create(CreateSuspended);
   FreeOnTerminate := True;
   Client := nil;
   fpSessionData := nil;
end;

constructor TDXClientThreadObject.Create(AOwner:TComponent);
begin
   inherited Create(AOwner);
   Client := nil;
   fpSessionData := nil;
end;
{$WARNINGS ON}

{$WARNINGS OFF}
destructor TDXClientThread.Destroy;
begin
   try
      if Assigned(ListenerThreadObject) then
         if Assigned(TDXServerCoreThread(ListenerThreadObject).fSessionTracker) then
            TDXServerCoreThread(ListenerThreadObject).fSessionTracker.UnregisterSession(Self);
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThread.Exception#1',E.Message);
      end;
   end;
   try
      if Assigned(fpSessionData) then
         if assigned(feDestroySessionData) then begin
            feDestroySessionData(Self, fpSessionData);
         end;
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThread.Exception#2',E.Message);
      end;
   end;
   try
      if Assigned(Client) then begin
         Client.Free;
         Client := nil;
      end;
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThread.Exception#3',E.Message);
      end;
   end;
   inherited Destroy;
end;

destructor TDXClientThreadObject.Destroy;
begin
   try
      if Assigned(ListenerThreadObject) then
         if Assigned(TDXServerCoreThread(ListenerThreadObject).fSessionTracker) then
            TDXServerCoreThread(ListenerThreadObject).fSessionTracker.UnregisterSession(TDXClientThread(Self));
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThreadObject.Exception#1',E.Message);
      end;
   end;
   try
      if Assigned(fpSessionData) then
         if assigned(feDestroySessionData) then begin
            feDestroySessionData(TDXClientThread(Self), fpSessionData);
         end;
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThreadObject.Exception#2',E.Message);
      end;
   end;
   try
      if Assigned(Client) then begin
         Client.Free;
         Client := nil;
      end;
   except
      on E: Exception do begin
         ShowMessageWindow('TDXClientThreadObject.Exception#3',E.Message);
      end;
   end;
   inherited Destroy;
end;
{$WARNINGS ON}

function TDXClientThread.GetSessionID: Integer;
begin
   Result := ThreadID;
end;

function TDXClientThreadObject.GetSessionID: Integer;
begin
   Result := GetCurrentThreadID;
end;

///////////////////////////////////////////////////////////////////////////////
//EXECUTE:
//        Once this thread has "Resume"d, execute is called by TThread. This will
//        fire the OnExecute (where the server protocol processes the connection)
//        and once that is finished it fires the OnDisconnet event.
///////////////////////////////////////////////////////////////////////////////

procedure TDXClientThread.Execute;
begin
   try
      while not Terminated do begin
         if Assigned(Client) then begin
            Client.OutputBufferSize := fBlockSizeFlags;
            if Client.ValidSocket then begin
               try
                  TDXServerCoreThread(ListenerThreadObject).fSessionTracker.RegisterSession(Self);
                  if Assigned(feNewConnect) then begin
                     feNewConnect(Self);
                  end;
               finally
                  TDXServerCoreThread(ListenerThreadObject).fSessionTracker.UnRegisterSession(Self);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -