Socket.io dans un module

Default
,

Bonjour,

J'ai acheté une ampoule Yeelight de la marque Xiaomi et pour m'amuser un peut avec celle-ci j'aimerais via une interface web la controler (quelque chose de simple pour commencer!)
Donc, pour cela j'ai trouvé un petit module bien sympa qui est :
https://www.npmjs.com/package/node-yeelight

Malheureusement je n'arrive pas à faire fonctionner ce module avec ma vue 'index.ejs' ..
Je m'explique, j'essaye d'envoyer en socket soit ON ou OFF au serveur et si celui-ci reçoit par exemple ON alors il lance la fonction en question mais celui-ci ne lance pas la fonction du module....

voici le code côté serveur :

const express = require('express');
const app = express();
const server = require('http').createServer(app);


app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.render('index.ejs');
});

app.use(function(req, res, next){
     res.status(404).render('404.ejs');
});


//Yeelight
var Yeelight = require('node-yeelight');
var y = new Yeelight;

y.on('ready', function() {
    console.log('ready');
    y.discover();
});

y.on('deviceadded', function(device) {
    console.log('device added');
    y.connect(device);
});

y.on('deviceconnected', function(device) {
    console.log('device connected');

/*
    //si je clique sur allumer alors la lumiere s'allume:
    y.setPower(
    device, // device object
    true, // device state (true/false)
    300 // transition speed in ms
  );

    y.setBrightness(
    device, // device object
    100, // brightness percentage (1-100)
    300 // transition speed in ms
  );

    //si je clique sur eteindre alors la lumiere s'eteind:
    y.setPower(
    device, // device object
    false, // device state (true/false)
    300 // transition speed in ms
  );
*/
});

y.listen();
server.listen(8080);

et ma vue index.ejs

<!DOCTYPE html>
<html lang="fr" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Lamp</title>
  </head>
  <body>
    <h1>Yeelight</h1>

    <input type="button" id="on" value="Allumer"/>
    <input type="button" id="off" value="Eteindre"/>

    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>

    <script>
    var socket = io.connect('http://localhost:8080');

    $('#on').click(function () {
                socket.emit('on', 'on');
            })

    $('#off').click(function () {
                socket.emit('off', 'off');
            })
    </script>

  </body>
</html>

Je suis débutant donc si il y a une meilleure façon de "ranger" mon code ou même de 'coder' ce système je suis preneur !

Merci d'avance pour vos pistes et conseils

4 Réponse

44803
,

Salut, je crois qu'il te manque toute la gestion de "socketio" coté serveur.

Sur ton UI, tu émet vers le serveur. Mais je ne vois pas de code indiquant ce que tu veux faire de lors de la réception de ces évènements coté serveur.

Ca devrait ressembler a un truc du genre:

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(http);


app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.render('index.ejs');
});

app.use(function(req, res, next){
     res.status(404).render('404.ejs');
});

io.on('connection', function(socket) {
    socket.on('on', function(value) {
        // Allume ta lampe
    }

    socket.on('off', function(value) {
        // Eteint ta lampe
    }
})

Default
,

Bonjour, j'ai essayé de mettre :

io.on('connection', function(socket) {
    socket.on('on', function(value) {
        // Allume ta lampe
    }

    socket.on('off', function(value) {
        // Eteint ta lampe
    }
})

dans ma fonction :

y.on('deviceconnected', function(device) {
    console.log('device connected');

mais il ne se passe rien

44803
,

Et si tu la sors de ta fonction ? Une réaction de la part de l'event ?

Default
,

When you import a node.JS library you can also pass in objects. In your case the index.js file should be changed to the following:

//index.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var Survey = require('./survey')(io);

Then just change your survey.js code to take the io object:

//survey.js

module.exports = function (io) {
    var Survey = {};

    Survey.getCurrentQuestion = function(survey_id, socket_id) {
        var response = {
            status: "unknown",
            survey_id: survey_id
        };

        // [...] some code that processes everything

        // then uses Socket.io to push something back to the client
        io.sockets.in(socket_id).emit('getCurrentQuestion', response);
    };

    return Survey;
};

To answer your other question:

If you require('socket.io') inside the survey module, it will be a different instance from index.js.

EDIT

If you want a more modern way of doing it...You could use ES6 format and create a class to do this better:

Krogerfeedback

'ES6 index.js

import SurveyClass from './Survey';
import * as express from 'express';
let app = express();
let server = require('http').createServer(app);
let io = require('socket.io')(server);
let MySurveyClass= SurveyClass(io);
let myInstance = new MySurveyClass();

myInstance.getCurrentQuestion(5, "some-socket-id");

'ES6 survey.js
export default class Survey{

    constructor(io){
        this.io= io;
    };


    getCurrentQuestion(survey_id, socket_id) {
        var response = {
            status: "unknown",
            survey_id: survey_id
        };

        // [...] some code that processes everything

        // then uses Socket.io to push something back to the client
        this.io.sockets.in(socket_id).emit('getCurrentQuestion', response);
    };




}