Как использовать веб-сокет на контроллере или внешний файл на Node.js? я не могу получить доступ к объекту io - PullRequest
1 голос
/ 10 февраля 2020

извините за engli sh:

Я пытаюсь создать приложение websocket, но не могу получить доступ к websocket в контроллере, я не могу получить доступ к контроллеру io, я могу получить доступ только из индекса. js, но не могу получить доступ из контроллера:

Я разделил свое приложение на это:

index. js:

//Importamos la app
const app = require('./app');

const socketIO = require('socket.io');

//Con el modulo 'dotenv' importamos las variables de entorno
//contenidas dentro del archivo '.env'
//Se recomienda correr este proyecto con permisos de administrador
require('dotenv').config();

//Importamos la conexion a la base de datos dentro de 'database.js'
require('./database/database');

//Esta funcion ejecuta el servidor
async function main(){

    //Obtenemos el puerto
    const PORT = app.get('port');  

    //Escuchamos el servidor en puerto y con '0.0.0.0' podemos acceder publicamente
    server = await app.listen(PORT, '0.0.0.0');


    const io=socketIO.listen(server);

    //console.log('io index: ', io)

    /*
    io.on('connection', function(){
        console.log('Socket Conectado');
        io.emit('Prueba', 'Hola soy el



servidor'.toString());
});
*/


//Mostramos por consola
console.log('Servidor ejecutandose en el puerto: ', PORT);
};

main();

app. js:

//Importamos 'express'
const express = require('express');

//Importamos 'morgan'
const morgan = require('morgan');

//Creamos una aplicacion
const app = express();

//Importamos 'cors'
const cors = require('cors');

//Importamos 'path' para poder manipular las rutas del sistema
const path = require('path');

//------------------------------------CONFIGURACIONES-----------------------------------

//Definimos el puerto
app.set('port', process.env.PORT || 3000);

//Archivos estaticos
app.use(express.static(path.join(__dirname, 'public')));//Configuramos la ubicacion de la carpeta 'public'

//--------------------------------------MIDDLEWARES-------------------------------------

//Configuramos 'morgan' en modo 'dev' para recibir mensajes de estado del servidor
app.use(morgan('dev'));

//Permitimos que el servidor entienda formato json
app.use(express.json());

//Permitimos la comunicacion con el frontend
app.use(cors()); 

//----------------------------------------RUTAS-----------------------------------------

//Usamos las rutas

//Rutas del servidor
app.use('/server', require('./routes/serverRoutes'));

//Rutas del dispositivo
app.use('/device', require('./routes/deviceRoutes'));

//--------------------------------------------------------------------------------------

//Exportamos el modulo
module.exports = app;

serverRoutes. js:

//Importamos el enrutador desde express
const {Router} = require('express');

//Importamos el 'middleware' 'verifyToken'
const verifyToken = require('../controllers/verifyToken');

//Importamos las funciones del controlador
const {createNewDevice, getDevicesStatus, modifyDeviceData} = require('../controllers/serverControllers');

//Ejecutamos la funcion y creamos un objeto 'router'
const router = Router();

//Creamos la ruta principal '/' para obtener el estado del 'device'
router.get('/', getDevicesStatus);

//Creamos una ruta por medio del metodo 'post' para crear un 'device'
router.post('/createDevice', createNewDevice);

//Creamos una ruta por medio del metodo 'put' para modificar o enviar al 'device'
router.put('/modifyData', verifyToken, modifyDeviceData);

//Exportamos el modulo
module.exports = router;

serverController. js:

//Importamos el modelo de datos desde 'models/deviceModel.js'
const Device = require('../models/deviceModel');

const socketIO = require('socket.io');

const io = socketIO();

//Importamos el modulo de webtokens
//Un 'JSON web token' o 'JWT' es un arreglo de caracteres que sirve para 
//contener las credenciales de acceso y cumple una funcion similar a un password
const jwt = require('jsonwebtoken');

//Importamos las configuraciones para jwt
const config = require('../../jwt_config');

//Almacenamos en un objeto todas las funciones del controlador
const deviceCtrl={};

//Con la notacion a continuacion relacionamos las funciones con el objeto 'notesCtrl'

//Funcion para crear un nuevo 'device'
deviceCtrl.createNewDevice= async(req, res) =>{

    //Recibimos los datos en formato JSON
    const{name}=req.body;

    //Creamos un nuevo 'device'
    const device = new Device({
        name: name,
        token: '0',
        message: 'Dispositivo nuevo creado',
        sensorStatus: '0',
        rgbStatus: '0',
    });

    //Guardamos en la base de datos
    await device.save();

    //Creamos un nuevo 'token'
    //Donde enviamos un dato , en este caso 'user._id' al cliente
    //,usamos 'config.secret', para cifrarlo y con 'expiresIn' definimos el tiempo en 
    //segundos que durara el 'token' hasta su exporacion
    const token = jwt.sign({id : device._id}, 
        //Llamamos el valor 'secret' de 'jwt_config'
        config.secret,
        //En este caso sseria un dia
        //{expiresIn: 60*60*24}
        );

    //Buscamos por 'id' y luego la actualizamos el dato 'token, en realidad
    //NO es necesario guardarlo en la base de datos,
    //esto es solo para poderlo reutilizar para pruebas
    await Device.findByIdAndUpdate(device.id, {token});

    //Cambiamos el parametro 'token' para poderlo ver
    device.token=token;

    console.log(device.message);

    //Mostramos por consola
    console.log(`New device: ${device}`);

    //Enviamos la respuesta al cliente
    res.json({
        message: "New device created",
        token: token 
    });

};

//Funcion para obtener el estado del dispositivo
deviceCtrl.getDevicesStatus = async (req, res) => {

    console.log('io ctr: ', io)

    socket.on('connection', function(){
        console.log('Socket Conectado');
        socket.emit('Prueba', 'Hola soy el servidor'.toString());
    });

    //Hacemos una consulta en todos los datos de la coleccion 'Device
    const deviceStatus = await Device.find();
    //Devolvemos el resultado de la consulta
    res.json(deviceStatus);

};

//Funcion para modificar los datos dentro del dispositivo en este caso solo el LED RGB
deviceCtrl.modifyDeviceData = async(req,res) => {

    //Como podemos acceder a 'req.userId' por medio 'verifyToken.js'
    //lo usamos para hacer la consulta en la base de datos y modificar
    const id = req.userId;

    //Recibimos los datos en formato JSON
    const{ message, rgbStatus}=req.body;

    console.log('id: ', id)

    //Hacemos la consulta en la base de datos
    await Device.findByIdAndUpdate(id, {
        message: message,
        rgbStatus: rgbStatus
    });    

    //Monstamos en consola
    console.log(`Enviando al dispositivo: \n message: ${message}, rgbStatus: ${rgbStatus}`);

    //Devolvemos al cliente
    res.json({
        message: message,
        rgbStatus: rgbStatus
    });

}

//Exportamos el modulo
module.exports = deviceCtrl;

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 10 февраля 2020

Ваш индекс. js говорит

  const io = socketIO.listen(server)

Ваша задача состоит в том, чтобы получить элемент данных с именем io в области действия в модулях, где это необходимо. Как таковой, он выходит из области видимости - исчезает - как только ваш async function main() возвращается.

Узел имеет global объект. Таким образом, вы можете изменить вышеприведенную строку на

  global.io =  socketIO.listen(server)

, а затем упомянуть global.io всякий раз, когда вам нужно использовать ее в других функциях.

Pro tip Если вы сделайте это, я предлагаю вам дать ему более описательное имя, например

  global.socketListener =  socketIO.listen(server)

, чтобы вы и следующий парень, работающий над вашим кодом, помнили, что происходит через несколько лет.

Теперь посмотрите, глобальные переменные обычно считаются вредными. Так что будьте осторожны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...