Newsgroups : Borland : borland.public.delphi.internet.winsock : 2007 Nov : Converting working Win32 app to Windows Service - using TServerSocket
| Subject: | Converting working Win32 app to Windows Service - using TServerSocket |
| Posted by: | "Warrick Wilson" (warri..@cwwilson.com) |
| Date: | Tue, 20 Nov 2007 10:48:53 |
I've got a Win32 application that's working. It's got a TServerSocket that's
receiving on a port from an external data feed that comes looking for the
server - it's highly targeted from the origin to the server. It's been
running the past two weeks with no problems, even with "rapid" changes (4 or
5 per minute). It's written using BDS 2006.
I want to convert it to a Windows service, so I've dug up a few articles on
writing Windows services in Delphi, and followed the basic outlines.
Everything's good until I get to the point where I have to fill in the
Execute part. Based on my reading, and my Googling, I've still not gotten
anything to work. And I'll freely admit I'm guessing at some of this - it's
my first serious foray into sockets and services.
My Execute function is here. I've removed some lines that are (likely) not
pertinent. I'd also tried logging some info to a debug log to trace the
progress (sadly, because of the network setup required to get the feed into
our location, I can't tap into it on my dev machine, but it only runs on a
test box that I can't do too much to as far as instrumenting for debug). Any
suggestions or educational info appreciated.
If the socket "works", I get a data file written to a known location. When I
install and start the service, I do not get the data file and I'm curently
getting (using the code shown below) a debug log that stops with one
'checking requests in Execute loop again...' message (i.e. I see everything
I'd expect from start to that point, and that's the last line in the debug
log file, so I'm not getting back to the top of my while not Terminated
loop)
procedure TmyService.ServiceExecute(Sender: TService);
var
path: string;
begin
// Run the service function
WriteDebugLog('Starting ServiceExecute');
// Initialize state machine
fCurrRecvState := recvWaiting;
FCurrMsg := '';
// starts false; set to true after first
// message is received on Server Socket
FMsgReceived := false;
// starts false; set to true when log file
// first log file is written
FOutputWritten := false;
FLastWrittenMsg := '';
// Basic init stuff
fIniFile := ExtractFilePath(ParamStr(0)) + iniFile;
// Read in values from init file
LoadIniSettings;
// Check that the path for the output file exists. If not, create it
path := ExtractFilePath(FOutputFileName);
//TODO: There could be an exception here, should protect against it
try
if not DirectoryExists(path) then
ForceDirectories(path);
except
// Swallows the exception ... BAD, BAD, BAD
end;
// Create a socket
ServerSocket1 := TServerSocket.Create(nil);
ServerSocket1.Active := false;
// ServerSocket1.ServerType := stNonBlocking; // THIS DIDN' WORK
ServerSocket1.ServerType := stThreadBlocking; // THIS ISN"T WORKING
EITHER
ServerSocket1.Port := 7600;
ServerSocket1.OnClientRead := ServerSocket1ClientRead;
// Start the server
StartServer;
WriteDebugLog('starting loop in Execute');
while not Terminated do
begin
Sleep(1000);
WriteDebugLog('checking requests in Execute loop again...');
//ServiceThread.ProcessRequests(false); // DIDN"T WORK WITH THIS
VALUE
ServiceThread.ProcessRequests(true); // DOESN'T WORK WITH THIS
EITHER
end;
// If we stop, stop the server
StopServer;
end;
procedure TmyService.StartServer;
begin
WriteDebugLog('StartServer');
if ServerSocket1.Active then
ServerSocket1.Active := false;
// Reset state machine values
FCurrMsg := '';
FCurrRecvState := recvWaiting;
// Start listening
ServerSocket1.Port := fListenPort;
ServerSocket1.Active := true;
end;
procedure TmyService.StopServer;
begin
ServerSocket1.Active := false;
end;