How do I get a signal from QNetworkAccessManager::networkAccessibleChanged()? - qt

I am using the QNetworkAccessManager to do HTTP requests. We have found that the network connection we are using can go offline occasionally, and I want to actively detect when the link goes down.
I have connected a slot to the QNetworkAccessManager::networkAccessibleChanged() signal, but am not seeing any output from my slot.
In searching for a solution, the closest I come to an answer is the following discussion: http://www.qtcentre.org/threads/37514-use-of-QNetworkAccessManager-networkAccessible
However, the solutions suggested didn't resolve my problem.
Any suggestions on what I may be doing wrong?

Ok, after some more experimenting, I have found the answer...
Turns out my problem is that I have several Ethernet interfaces on my system.
In the discussion linked from my question, adding the following code was suggested:
QNetworkAccessManager* mNetworkAccessManager = new QNetworkAccessManager();
QNetworkConfigurationManager manager;
mNetworkAccessManager->setConfiguration(manager.defaultConfiguration());
The documentation for QNetworkAccessManager::setConfiguration() indicates the the default configuration is used automatically; so this is unnecessary, but it set me on the right track.
My problem is that the default configuration attaches to a different interface than the one my connection is going through; so I did the following:
QString ifName = "eth2";
QNetworkAccessManager* pNetworkAccessManager = new QNetworkAccessManager();
QNetworkConfigurationManager manager;
foreach(QNetworkConfiguration cfg, manager.allConfigurations()) {
if (cfg.name() == ifName) {
pNetworkAccessManager->setConfiguration(cfg);
break;
}
}
Now, my slot gets called.
I wish there were an easier way to get the desired configuration. Now, I have to figure out how to get the configuration starting with an IP address, instead of the interface name.

Related

Having trouble connecting to iSeries from .NET Core

This is a follow-up from the following question: Having trouble connecting to iSeries from .NET Core
The initial problem was resolved by setting a port number. I'm now running into the problem of the connection seemingly opening, however, hanging on the actual .Open() step - IE, never continuing on to the next line of code. For reference, here's my code block:
public static DB2Connection GetDatabaseConnection(string connectionString)
{
DB2Connection DB2Connection = new DB2Connection(connectionString);
DB2Connection.SystemNaming = true;
try
{
DB2Connection.Open();
return DB2Connection;
}
catch (Exception ex)
{
throw ex;
}
}
And my connection string is in this format: Server=###.###.###.###:#####;Database=DATABASE;UID=USER;PWD=PASSWORD;LibraryList=LIBRARY,LIST
Looking at the logs on the i Navigator, I see that there is a job name Qzhqssrv when is opened, with the user Quser, status Running, and type Prestart batch - Server. Looking into the logs for that entry, I see Job #####/QUSER/QZHQSSRV started on DATE at TIME in subsystem QUSRWRK in QSYS. Job entered system on DATE at TIME. However, it doesn't seem to continue beyond that.
Looking at the logs for a similar operation, when I'm connecting via Access Client Solutions, I get considerably more information and more steps in the logs. This leads me to believe that the system is waiting for me to send further information, however, my application is still stuck on .Open() - so perhaps there is something else I was supposed to send as part of the .Open() instruction. If so, I'm not sure what it would be.
Any insights would be greatly appreciated. Thanks!
Just to close this topic out - the problem was indeed the lack of a license. Connecting on port 446 was the correct approach, and once we got a license, we were able to get the connection working. Thanks #nfgl!

QLowEnergyService never transitions to ServiceDiscovered state on custom bluetooth service

I have created a Bluetooth communicator in Qt 5.5.1 following the Qt documentation. I have gotten to the point where I am able to view a list of services offered by a Bluetooth device. The services are generated by:
QLowEnergyService *service = controller->createServiceObject(serviceUuid);
Where controller is a QLowEnergyController and serviceUuid is a QBluetoothUuid. The service is created successfully but since it is a custom service offered by the device I am trying to connect to, the name is unknown. At this point I call:
service->discoverDetails();
which transitions the service to the QLowEnergyService::DiscoveringServices state from the QLowEnergyService::DiscoveryRequired state. Once this happens, the state never changes again and no error is ever thrown. Is there a way to pull the characteristics of an "unknown service"? I have checked the Uuid against what I expected for the service and it is correct. I also have the Uuid of the expected characteristics.
Note: I am using a pyqt (Python binding library of QT C++).
I stumbled upon issue while trying to connect to some device which offers two services. One is the standard battery service and another is private custom non-standard service.
I noticed that I was able to discover the batter service successfully, but I was not able to discover that custom service. However, for some reason, when I subscribed to service_error signal, the discovery works fine, and whenever i comment it out, it does not work.
void QLowEnergyService::error(QLowEnergyService::ServiceError newError)
I know it is funny and I do not have an explanation, but it could be related and i felt it is worth sharing.
QMetaObject::invokeMethod(this, "discoverCharacteristics", Qt::QueuedConnection);
void discoverCharacteristics() {
service->discoverDetails();
}

C3P0 connection pool gives connection timeout error with this configuration

I am using resin server + spring framework and c3p0 connection pooling. I have configured the connection pool with the following properties file. But somehow every 24 hours or so my website faces connection timeout errors and then i have to restart my resin server to make the website live again. Please tell me whats wrong in the following configuration file and what im missing here.
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.databaseURL=jdbc:mysql://localhost/my_database1_url
jdbc.StockDatabaseURL=jdbc:mysql://localhost/my_database2_url
jdbc.username=my_username
jdbc.password=my_password
jdbc.acquireIncrement=10
jdbc.minPoolSize=20
jdbc.maxPoolSize=30
jdbc.maxStockPoolSize=30
jdbc.maxStatements=100
jdbc.numOfHelperThreads=6
jdbc.testConnectionOnCheckout=true
jdbc.testConnectionOnCheckin=true
jdbc.idleConnectionTestPeriod=30
jdbc.prefferedTestQuery=select curdate();
jdbc.maxIdleTime=7200
jdbc.maxIdleTimeExcessConnections=5
So, a bunch of things.
c3p0 has built-in facilities for observing and debugging for Connection leaks. Please set the configuration parameters unusedConnectionTimeout unreturnedConnectionTimeout and debugUnreturnedConnectionStackTraces. Set an unreturnedConnectionTimeout that defines a period of time after which c3p0 should presume a Connection has leaked, and so close it. Set debugUnreturnedConnectionStackTraces to ask c3p0 to log the stack trace that checked out the Connection that did not get checked in properly. See Configuring to Debug and Workaround Broken Client Applications.
You are configuring c3p0 in a nonstandard way. That might be fine, or not, but you want to verify that the config that you intend to set is the config c3p0 gets. c3p0 DataSources dump their config at INFO on pool initialization. Please consider checking that to be sure you are getting the config you intend. Alternatively, you can check your DataSource's runtime config via JMX.
Besides the nonstandard means of configuration, several of your configuration properties seem amiss. prefferedTestQuery should be preferredTestQuery. numOfHelperThreads should be numHelperThreads.
The following are not c3p0 configuration names at all. Perhaps you are internally mapping them to c3p0 configuration, but you'd want to verify this. Here are the not-c3p0-property-names:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.databaseURL=jdbc:mysql://localhost/my_database1_url
jdbc.StockDatabaseURL=jdbc:mysql://localhost/my_database2_url
jdbc.username=my_username
jdbc.maxStockPoolSize=30
In a standard c3p0.properties form, what you probably mean is
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.jdbcURL=jdbc:mysql://localhost/my_database1_url
# no equivalent -- jdbc.StockDatabaseURL=jdbc:mysql://localhost/my_database2_url
c3p0.user=my_username
# no equivalent -- jdbc.maxStockPoolSize=30
Please see Configuration Properties. Again, c3p0 knows nothing about jdbc.-prefixed properties, but perhaps something in your own libraries or middleware picks those up.
Note: I love to see #NiSay's way of checking for Connection leaks, because I love to see people using more advanced c3p0 API. It will work, as long as you don't hot-update your DataSource's config. But you don't need to go to that much trouble, and there's no guarantee this approach will continue to work in future versions c3p0 makes no promises about ConnectionCustomizer lifecycles. ConnectionCustomizers are intended to be stateless. It is easier and safer to use c3p0's built-in leak check facility, described in the first bullet-point above.
As there could be possibility of connection leaks in the program (the probable cause of connection timeouts), you need to follow the below steps in order to identify the leaks.
Make as entry in your c3p0.properties file
c3p0.connectionCustomizerClassName = some.package.ConnectionLeakDetector
Create a class with name 'ConnectionLeakDetector' and place it in appropriate package. Below is the content of the class.
import java.sql.Connection;
import java.util.concurrent.atomic.AtomicInteger;
public class ConnectionLeakDetector implements com.mchange.v2.c3p0.ConnectionCustomizer {
static AtomicInteger connectionCount = new AtomicInteger(0);
#Override
public void onAcquire(Connection c, String parentDataSourceIdentityToken)
throws Exception {
}
#Override
public void onDestroy(Connection c, String parentDataSourceIdentityToken)
throws Exception {
}
#Override
public void onCheckOut(Connection c, String parentDataSourceIdentityToken)
throws Exception {
System.out.println("Connections acquired: " + connectionCount.decrementAndGet());
}
#Override
public void onCheckIn(Connection c, String parentDataSourceIdentityToken)
throws Exception {
System.out.println("Connections released: " + connectionCount.incrementAndGet());
}
}
The onCheckOut method will increment the count when the connection is acquired, where as onCheckOut will decrement it when the connection is released.
Execute some scenarios and observe the statistics on your console. If the count is more than 0, then the scenario executed has a connection leak. Try to fix them and you will observe the difference.
As a side note, you can increment the jdbc.maxPoolSize as a temporary solution until you deploy the fix.

on calling close() the ui does not close

In Qt I have a 2 forms say FirstUI and SecondUI. The main opens the FirstUI. Here I check if the databases needed for the application are present and if not present creates a new one. It also checks if there are any wifi network details stored in the database. If there are details of the last connected wifi, then the application scans for available networks and connects to the wifi network using the details from the database.
Now if there is no wifi detail in the database or if the network listed in the database is not present or if the application was unable to connect to the wifi network it will emit a signal WifiNotConnected();
I have connected the signal to a slot that opens the SecondUI.
connect(this,SIGNAL(WifiNotConnected()),this,SLOT(OpenSecondUI()));
.....
void FirstUI::OpenSecondUI()
{
SecondUI *sec = new SecondUI();
this->close();
sec->show();
}
The SecondUI opens, but this does not close the FirstUI.
EDIT: If the wifi details are present, I have a class (WifiBoot) that inherits QObject and does the connection tasks for me. Since I want the GIF file to be played in the GUI and the connection to occur same time I have instantiated the class (WifiBoot) that does the wifi connection and moved it to another thread. After the wifi is connected I emit the finished signal which is connected to the slot to open the SecondUI
connect(worker,SIGNAL(finished()),this,SLOT(FinishedConnection()));
void FirstUI::FinishedConnection()
{
OpenSecondUI();
}
Here it closes the FirstUI and opens the SecondUI. But in the first case it does not. Why is this happening? Is there a better way to go about it?
Any help is appreciated
first check if
this->close();
returns true. the other thing might be to just hide it using
QWidget::hide()
as well as set the FirstUI as parent of the SecondUI so your application will not leak memory IF you have multiple instances of FirstUI. (Forget the parent thing if you still close() the widget)
cheers
The OpenSecondUI() was called in the constructor itself. Therefore the close() in OpenSecondUI() was taking place before the UI was up and running. To solve this as suggested in the QT Forum and by #andrea.marangoni hint of the constructor being too populated, I used a single shot timer and moved the entire code in the constructor to a slot and called the slot after a certain delay. This ensured that before the slot OpenSecondUI() was called, the UI was up and running.

Qt DBus registerService function call returns false on an embedded Linux device

I’m new to DBus, but I’m trying to use it in two Qt applications on an embedded device. I have a very simple interface that consists of one slot:
QString SendMessage(const QString &cmd);
The server application is then using the following code to start the connection:
DbusService* dBus = new DbusService;
new interfaceIfAdaptor(dBus);
QDBusConnection connection = QDBusConnection::sessionBus();
bool ret = connection.registerService("com.domain.project.interface");
qDebug() << "returns" << ret;
ret = connection.registerObject("/", dBus);
qDebug() << "returns" << ret;
This works fine on the desktop. In the embedded system, the connection.registerService function returns false. As a result, any messages to the server fail. I’m not sure why. Running ‘ps’ tells me that [dbus-daemon —system] and [dbus-daemon —sesson] are both running.
Finally, I have noticed that Qt Creator complains when I debug the application. I see the following warning messages:
Could not load shared library symbols for 10 libraries, e.g. /opt/arm/lib/libQtDBus.so.4.
Use the “info sharedlibrary” command to see the complete listing.
Do you need “set solib-search-path” or “set sysroot”?
Could not load shared library symbols for /usr/lib/libdbus-1.so.3.
Do you need “set solib-search-path” or “set sysroot”?
If additional information is required to debug this problem, please let me know. Or if there are useful dbus commands I could run to help figure this out. Thanks!
It turns out the session bus was not getting started on the device. I enabled it, but then I ran into the problem of the address not getting propagated to the environment variables. I can manually set it in a terminal, but I'm not sure how to do the same in Qt Creator.
Anyway, rather than spend more time figuring out the issues with the session bus, I switched to using the system bus. I just had to change the /etc/dbus-1/system.conf file to allow anyone to talk to the system bus and my applications work on the embedded device. I know that's probably not the long term solution, but it works for now.

Resources