plastkort 0 Posted August 31, 2019 hi! I have been using TWSocket erarlier to create listening sockets, but this is several years back, now i have a case where i need to make it work again. I got it to listen, but it eventually dies after some time, it could be 1 hour or 1 day. I do the following: First i create the listening socket: wsTradingWebHook.addr:='0.0.0.0'; wsTradingWebHook.port:='80'; wsTradingWebHook.Listen; When incoming I do the following: procedure TDataFunctions.wsTradingWebHookSessionAvailable(Sender: TObject; ErrCode: Word); var html : TStringlist; FMySocket : TWSocket; begin FMySocket := Twsocket.create(self); html := TStringlist.Create; with FMySocket do try OnDataAvailable := wsTradingWebHookDataAvailable; HSocket := twsocket(sender).Accept; html.add('<html><head>'); html.add('<title>Welcome to WhaleAlert</title>'); html.add('</head><body>'); html.add('Usage: <br>'); html.add('{ "signal": "short", "message": "short signal on 5 minutes" } <br>'); html.add('{ "signal": "long", "message": "long signal on 5 minutes" } <br>'); html.add('</body></html> sendstr('HTTP/1.1 200 OK'#13#10); sendstr(format('Date: %s GMT+2'#13#10,[formatdatetime('ddd, dd mmm yyyy hh:mm:ss', date)])); sendstr('Server; myserver'#13#10); sendstr('Content-Type: text/html; charset=iso-8859-1'#13#10); sendstr(format('Content-length=%d'#13#10,[length(html.Text)])); sendstr(#13#10); sendstr(html.Text); sendstr(#13#10); finally freeAndNil(html); end; end; When I receive data from the server i handle it like this: ( I just want the json data received, so any data prior to the { and } will be deleted) I am unsure if i need the "TWSocket(sender).Free;" is needed, or the socket will just clean itself, if i try connect with a normal webserver i receive the "info" message, but the client still seem to wait for more data...i.e. the waiting circle keeps spinning... function TDataFunctions.ProcessWebHook(Received : string) : string; var PostCommand : string; begin result := ''; if pos('POST',received) <> 0 then begin PostCommand := received; if (pos('{',PostCommand) <> 0) and (pos('}',PostCommand) <> 0) then begin Delete(postcommand, 1, pred(pos('{',PostCommand))); Result := PostCommand; end; end; end; procedure TDataFunctions.wsTradingWebHookDataAvailable(Sender: TObject; ErrCode: Word); var ProcessedCommand : string; Signal : string; TrayIcon : TRzTrayIcon; UserData : ISuperObject; ReceivedJSON : AnsiString; begin try ProcessedCommand := ProcessWebHook(AnsiString(TSslWSocket(Sender).ReceiveStr)); if (trim(ProcessedCommand) <> '') then try TrayIcon := frmMain.MyTrayicon; UserData := SO(ProcessedCommand); if userdata.s['signal'] = 'short' then begin Signal := userdata.s['message']; AddSignal(signal, false); end; if userdata.s['signal'] = 'long' then begin Signal := userdata.s['message']; AddSignal(signal, true); end; finally TWSocket(sender).Free; end; except AddSignal(ProcessedCommand, false,true); end; end; Share this post Link to post
FPiette 382 Posted August 31, 2019 It looks like you are rewriting HTTP protocol. Why don't you use the HTTP server component. It does everything for you. See sample programs containing HTTP server component. Share this post Link to post
plastkort 0 Posted August 31, 2019 I looked at it, and it seems it needed a HTML folder, I just need to answer a few lines. this works for me. for a short time. but the listening socket seems to die Share this post Link to post
FPiette 382 Posted August 31, 2019 HTTP protocol is more complex than you think... There is also THttpAppSrv component and his demo application OverbyteIcsWebAppServer. THttpAppSrv is more oriented to answer with "computed" responses. Share this post Link to post
plastkort 0 Posted August 31, 2019 1 hour ago, FPiette said: HTTP protocol is more complex than you think... There is also THttpAppSrv component and his demo application OverbyteIcsWebAppServer. THttpAppSrv is more oriented to answer with "computed" responses. That one might do the trick, but i hope it can be simplified. I just require it to receive a POST message, and just reply a simple instruction page on the default. but I would also appreciate if you have any answer to why my listening socket just stops listening after a while, im concerned that this happens on other projects i might be planning to do in the future. are there any sample codes around I can take a look at so i know that i do everything right ? Share this post Link to post
plastkort 0 Posted August 31, 2019 hmm.. it seems this appserver will overcomplicate my simple project.. I did however notice something in your sample files called: OverbyteIcsSrv5 i use "FNewSocket := _TWSocket(sender).Accept;" but i did not apply the FnewSocket := TWSocket(sender).dup is this a very important part i was missing ? also i have added : ShutDown(2); Close; and will see if this allows my server to live longer, note, it's only the listening socket that died earlier, and not the rest of my program. however im not sure if it just stopped listen or something else messed it up Share this post Link to post
FPiette 382 Posted September 1, 2019 Quote is this a very important part i was missing ? Look at TWSocketServer if you want something basic able to listen for client and instanciate new TWSocket for each client. It doesn't do anything special related to HTTP protocol which is handled by THttpSrv component. As you can see there is a full hierarchy of classes each one being more intelligent. TWSocket is below everything, TWSocketServer add support for server features above TWSocket. THttpServer add HTTP protocol support (server side) to TWSocketServer. THttpAppSrv add REST application layer to THttpServer. In this hierarchy, there are some more intermediate classes for "custom", "Line mode", "proxy", "SSL/TLS" and more. 1 Share this post Link to post
Angus Robertson 574 Posted September 1, 2019 As François says, you should be using TWSocketServer which handles aspects of accepting and closing connections, you just plug in your existing onDataAvailable code. Also makes it easier to move to SSL in the future. If you are using the HTTP protocol, there is a new component TSimpleWebSrv in OverbyteIcsSslHttpRest,pas which uses TWSocketServer and adds a simple HTTP protocol, just a few lines of code, ICS uses it for lightweight HTTP servers for OAuth2 and Lets Encrypt. Angus 1 Share this post Link to post
plastkort 0 Posted September 2, 2019 I can take a look at TWSocketServer, I think i used it before, but maybe 6-7 years ago. As a sidenote, i think the shutdown(2) and close did the trick i think. program still accepting connections after 2 days. Share this post Link to post
Angus Robertson 574 Posted September 2, 2019 Years ago I had TWSocketServers running and accepting thousands of short connections a day for a few months at a tine, had to workaround the 49 day GetTickCount wrap around. Now my servers never run for more than 35 days, due to Microsoft being more aggressive with Windows Update and forcing reboots. Angus Share this post Link to post