rossmann-engineering / EEIP.NET

Ethernet/IP compatible library for .NET implementations
MIT License
208 stars 120 forks source link

Device unreachable after UnregisterSession #25

Open nick990 opened 2 years ago

nick990 commented 2 years ago

I'm trying to to read data periodically using explicit messaging. Currently I do the following:

  1. create an instance of EEIPClient
  2. register a session
  3. read data
  4. unregister the session
  5. sleep
  6. go to point 2

The idea is to register/unregister the session each loop cycle in order to prevent a disconnection from the device. In case of connection lost (e.g. network issue, PLC reboot, etc.) I was expecting the library would be able to register a new session. What happens is that after a few iterations, the device become unreachable. I can't even ping it, I have to reboot it.

var client = EEIPClient();
while(true){
   client.RegisterSession(IP_ ADDRESS, PORT);

   client.GetAttributeSingle(CLASS_ID, INSTANCE_ID, ATTRIBUTE_ID);

   client.UnregisterSession();
   Sleep(5000);

I would to know if my approach is correct or there is a better way to obtain the desired behavior. If the approach is right, what could be the cause of this problem? Thanks

IlliniHiker commented 2 years ago

Personally, if you are connecting every 5 seconds, I would leave the connection open.

nick990 commented 2 years ago

Personally, if you are connecting every 5 seconds, I would leave the connection open.

I can't leave the connection open because EEIP is not able to reconnect in case of loss of connection.

After some tests, it seems that the device doesn't become unreachable if I put a sleep over seconds between the the UnregisterSession and RegisterSession calls. So the workaround I found is to leave the connection open and recreate the session in case of any error.

EEIPClient client ;
bool sessionRegistered = false;

void RegisterSession(){
   client = new EEIPClient();
   client.RegisterSession(IP_ ADDRESS, PORT);
   sessionRegistered = true;
}

void DestroySession(){
   client.UnRegisteredSession();
   sessionRegistered = false;
}

while(true){
   try{
      if(!sessionRegistered){
         RegisterSession();
      }
      client.GetAttributeSingle(CLASS_ID, INSTANCE_ID, ATTRIBUTE_ID);
      Sleep(5000);
   }catch(Exception ex){
      DestroySession();
      Sleep(10000);
   }
}

I think the sleep of 10 seconds solves the problem because the client doesn't wait for unregistration. Is there a better way to check connection status?