IO客户端C+,如何从socket.on获取数组?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (126)

我正在为C ++构建一个Socket.io客户端实现,能够同时管理一个对象数组,我有一个像这样配置的Node.JS服务器来发送一个JSON格式的对象数组

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var numeroconectados = 0;
var booleano = 0;
var valormotor = 0,
  valorled = 0,
  valorpiston = 0,
  valorultrasonico = 0;
app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/index.html');
});

io.on('connection', function(socket) {
  numeroconectados += 1;

  socket.emit('inicializar', {
    'led': valorled,
    'piston': valorpiston,
    'motor': valormotor,
    'ultrasonico': valorultrasonico
  });
  console.log("<<Usuario conectado>> Usuarios en linea: " + numeroconectados);
  socket.on('disconnect', function() {
    numeroconectados -= 1;
    console.log('<<Usuario desconectado>> Usuarios en linea: ' + numeroconectados);
  });

  socket.on("datos", function(data) {
    var sizedatos = data.length;
    console.log(sizedatos);
    for (i = 0; i < sizedatos; i++) {
      console.log("Nombre: " + data[i].nombre + " Tipo: " + data[i].tipo +
        " Valor: " + data[i].valor);
        if(data[i].tipo == 'motor') valormotor = data[i].valor;
        if(data[i].tipo == 'led') valormotor = data[i].valor;
        if(data[i].tipo == 'ultrasonico') valormotor = data[i].valor;
        if(data[i].tipo == 'piston') valormotor = data[i].valor;
    }
    socket.broadcast.emit('datos', data); //Envia a todos los clientes

  });
  /*socket.on('motor', function(msg) {
    console.log('motor ' + msg);
    valormotor = msg;
    socket.broadcast.emit('motor', msg);
  });
  socket.on('led', function(msg) {
    valorled = msg;
    console.log('led ' + msg);
    socket.broadcast.emit('led', msg);
  });
  socket.on('ultrasonico', function(msg) {
    valorultrasonico = msg;
    console.log('ultrasonico ' + msg);
    socket.broadcast.emit('ultrasonico', msg);
  });
  socket.on('piston', function(msg) {
    valorpiston = msg;
    console.log('piston ' + msg);
    socket.broadcast.emit('piston', msg);
  });*/
});

http.listen(3000, function() {
  console.log('listening on *:3000');
});

我有一个存储数据的对象,以提高系统响应性,当一些对象发生变化时发送对象向量。在我的C ++程序中,我收到JSON中的结果对象数组,因为我有代码

#include "sio_client.h"                 //Librería de Sockets io

#include <functional>                   //Librerías estándar
#include <iostream>
#include <thread>                       //Librerías de Multriprocesamiento
#include <mutex>
#include <condition_variable>
#include <string>                       //Librerías de cadena de caracteres
#include <sstream>

#define HIGHLIGHT(__O__) std::cout<<"\e[1;31m"<<__O__<<"\e[0m"<<std::endl   //Colorear las funciones
#define EM(__O__) std::cout<<"\e[1;30;1m"<<__O__<<"\e[0m"<<std::endl

using namespace sio; //Workspace de Sockets.io
using namespace std; //Workspace de std
std::mutex _lock; //Workspace de multithreading

std::condition_variable_any _cond;
bool connect_finish = false;

/*
 *  Clase para conectar el listener, para aguardar por eventos
 */
class connection_listener {
    sio::client &handler;

public:

    connection_listener(sio::client& h) :
    handler(h) {
    }

    void on_connected() {
        _lock.lock();
        _cond.notify_all();
        connect_finish = true;
        _lock.unlock();
        std::cout << "Servidor conectado correctamente" << std::endl;
    }

    void on_close(client::close_reason const& reason) {
        std::cout << "sio closed " << std::endl;
        exit(0);
    }

    void on_fail() {
        std::cout << "sio failed " << std::endl;
        exit(0);
    }
};

socket::ptr current_socket; //Api de socket
string mensaje;

void eventos() {
    std::cout << "Inicio de recepcion de datos" << std::endl;
    std::vector<std::shared_ptr < message>> hola;
    current_socket->on("datos", sio::socket::event_listener_aux([&](string
            const& name, message::ptr const& data, bool isAck, message::list & ack_resp) {
        _lock.lock(); //Bloquear la ejecucion hasta realizar una opcion
        hola = data -> get_vector();
        for (int i = 0; i < hola.size(); i++) {
            std::cout << hola.at(i)->get_map()["tipo"]->get_string() << std::endl;
                    std::cout << hola.at(i)->get_map()["nombre"]->get_string() << std::endl;
                    std::cout << hola.at(i)->get_map()["tipo"]->get_string() << std::endl;
                    std::cout << hola.at(i)->get_map()["valor"]->get_string() << std::endl;
        }
        _lock.unlock(); //Desbloquear la ejecucion para seguir con el programa
    }));
}

//Separar string con delimitador

std::vector<std::string> split(std::string strToSplit, char delimeter) {
    std::stringstream ss(strToSplit);
    std::string item;
    std::vector<std::string> splittedStrings;
    while (std::getline(ss, item, delimeter)) {
        splittedStrings.push_back(item);
    }
    return splittedStrings;
}

int main(int argc, const char* args[]) {
    sio::client h; //Creación de un nuevo cliente de Sockets.io
    connection_listener l(h); //Añado al cliente un listener para obtener eventos
    h.set_open_listener(std::bind(&connection_listener::on_connected, &l));
    h.set_close_listener(std::bind(&connection_listener::on_close, &l, std::placeholders::_1));
    h.set_fail_listener(std::bind(&connection_listener::on_fail, &l));
    h.connect("http://127.0.0.1:3000"); //Conexión  al servidor Web

    _lock.lock();
    if (!connect_finish) {
        _cond.wait(_lock);
    }
    _lock.unlock();
    current_socket = h.socket(); //Socket para inicio de dato

    //Separar string
    std::vector<std::string> cadenaseparada;

    int numeroentrada = 0;
    string identificador;
    int opcion = 20;
    eventos(); //mandar a llamar una vez, obligatorio
    for (std::string line; std::getline(std::cin, line);) {
        if (line.length() > 0) {
            if (line == "$exit") {
                std::cout << "Salir" << std::endl;
                break;
            } else if (line.length() > 4 && line.length() < 15) {
                cadenaseparada = split(line, ',');
                identificador = cadenaseparada[0];
                mensaje = cadenaseparada[1];
                current_socket->emit(identificador, mensaje);
                _lock.lock();
                std::cout << "Identificador: " << identificador << std::endl << "Mensaje: " << mensaje << std::endl;
                _lock.unlock();
            } else {
                std::cout << "Evento desconocido" << std::endl;
            }
        }
    }
    h.close(); //Cerrar servidor
    return 0;
}

我用方法(hola是a )将message::ptr const& data接收的current_socket -> on方法转换为std :: vector ,但是当我想访问数组时,我得到一个SIGSEGV错误

提问于
用户回答回答于

holavector 的定义放入lambda。

    _lock.lock(); //Bloquear la ejecucion hasta realizar una opcion
    std::vector<std::shared_ptr < message>> hola = data -> get_vector();

现在,在eventos函数中创建lambda,它通过引用([&])捕获所有局部变量,因此你的lambda保存对holavector的引用。

扫码关注云+社区

领取腾讯云代金券