onvif icon indicating copy to clipboard operation
onvif copied to clipboard

Restart event loop for pull messages request when cam drops connection

Open akomelj opened this issue 1 year ago • 1 comments

TP-Link Tapo C220 (firmware 1.1.6) supports ONVIF pull-point subscriptions but unfortunately sets the socket read timeout on the pull endpoint to 10 seconds - i.e. every pull messages request gets closed by the cam after 10 seconds of I/O inactivity.

I tried changing various timeouts on the network & messages level and using TCP keep-alives to no avail - the cam sends TCP FIN packet roughly 10 seconds after receiving HTTP request headers and the connection gets closed prematurely with ECONNRESET error.

This pull request intercepts ECONNRESET error before it is propagated to event callbacks and restarts the event request loop (which handles subscription expiration, renewal, etc).

I believe the original plan of the author was to handle such cases one level higher - in _eventPull() - by unsubscribing and resubscribing again, but due to a bug in the code (?) unsubscribe() callback is never called and subscription never gets reinitialized.

This code:

	this.unsubscribe({}, function(_err,_data,_xml) {
		// once the unsubsribe has completed (even if it failed), go around the loop again
		this._eventRequest();
	});

should probably be without the empty object {} passed as the first parameter of unsubscribe call (the callback parameter).

	this.unsubscribe(function(_err,_data,_xml) {
		// once the unsubsribe has completed (even if it failed), go around the loop again
		this._eventRequest();
	});

Edited to add: fix for the above has already been submitted in #310.

In any case, as the subscription is still active at this point , there is no need to go through the unsubscribe/subscribe cycle again until the subscription expires and this is handled automatically by _eventRequest(). Unsubscribe doesn't work in the case of Tapo C220 anyway - the cam returns 500 Internal Server Error. :-)

ECONNRESET handling could be moved to _eventPull(), though. Please advise if any changes are needed.

akomelj avatar Feb 11 '24 23:02 akomelj