Bonjour,

Je souhaite mettre en place un pool de socket afin de dialoguer avec un module wago par le biais du protocole modbus.

Pour cela j'ai créé un class WagoConnectorPool de type singleton permettant de récupérer une instance de connecteur.

Voici l'implémentation de cette classe
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <QMutexLocker>
#include <QList>
 
#include "wagoConnector.h"
#include "wagoConfiguration.h"
 
#include "wagoConnectorPool.h"
 
WagoConnectorPool *WagoConnectorPool::_instance = 0;
quint8 WagoConnectorPool::nbInstance = 4;
 
WagoConnectorPool::WagoConnectorPool(void) {
  : _wagoInstances() {
 
  createConnectors();
}
 
WagoConnectorPool::~WagoConnectorPool(void) {
 
  _wagoInstances.clear();
}
 
WagoConnectorPool *WagoConnectorPool::instance(void) {
 
  if (_instance == 0)
    _instance = new WagoConnectorPool();
 
  return _instance;
}
 
void WagoConnectorPool::remove(void) {
 
  delete _instance;
}
 
Modbus *WagoConnectorPool::getConnector(void) {
 
  if (!_wagoInstances.isEmpty()) {
 
    QMutexLocker locker(&_mutex);
 
    if (!_wagoInstances.isEmpty()) {
 
      Modbus *connector = _wagoInstances.front();
      _wagoInstances.pop_front();
 
      return connector;
    }
    else
      return 0;
  }
 
  return 0;
}
 
void WagoConnectorPool::releaseConnector(Modbus *connector) {
 
  QMutexLocker locker(&_mutex);
 
  _wagoInstances.push_back(connector);
}
 
void WagoConnectorPool::createConnectors(void) {
 
  for (unsigned int i = 0; i < nbInstance; ++i) {
 
    Modbus *connector = new Modbus(WagoConfiguration::instance()->address(), WagoConfiguration::instance()->port());
 
    connect(connector, SIGNAL(connected(void)), this, SLOT(connectorConnected(void)));
    connect(connector, SIGNAL(errorDuringConnection(QAbstractSocket::SocketError)), this, SIGNAL(errorDuringConnection(QAbstractSocket::SocketError)));
 
    connector->connect();
  }
}
 
void WagoConnectorPool::connectorConnected(void) {
 
  Modbus *connector = qobject_cast<Modbus *>(sender());
 
  if (connector != 0)
    _wagoInstances.push_back(connector);
}
La classe WagoConnector contient la socket permettant de dialoguer avec le module Wago.

Je voulais savoir si cette implémentation était valide sur le plan du multi-thread et surtout thread-safe.

Question supplémentaire :

L'application finale doit être réactive et il est nécessaire de ne pas perdre la connexion.

Afin de ne pas perdre la connexion j'ai voulu activer le support du TcpKeepAlive sous windows mais cela ne semble pas fonctionner. Car il arrive que mes commandes ne soient plus envoyées au wago car la socket n'est plus connectée. De plus, j'ai augmenté au maximum le timeout du côté wago (5min). Auriez-vous une idée pour réussir à maintenir active mes sockets ?

Merci d'avance.