1. 程式人生 > >Delphi2010中DataSnap高階技術(5)—建立穩定服務程式之TCP心跳包的使用

Delphi2010中DataSnap高階技術(5)—建立穩定服務程式之TCP心跳包的使用

為了能讓我們的服務程式更加穩定,有些細節問題必須解決。就如上一講中提到的客戶端拔掉網線,造成伺服器上TCP變成死連線,如果死連線數量過多,對伺服器能長期穩定執行是一個巨大的威脅。

另外,經過測試,如果伺服器上有TCP死連線,那麼服務程式連線資料庫,也會產生那個一個死連線。這樣的話,給資料庫伺服器也造成威脅。所以,伺服器程式編寫的好壞,直接影響系統的穩定性!

如何解決TCP死連線的問題,有多種方法,其中最有效的就是心跳包技術。

我們在DSServer的OnConnect事件中加入心跳包程式碼

uses IdTCPConnection,IdWinsock2

........

type
  TCP_KeepAlive = record
    OnOff: Cardinal;
    KeepAliveTime: Cardinal;
    KeepAliveInterval: Cardinal;
end;

........

procedure TServerContainer1.DSServer1Connect
  (DSConnectEventObject: TDSConnectEventObject);
var
  Val: TCP_KeepAlive;
  Ret: DWord;
  ClientConnection: TIdTCPConnection;
begin
  ClientConnection := TIdTCPConnection(DSConnectEventObject.ChannelInfo.Id);
  Val.OnOff := 1;
  Val.KeepAliveTime := 5000;
  Val.KeepAliveInterval := 3000;
  WSAIoctl(ClientConnection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4,
    @Val, SizeOf(Val), nil, 0, @Ret, nil, nil);
end;

觀察上述程式碼,我們把心跳包放到服務端上執行,如果伺服器的某個TCP連線在5秒鐘沒有收到資料,將會發送向對端傳送心跳包,間隔3秒鐘,連續傳送5次(引數詳解見上一講高階技術4)。如果5次以後對端還沒有應答,伺服器將結束該TCP連線。TCP的連線可以使用 netstat -p tcp 命令檢視。

當該TCP結束後,delphi編寫的服務程式會自動結束和資料庫的連線。我用的是FireBird資料庫,大家可以使用命令檢視 SELECT MON$USER, MON$REMOTE_ADDRESS,
  MON$REMOTE_PID,
  MON$TIMESTAMP
 FROM MON$ATTACHMENTS

現在伺服器的tcp死連線和資料庫的死連線都清除了,我們的系統將能長期穩定的執行。