Frage / Problem zu {ShutdownFn}

Begonnen von DS_Starter, 23 April 2016, 18:27:11

Vorheriges Thema - Nächstes Thema

DS_Starter

Hallo zusammen,

ich versuche gerade einen Fehler in einem entstehenden Modul zu finden.
Konkret geht es darum beim Restart von FHEM einen zuvor geöffneten IP-Socket zu schließen. Er wird geöffnet mit:

  my $socket = IO::Socket::Multicast->new(
    Proto     => 'udp',
    LocalPort => '9522',

$socket->mcast_add('239.12.255.254');

  $hash->{TCPDev}= $socket;
  $hash->{FD} = $socket->fileno();
......


Es ist jeweils eine Routine als {UndefFn} und als {ShutdownFn} definiert und initialisiert. Beide Routinen sind gleich:

#####################################
sub
SMAEM_Shutdown($$)
{
  my ($hash, $arg) = @_;
  my $name= $hash->{NAME};
  my $socket= $hash->{TCPDev};
 
  Log3 $hash, 3, "$name: Closing multicast socket...";
  $socket->mcast_drop('239.12.255.254');
  $socket->close;

return undef;
}

#####################################
sub
SMAEM_Undef($$)
{
  my ($hash, $arg) = @_;
  my $name= $hash->{NAME};
  my $socket= $hash->{TCPDev};
 
  Log3 $hash, 3, "$name: Closing multicast socket...";
  $socket->mcast_drop('239.12.255.254');
  $socket->close;

  return undef;
}


Alles klappt prima wenn "rereadcfg" ausgeführt wird, d.h. die sub SMAEM_Undef.
Nur bei einem FHEM-Shutdown klappt das Schließen des Sockets nicht (in seltenden Fällen klappt es auch hier). Demzufolge finden sich im Log nach dem FHEM-Start entsprechende Socketfehler die darauf hinweisen dass der Socket beim Shutdown nicht geschlossen wurde :

Can't bind : IO::Socket::Multicast: Die Adresse wird bereits verwendet

Wird nach dem Restart wieder "rereadcfg" ausgeführt, funktioniert das Schließen und Eröffnen des Sockets.

Hat jemand eine Idee woran das Problem liegen könnte ?

viele Grüße
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Markus Bloch

Das liegt höchstwarscheinlich an der Tatsache, dass beim Shutdown zuerst die UndefFn und danach die ShutdownFn ausgeführt wird. Bei einem rereadcfg wird nur die UndefFn ausgeführt.

Wenn also ein Shutdown ausgeführt wird, wird 2 mal versucht den Socket zu schließen. In der UndefFn funktioniert das auch, in der ShutdownFn ist der Socket ja bereits zu.

Da es meiner Meinung nach keinen Grund gibt eine ShutdownFn explizit damit zu belegen, solltest du dir die ShutdownFn klemmen und nur die UndefFn verwenden.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

DS_Starter

Hi Markus,

danke für deine schnelle Antwort ... ich habs gleich mal mehrfach ausprobiert.
Gleiches Bild , shutdown mit Socketproblem , reread klappt prima... hmm

Gruß
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rudolfkoenig

Ich habe mit Multicast noch keine Erfahrung, aber bei den normalen Sockets muss man ReuseAddr => 1 setzen, sonst blockiert der naechste Server-Bind-Aufruf (falls es zeitnah geschieht) mit dem gemeldeten Fehler. Vielleicht braucht IO::Socket::Multicast auch sowas. Btw. wozu braucht man heutzutage multicast?

DS_Starter

Hallo Rudi,

danke für die Idee ... schaue ich mal in die Richtung ...

ZitatBtw. wozu braucht man heutzutage multicast?

Die SMA-PV-Geräte wie Wechselrichter, SMA Energy Meter verwenden Multicast. Wir basteln (d.h. Volker bastelt und ich unterstütze etwas beim Test)  hier https://forum.fhem.de/index.php?topic=51569.0 an einer FHEM integrierten Lösung um ohne zusatzliche Softwarekomponenten wie SBFspot o.ä. auszukommen.

Grüße
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

justme1968

zusätzlich zu ReuseAddr ist es vermutlich auch sinnvoll ReusePort zu setzen. sonst kann nur ein prozess auf diesem port lauschen. leider ist das nicht auf allen plattformen verfügbar. das kann man so abfangen:ReusePort=>defined(&ReusePort)?1:0)wenn es mit beiden flags immer noch nicht geht schau mal ins fakeRoko (und plex) modul. da verwende ich ebenfalls IO::Socket::Multicast.

@rudi: es gibt noch diverse protokolle die multicast verwenden u.a. ssdp um upnp geräte (alle möglichen audio und video geräte, die hue bridge, ...) zu finden, plex gdm, und noch einiges mehr.
wenn man auf dem netzwerk lauscht kommt da eine ganze menge vorbei.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

DS_Starter

Hi Andre,

super ... danke  ! Da schaue ich mal rein bzw. teste das ...

Gruß
Heiko
Proxmox+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter