Utilizzando socket.io in Express 4 e in / bin / www di express-generator


93

Quindi ecco l'affare: sto cercando di utilizzare socket.io in un progetto express. Dopo che Express Js 4 è stato lanciato, ho aggiornato il mio generatore di espresso e ora le funzioni iniziali dell'app vengono inserite nel ./bin/wwwfile, comprese quelle variabili (contenuto del file www: http://jsfiddle.net/avMa5/ )

var server = app.listen(app.get('port'), function() {..}

(controlla prima npm install -g express-generatore poiexpress myApp

Detto questo, ricordiamo come i documenti socket.io ci chiedono di attivarlo:

var app = require('express').createServer();
var io = require('socket.io')(app);

Ok ma non posso farlo all'interno di app.js, come consigliato. Questo dovrebbe essere fatto in ./bin/www per poter funzionare. in ./bin/www questo è quello che posso fare per farlo funzionare:

var io = require('socket.io')(server)

Ok, funziona, ma non posso usare io var da nessun'altra parte, e davvero non voglio mettere le mie funzioni socket.io su wwwfile.

Immagino che questa sia solo una sintassi di base, ma non riesco a farlo funzionare, nemmeno usando module.exports = servero server.exports = servermodule.exports.io = app(io)sul file www

Quindi la domanda è: come posso usare socket.io avendo questo file / bin / www come punto di partenza della mia app?


Non devi inserire l'importazione ./bin/www.. Mettilo nello stesso posto, dov'è il tuo var app.
alandarev

15
Vorrei che la gente smettesse di suggerire express-io. È obsoleto e non è più mantenuto.
Ben Fortune

@Mritunjay grazie, ma non l'ha risolto: /
user1576978

@ BenFortune mi dispiace, lo terrò a mente.
Mritunjay

@alandarev var app = express () ?? L'ho provato, senza successo
user1576978

Risposte:


160

Ho una soluzione per rendere disponibile socket.io in app.js.

app.js:

var express      = require( "express"   );
var socket_io    = require( "socket.io" );

// Express
var app          = express();

// Socket.io
var io           = socket_io();
app.io           = io;

(...)

// socket.io events
io.on( "connection", function( socket )
{
    console.log( "A user connected" );
});

module.exports = app;

// Or a shorter version of previous lines:
//
//    var app = require( "express"   )();
//    var io  = app.io = require( "socket.io" )();
//    io.on( "connection", function( socket ) {
//        console.log( "A user connected" );
//    });
//    module.exports = app;

bin / www:

(...)

/**
 * Create HTTP server.
 */

var server = http.createServer( app );


/**
 * Socket.io
 */

var io     = app.io
io.attach( server );

(...)

In questo modo, puoi accedere alla variabile io nel tuo app.js e persino renderlo disponibile per le tue rotte definendo module.exports come una funzione che accetta io come parametro.

index.js

module.exports = function(io) {
    var app = require('express');
    var router = app.Router();

    io.on('connection', function(socket) { 
        (...) 
    });

    return router;
}

Quindi, passa io nel modulo dopo che è stato configurato:

app.js

// Socket.io
var io = socket_io();
app.io = io;

var routes = require('./routes/index')(io);

1
Sono nuovo su NodeJS. Puoi per favore spiegare cosa sta succedendo esattamente su questa riga app.io = io;nel app.jsfile
Aryak Sengupta

3
Si tratta semplicemente di inserire la variabile io nell'oggetto app. Potrebbe anche essere: app.io = socket_io ();
Gabriel Hautclocq

7
"... e, se lo desideri, rendilo disponibile anche per i tuoi percorsi." Va bene, ma come? Sarebbe fantastico se potessi fornire un esempio su come farlo.
scaryguy

2
Non è male allegare una proprietà personalizzata appall'oggetto? Meglio usare i simboli o app.set().
Alexander Gonchiy

3
Perché app.io = ioquando potresti usare module.exports = { app, io }invece
Manan Mehta

56

Un approccio leggermente diverso per iniziare socket.io, raggruppa tutto il codice correlato in un unico posto:

bin / www

/**
 * Socket.io
 */
var socketApi = require('../socketApi');
var io = socketApi.io;
io.attach(server);

socketApi.js

var socket_io = require('socket.io');
var io = socket_io();
var socketApi = {};

socketApi.io = io;

io.on('connection', function(socket){
    console.log('A user connected');
});

socketApi.sendNotification = function() {
    io.sockets.emit('hello', {msg: 'Hello World!'});
}

module.exports = socketApi;

app.js

// Nothing here

In questo modo tutti socket.io codice relativo in un modulo e la funzione da esso posso richiamare da qualsiasi punto dell'applicazione.


4
Questa risposta merita più voti positivi! Molto semplice e pulito, mantiene le route del socket all'esterno di www , app.js e anche all'esterno di index.js (sì, all'esterno di index.js ), questo file dovrebbe contenere solo route HTTP Express.
adelriosantiago

1
Incredibile, molto pulito
sanket

3
Qualcuno può aggiornarlo per socket.io 2.0? Non funziona per me. io.attach (server) e io.listen (server) lanciano entrambi "non possono leggere la proprietà X di undefined".
tsujp

1
Anche parlare con @tsujp funziona allo stesso modo. Devi premere l'URL corretto e aggiungere il client socket.io e vedrai che funziona
Tamb

Ho un problema simile a @tsujp, sto usando socket.io 2.3.0 e ricevoio.attach is not a function
raquelhortab

43

Si scopre che era davvero un problema di sintassi di base ... Ho ricevuto queste righe da questo tutorial sulla chat di socket.io ...

su ./bin/www, subito dopo var server = app.listen(.....)

var io = require('socket.io').listen(server);
require('../sockets/base')(io);

quindi ora creo il file ../sockets/base.js e ci metto dentro questo piccoletto:

module.exports = function (io) { // io stuff here... io.on('conection..... }

Si! Ora funziona ... Quindi immagino di non avere altra scelta che avviare socket.io all'interno di / bin / www, perché è lì che è stato avviato il mio server http. L'obiettivo è che ora posso creare funzionalità socket in altri file, mantenendo la cosa modulare, tramiterequire('fileHere')(io);

<3


1
Il problema è che non puoi fare qualcosa comeio.on('connection', function(socket) { res.render('connection.jade') });
Gofilord

3
@Gofilord è perché vanifica l'intero scopo dei socket ... ciò di cui hai bisogno è un routing regolare che include il rendering. I socket sono qui solo per inviare messaggi tra client e server senza richieste http. magari leggi questo articolo enterprisewebbook.com/ch8_websockets.html
Unispaw

19

Il vecchio "expressjs", tutto accade nel file "app.js". Quindi l'associazione socket.io al server avviene anche in quel file. (BTW, si può ancora farlo alla vecchia maniera e rimuovere bin / www)

Ora con il nuovo expressjs, deve accadere nel file "bin / www".

Fortunatamente, javascript / requirejs ha reso facile il passaggio di oggetti. Come ha sottolineato Gabriel Hautclocq, socket.io è ancora "importato" in "app.js" e viene allegato all'oggetto "app" tramite una proprietà

app.io = require('socket.io')();

Il socket.io viene reso attivo collegandolo al server in "bin / www"

app.io.attach(server); 

perché l'oggetto "app" viene passato in "bin / www" in precedenza

app = require("../app");

È davvero semplice come

require('socket.io')().attach(server);

Ma farlo nel modo "difficile" assicura che app.ioora contenga l'oggetto socke.io.

Ora, se hai bisogno di questo oggetto socket.io anche in "routes / index.js", ad esempio, usa lo stesso principio per passare quell'oggetto.

Prima in "app.js", fai

app.use('/', require('./routes/index')(app.io));

Quindi in "route / index.js"

module.exports = function(io){
    //now you can use io.emit() in this file

    var router = express.Router();



    return router;
 }

Quindi "io" viene iniettato in "index.js".


9

Aggiornamento alla risposta di Gabriel Hautclocq :

Nel file www, il codice dovrebbe apparire come il seguente a causa degli aggiornamenti con Socket.io. Allega ora è Ascolta.

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);


/**
 * Socket.io
 */
var io = app.io;
io.listen(server);`

Inoltre, per far funzionare la connessione è necessario implementare anche l'API lato client. Questo non è specifico per Express ma senza di esso la chiamata di connessione non funzionerà. L'API è inclusa in

/node_modules/socket.io-client/socket.io.js. 

Includi questo file nel front-end e prova con quanto segue:

var socket = io.connect('http://localhost:3000');

7

Dopo aver letto tutti i commenti, mi è venuto in mente il seguente utilizzo Socket.io Server Version: 1.5.0

Problemi che ho riscontrato:

  1. var sockIO = require ('socket.io') dovrebbe essere var sockIO = require ('socket.io') () . (Credito a: Zhe Hu )

  2. sockIO.attach dovrebbe essere sockIO. ascolta (Credito a: rickrizzo )

Passi

  1. Installa Socket.io con il seguente comando:

    npm install --save socket.io
  2. Aggiungi quanto segue ad app.js :

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
  3. In bin / www , dopo var server = http.createServer (app) , aggiungi quanto segue:

    var sockIO = app.sockIO;
    sockIO.listen(server);
  4. Per testare la funzionalità, in app.js , puoi aggiungere la riga:

    sockIO.on('connection', function(socket){
        console.log('A client connection occurred!');
    });

5

Un tutorial per principianti di Cedric Pabst
qui sono le brevi nozioni di base dal collegamento per una chat dell'app:

utilizzando express-generate e il motore ejs utilizzabile in ogni file .ejs standard routing in express-generate

modifica il file bin \ www e aggiungi questo app.io.attach (server); come questo

...
/*
 * Create HTTP server.
/*  
var server = http.createServer(app);
/*
 * attach socket.io
/*  
app.io.attach(server); 
/*
 * Listen to provided port, on all network interfaces.
/*  
...

modifica in app.js

//connect socket.io
... var app = express();
// call socket.io to the app
app.io = require('socket.io')();

//view engine setup
app.set('views', path.join(_dirname, 'views'));
...



...
//start listen with socket.io
app.io.on('connection', function(socket){
console.log('a user connected');

// receive from client (index.ejs) with socket.on
socket.on('new message', function(msg){
      console.log('new message: ' + msg);
      // send to client (index.ejs) with app.io.emit
      // here it reacts direct after receiving a message from the client
      app.io.emit('chat message' , msg);
      });
});
...
module.exports = app;

modificare in index.ejs

 <head>  
   <title><%= title %></title>
   <link rel='stylesheet' href='/stylesheets/style.css' />
   <script src="/socket.io/socket.io.js"></script>
   //include jquery
   <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
   <script>
   var socket = io();
   //define functions socket.emit sending to server (app.js) and socket.on receiving 
     // 'new message' is for the id of the socket and $('#new-message') is for the button
     function sendFunction() {
     socket.emit('new message', $('#new-message').val());
     $('#new-message').val('');
   }
    // 'chat message' is for the id of the socket and $('#new-area') is for the text area
   socket.on('chat message', function(msg){
     $('#messages-area').append($('<li>').text(msg));
   });
   </script>
 </head>  

 <body>  
   <h1><%= title %></h1>
   <h3>Welcome to <%= title %></h3>
   <ul id="messages-area"></ul>
   <form id="form" onsubmit="return false;">
     <input id="new-message" type="text" /><button onclick="sendFunction()">Send</button>
   </form>
 </body>

Buon divertimento :) e grazie mille a Cedric Pabst


2

Alcune risposte precedenti non funzionano e altre sono eccessivamente complicate. Prova invece la seguente soluzione ...

Installa i moduli del nodo socket.io lato server e lato client:

npm install --save socket.io socket.io-client

Lato server

Aggiungere il codice seguente a bin / www dopo la definizione del server var server = http.createServer(app);:

/**
 * Socket.io
 */

var io = require('socket.io')(server);

io.on("connection", function(socket){
  console.log("SOCKET SERVER CONNECTION");
  socket.emit('news', { hello: 'world' });
});

Dalla parte del cliente

Se utilizzi webpack, aggiungi il seguente codice al tuo file webpack entry.js :

var socket = require('socket.io-client')();
socket.on('connect', function(){
  console.log("SOCKET CLIENT CONNECT")
});

socket.on('news', function(data){
  console.log("SOCKET CLIENT NEWS", data)
});

Fatto. Visita il tuo sito e controlla la console per sviluppatori js del browser.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.