NotionCommotion Posted January 21, 2018 Share Posted January 21, 2018 The purpose of the below socket server is: Allow a sub-client to connect and register. Allow an HTTP server (referred to as super-client) to make a one-time connection to the socket server and send some data to be forwarded to a specific sub-client identified by its guid. Return the response of the sub-client to the super-client. Note that I've taken my script and removed non-applicable portions to highlight specific aspects, and might have accidentally left something out. I've also added fictional methods clientRegistersWithServer(), gotValidReplyFromSubClient(), and superClientInitiatesRequest() to remove clutter. When the super-client connects, an anonymous function which will return the results is stored in an array, and then the message is sent to the sub-client. When the sub-client responds, the anonymous is executed, and then deleted from the array. Originally, I was thinking of unsetting the connection in the anonymous function, but feel it is not necessary as when the HTTP script closes, any associated socket connections will be closed, and thus the connection on the socket server will close, true? Is there anything I should be doing to release resources? Any other generic recommendations or comments would be appreciated. Thanks class SocketServer implements SocketServerInterface { private $callbacks=[], $guidMap=[]; public function __construct($host, $pdo, $influx, $influxClient, $SourceServerSoap, $baseDir) { $this->clientList = new \SplObjectStorage(); //Only used to associate guid with connection? } public function start() { $loop = \React\EventLoop\Factory::create(); $server = new \React\Socket\TcpServer($this->host['url'].':'.$this->host['port'], $loop); $server->on('connection', function (\React\Socket\ConnectionInterface $conn) { $connStream = new LengthPrefixStream($conn); $connStream->on('data', function($data) use ($connStream){ if(clientRegistersWithServer($data)) { $clientData=new \stdClass; $clientData->guid=$data->params->guid; $this->clientList->attach($connStream,$clientData); $this->guidMap[$data->params->guid] = $connStream; $this->callbacks[$data->guid]=(object)['fn'=>[],'callbackCount'=>0]; } if(gotValidReplyFromSubClient($data)) { $this->callbacks[$guid]->fn[$data->id]($data); //Callback will respond to http server unset($this->callbacks[$guid]->fn[$data->id]); } if(superClientInitiatesRequest($data)) { $forwardClient = $this->findConnectionByGuid($data->params->guid); $data->params->request->id=++$this->callbacks[$data->params->guid]->callbackCount; $this->callbacks[$data->params->guid]->fn[$data->params->request->id]=function($response) use($connStream) { syslog(LOG_INFO,'reply to HTTP Socket client'); //Should connStream be inherited by reference using &$connStream? $connStream->send(response); //unset($connStream); //Unset connection to HTTP server (maybe it already will happen when server gets response or times out?) }; $this->send($forwardClient,$data->params->request); //Send to gateway } }); }); $loop->run(); } private function findConnectionByGuid($guid) { return isset($this->guidMap[$guid])?$this->guidMap[$guid]:null; } } Quote Link to comment https://forums.phpfreaks.com/topic/306288-do-anonymous-functions-andor-socket-connections-need-to-be-deleted/ Share on other sites More sharing options...
requinix Posted January 21, 2018 Share Posted January 21, 2018 The socket will be closed but I would not assume that everything in PHP will be cleaned up. If you know the connection is closed and done with, delete what you have stored with it. At the very least it won't do any harm. Quote Link to comment https://forums.phpfreaks.com/topic/306288-do-anonymous-functions-andor-socket-connections-need-to-be-deleted/#findComment-1555627 Share on other sites More sharing options...
NotionCommotion Posted January 21, 2018 Author Share Posted January 21, 2018 Thanks requinix, I am assuming I should not take for granted that resources are dealt with as nicely as with a standard webserver setup. Will simply deleting the callback from the array release any memory associated for it? unset($this->callbacks[$guid]->fn[$data->id]); Quote Link to comment https://forums.phpfreaks.com/topic/306288-do-anonymous-functions-andor-socket-connections-need-to-be-deleted/#findComment-1555628 Share on other sites More sharing options...
kicken Posted January 22, 2018 Share Posted January 22, 2018 You could add some memory usage tracking to your code to get an idea of how much memory is being used over time. I did this recently in a worker script by just recording the result of memory_get_usage between tasks and logging it (and the difference from last reading) to help identify which tasks were eating up my memory and determine why. PHP should clean up your resources as it goes via garbage collection eventually, though manually unsetting / nulling things can help speed it up I think, particularly if you break any circular references. If your server is intended to be long running it would probably be worth thinking about restarting it periodically anyway. In my worker for example I fixed everything that might leak memory that I could think of and usage still grows by a few hundred bytes between jobs typically. Not sure if PHP itself is just leaking memory or if some library I am using may be the cause. Rather than waste a ton of time trying to track it down I just setup the script to exit periodically and have systemd will restart it. Quote Link to comment https://forums.phpfreaks.com/topic/306288-do-anonymous-functions-andor-socket-connections-need-to-be-deleted/#findComment-1555629 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.