This is my first question on stackoverflow and I'm new to C++. I hope you can all forgive my ignorance to the probably obvious problem here, but I'm at a loss.
Basically, I'm just trying to catch events emitted by a nodejs server in my C++ client. I've successfully compiled my binary (imported boost and socketio) and much hardache. I'm trying to emit an event through a websocket connection, but I first need to ensure the connection is successful. I've been mostly following the tutorial at this link: https://socket.io/blog/socket-io-cpp/. I've also been following the source code, which can be found here: https://github.com/socketio/socket.io-client-cpp/tree/master/examples/QT
For some reason, I seem to be getting a segfault when I access my _io pointer in my bound function (in the onConnected function of the SocketHandler class).
I'm sure I'm doing something silly, but any help is appreciated. Maybe I'm misunderstanding the use of the std::bind function? I'm coming from a mostly javascript world.
main.cpp
#include "sockethandler.h"
int main()
{
SocketHandler sh;
}
sockethandler.cpp
#include <iostream>
#include "sockethandler.h"
const char name[13] = "raspberry_pi";
SocketHandler::SocketHandler() :
_io(new client())
{
using std::placeholders::_1;
_io->set_socket_open_listener(std::bind(&SocketHandler::OnConnected,this,_1));
_io->connect("http://127.0.0.1:3000");
_io->socket()->on("bot-command", [&](sio::event& ev) {
std::cout << "GOT IT!" << "\n";
//handle login message
//post to UI thread if any UI updating.
});
}
void SocketHandler::OnConnected(std::string const& nsp)
{
std::cout << "CONNECTED" << "\n";
// I can access a private class variable such as _a as a string
// here
_io->socket()->emit("join");
}
sockethandler.h
#ifndef SOCKETHANDLER_H
#define SOCKETHANDLER_H
#include <sio_client.h>
using namespace sio;
class SocketHandler {
public:
explicit SocketHandler();
private:
void OnConnected(std::string const& nsp);
std::unique_ptr<client> _io;
};
#endif // SOCKETHANDLER_H
Pretty sure the socket io library you are using is threaded. Your object is created, sets up the callback (which include references to itself), the constructor exits, main exits and the automatic (stack) variable sh
is destroyed. Then the socket io library tries to run the callback which no longer has references to a valid object and it crashes. Put a debug statement in your SocketHandler
destructor like cerr << "destructor called" << endl;
and I'm pretty sure you'll always see that called before the program crashes.
To prove it to yourself, put a sleep(10);
or whatever as the last line of code in your main to stall it from exiting and I'm guessing you'll see your program succeed.