bugdude 0 Posted April 30 I am a hobbyist on a budget, so I use dated versions of Delphi and Indy (10.3.3 Delphi and the included Indy). I ran into problems with a project which uses TidCustomTCPServer to implement a web server with websocket support using OpenSSL. Basically the issue is that if the server has an active SSL websocket connection and TCPServer.Active is set false, the application stalls and gets locked into a loop in Indy (I think). Looking in the debugger I see that even though StopListeners was already called the recv handler is still being called repeatedly and generating exceptions. The browser code polls the server every 100ms for screen updates so the calls may originate from the client, but the connection does still seem to be active. (project based on sourceforge ThinVNC with SSL added and other things added). saw some notes about this issue in issue in GitHub, but I tried the solution mentioned there and that alone did not help.. (replaced call to AContext.Connection.Disconnect with Binding.CloseSocket call) Q1 - is there a particular code sequence I could follow to block out those active SSL connections before setting active False that would circumvent this problem without upgrading Indy ? Q2 - would upgrading Indy from GitHub fix this specific issue ? Q3 - would the Indy cleanup script work on Delphi 10.3.3 safely ? Q4 - is upgrading Indy likely to break anything else in this older version of Delphi ? Any other ideas or suggestions would be appreciated.. it works partially and I would like to get it stable... Share this post Link to post
Remy Lebeau 1417 Posted April 30 2 hours ago, bugdude said: I am a hobbyist on a budget, so I use dated versions of Delphi and Indy (10.3.3 Delphi and the included Indy). Just because you are on a budget doesn't mean you should use outdated tools. Especially tools that can be obtained for free. 2 hours ago, bugdude said: I ran into problems with a project which uses TidCustomTCPServer to implement a web server with websocket support using OpenSSL. Basically the issue is that if the server has an active SSL websocket connection and TCPServer.Active is set false, the application stalls and gets locked into a loop in Indy (I think). Looking in the debugger I see that even though StopListeners was already called the recv handler is still being called repeatedly and generating exceptions. What you describe sounds like the TCP server threads are not shutting down correctly. There couple be a number of reasons for that to happen. For instance: Are you catching and discarding the exceptions? If so, don't discard them. Rethrow them and let the server handle them. Are you shutting down the server in the main thread, and syncing with the main thread in your server events? If so, that is a guaranteed deadlock. Either shutdown the server from a worker thread so the main thread is free to continue processing sync requests. Or simply get rid of the syncs during shutdown. 2 hours ago, bugdude said: The browser code polls the server every 100ms for screen updates so the calls may originate from the client, but the connection does still seem to be active. (project based on sourceforge ThinVNC with SSL added and other things added). Is the client creating a new connection for each poll? Or reusing connections? 2 hours ago, bugdude said: saw some notes about this issue in issue in GitHub, but I tried the solution mentioned there and that alone did not help.. (replaced call to AContext.Connection.Disconnect with Binding.CloseSocket call) Simply closing the sockets may not be enough. The server has to be allowed to process the closures so it can terminate its worker threads. Besides, TIdTCPServer already calls CloseSocket() internally during its shutdown. At least it does in recent years - it USED to call Disconnect() instead, but that proved to cause problems with OpenSSL connections across thread boundaries. 2 hours ago, bugdude said: Q1 - is there a particular code sequence I could follow to block out those active SSL connections before setting active False that would circumvent this problem without upgrading Indy ? Hard to say without seeing your actual code to see why it is not shutting down correctly. 2 hours ago, bugdude said: Q2 - would upgrading Indy from GitHub fix this specific issue ? Possibly. Again, hard to say without knowing the root cause first. 2 hours ago, bugdude said: Q3 - would the Indy cleanup script work on Delphi 10.3.3 safely ? Define "safely". Is there a particular problem you are thinking of? 2 hours ago, bugdude said: Q4 - is upgrading Indy likely to break anything else in this older version of Delphi ? Known issues are documented in the Update instructions, ie: https://github.com/IndySockets/Indy/wiki/Updating-Indy#delphicbuilderradstudio-101-berlin-and-later Share this post Link to post
bugdude 0 Posted May 1 First off, thanks for answering. You're right on #1, but I do have a fair number of patched up open sourced but abandoned controls that are tricky to get up and running on each new version. I'll try installing community ed on another system with just the controls for this and see if using updated tools resolves this (should've thought of that sooner). Since I added openSSL to a tool originally built without it you're probably right that I have some errant thread shutdown issues (of my own creation). The connection is a long lived websocket connection (just one), but with the client hitting so often I think it gets hit again before the shutdown waittimes can expire and may be talking to a partially torn down object. That was why I wondered if there was a 'clean' way to abort/disconnect the SSL connection from the server side that could be used before trying to set active false on the server. Share this post Link to post
Remy Lebeau 1417 Posted May 1 3 minutes ago, bugdude said: The connection is a long lived websocket connection (just one), but with the client hitting so often I think it gets hit again before the shutdown waittimes can expire and may be talking to a partially torn down object. That was why I wondered if there was a 'clean' way to abort/disconnect the SSL connection from the server side that could be used before trying to set active false on the server. Again, without seeing the actual code, it is hard to answer definitively. Ideally, you would just set a flag that your server's OnExecute event handler can look for periodically and close the connection of the calling thread so it can terminate gracefully. But, if you absolutely had to close the connection quickly, then calling Binding.CloseSocket() from outside the server should suffice (like I said, modern Indy already does that, but maybe your older version is not), provided you are not swallowing any subsequent exceptions that may arise. Share this post Link to post