Menggunakan socket.io di Express 4 dan express-generator's / bin / www

93

Jadi inilah kesepakatannya: Saya mencoba menggunakan socket.io dalam proyek ekspres. Setelah Express Js 4 diluncurkan, saya telah memperbarui generator ekspres saya dan sekarang fungsi awal aplikasi masuk ke dalam ./bin/wwwfile, termasuk vars tersebut (konten file www: http://jsfiddle.net/avMa5/ )

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

(periksa npm install -g express-generatorkemudianexpress myApp

Karena itu, mari kita ingat bagaimana dokumen socket.io meminta kita untuk memecatnya:

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

Oke, tapi saya tidak bisa melakukannya di dalam app.js, seperti yang direkomendasikan. Ini harus dilakukan di ./bin/www agar berfungsi. di ./bin/www inilah yang dapat saya lakukan untuk membuatnya berfungsi:

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

Ok ini berfungsi, tetapi saya tidak dapat menggunakan io var di tempat lain, dan saya benar-benar tidak ingin menempatkan fungsi socket.io saya pada wwwfile.

Saya kira ini hanya sintaks dasar, tetapi saya tidak bisa membuatnya berfungsi, bahkan tidak menggunakan module.exports = serveratau server.exports = servertidak module.exports.io = app(io)pada file www

Jadi pertanyaannya adalah: bagaimana saya bisa menggunakan socket.io yang memiliki file / bin / www ini sebagai titik awal aplikasi saya?

pengguna1576978
sumber
Anda tidak perlu memasukkan impor ./bin/www.. Letakkan saja di tempat yang sama, di mana Anda var appberada.
alandarev
15
Saya berharap orang-orang berhenti menyarankan express-io. Itu sudah usang dan tidak lagi terawat.
Ben Fortune
@Mritunjay terima kasih, tetapi itu tidak menyelesaikannya: /
user1576978
@ BenFortune maaf saya akan mengingatnya.
Mritunjay
@alandarev var app = express () ?? Saya benar-benar mencobanya, tidak berhasil
pengguna1576978

Jawaban:

160

Saya memiliki solusi untuk membuat socket.io tersedia di 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 );

(...)

Dengan cara ini, Anda bisa mengakses variabel io di app.js Anda, dan bahkan membuatnya tersedia untuk rute Anda dengan mendefinisikan module.exports sebagai fungsi yang menerima io sebagai parameter.

index.js

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

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

    return router;
}

Kemudian, berikan io ke dalam modul setelah itu diatur:

app.js

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

var routes = require('./routes/index')(io);
Gabriel Hautclocq
sumber
1
Saya baru mengenal NodeJS. Bisakah Anda menjelaskan apa yang sebenarnya terjadi pada baris ini app.io = io;dalam app.jsfile
Aryak Sengupta
3
Ini hanyalah masalah meletakkan variabel io ke dalam objek aplikasi. Bisa juga: app.io = socket_io ();
Gabriel Hautclocq
7
"... dan bahkan membuatnya tersedia untuk rute Anda jika Anda mau." Oke, tapi bagaimana caranya? Akan sangat bagus jika Anda bisa memberi contoh bagaimana melakukannya.
scaryguy
2
Bukankah buruk untuk melampirkan properti khusus ke appobjek? Lebih baik gunakan simbol atau app.set().
Alexander Gonchiy
3
Mengapa app.io = ioketika Anda bisa menggunakan module.exports = { app, io }sebagai gantinya
Manan Mehta
59

Pendekatan yang sedikit berbeda untuk memulai socket.io, ini mengelompokkan semua kode terkait di satu tempat:

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

Dengan cara ini semua socket.iokode terkait dalam satu modul dan fungsi darinya dapat saya panggil dari mana saja dalam aplikasi.

Anatoly
sumber
4
Jawaban ini membutuhkan lebih banyak suara positif! Sangat sederhana dan bersih, itu membuat rute soket di luar www , app.js dan juga di luar index.js (ya, di luar index.js ), file ini seharusnya hanya berisi rute HTTP Ekspres.
adelriosantiago
1
Luar biasa, sangat bersih
sanket
3
Adakah yang bisa memperbarui ini untuk socket.io 2.0? Ini tidak berhasil untuk saya. io.attach (server) dan io.listen (server) keduanya membuang "tidak dapat membaca properti X yang tidak ditentukan".
Jordan
1
Juga untuk berbicara dengan @tsujp, saya bekerja sama. Anda harus menekan url yang benar dan menambahkan klien socket.io dan Anda akan melihatnya berfungsi
Tamb
Saya memiliki masalah yang sama dengan @tsujp, saya menggunakan socket.io 2.3.0 dan saya mendapatkanio.attach is not a function
raquelhortab
43

Ternyata itu benar-benar masalah sintax dasar .... Saya mendapat baris ini dari tutorial chat socket.io ini ...

di ./bin/www, setelahnya var server = app.listen(.....)

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

jadi sekarang saya membuat file ../sockets/base.js dan meletakkan orang kecil ini di dalamnya:

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

Ya! Sekarang berhasil ... Jadi saya rasa saya benar-benar tidak punya pilihan selain memulai socket.io di dalam / bin / www, karena di situlah server http saya dimulai. Tujuannya adalah sekarang saya dapat membangun fungsionalitas soket di file lain, menjaga agar tetap modular, olehrequire('fileHere')(io);

<3

pengguna1576978
sumber
1
Masalahnya adalah, Anda tidak dapat melakukan sesuatu sepertiio.on('connection', function(socket) { res.render('connection.jade') });
Gofilord
3
@Gofilord itu karena mengalahkan seluruh tujuan soket ... yang Anda butuhkan adalah perutean biasa yang mencakup rendering. Soket hanya di sini untuk mengirim pesan antara klien dan server tanpa permintaan http. mungkin membaca artikel ini enterprisewebbook.com/ch8_websockets.html
Unispaw
19

"Expressjs" yang lama, semuanya terjadi di file "app.js". Jadi pengikatan socket.io ke server juga terjadi di file itu. (BTW, seseorang masih bisa melakukannya dengan cara lama, dan menghapus bin / www)

Sekarang dengan expressjs baru, ini perlu dilakukan di file "bin / www".

Untungnya, javascript / requirejs membuatnya mudah untuk menyebarkan objek. Seperti yang ditunjukkan oleh Gabriel Hautclocq, socket.io masih "diimpor" di "app.js" dan akan dilampirkan ke objek "app" melalui properti

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

Socket.io dibuat langsung dengan melampirkannya ke server di "bin / www"

app.io.attach(server); 

karena objek "app" diteruskan ke "bin / www" sebelumnya

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

Ini benar-benar sesederhana

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

Tetapi melakukannya dengan cara yang "sulit" memastikan bahwa app.iosekarang menampung objek socke.io.

Sekarang jika Anda membutuhkan objek socket.io ini juga dalam "routes / index.js" misalnya, gunakan saja prinsip yang sama untuk meneruskan objek tersebut.

Pertama di "app.js", lakukan

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

Lalu di "routes / index.js"

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

    var router = express.Router();



    return router;
 }

Jadi "io" disuntikkan ke "index.js".

Zhe Hu
sumber
9

Pembaruan atas tanggapan Gabriel Hautclocq :

Dalam file www, kode tersebut akan muncul sebagai berikut karena pembaruan dengan Socket.io. Attach sekarang Dengarkan.

/**
 * 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);`

Selain itu, agar koneksi itu berfungsi membutuhkan penerapan API sisi klien juga. Ini tidak spesifik Express tetapi tanpa itu panggilan terhubung tidak akan berfungsi. API sudah termasuk dalam

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

Sertakan file ini di bagian depan dan uji dengan yang berikut:

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

Setelah membaca semua komentar, saya menemukan yang berikut ini menggunakan Socket.io Versi Server: 1.5.0

Masalah yang saya hadapi:

  1. var sockIO = membutuhkan ('socket.io') harus var sockIO = membutuhkan ('socket.io') () . (Penghargaan untuk: Zhe Hu )

  2. sockIO.attach harus sockIO. mendengarkan (Kredit untuk: rickrizzo )

Langkah

  1. Instal Socket.io dengan perintah berikut:

    npm install --save socket.io
    
  2. Tambahkan berikut ini ke app.js :

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
    
  3. Di bin / www , setelah var server = http.createServer (app) , tambahkan yang berikut ini:

    var sockIO = app.sockIO;
    sockIO.listen(server);
    
  4. Untuk menguji fungsionalitas, di app.js , Anda dapat menambahkan baris:

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

Tutorial untuk pemula dari Cedric Pabst
berikut adalah dasar-dasar singkat dari tautan untuk obrolan aplikasi:

menggunakan express-generate dan ejs engine yang dapat digunakan di setiap file .ejs perutean standar di express-generate

edit file bin \ www dan tambahkan app.io.attach (server) ini; seperti ini

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

edit di 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;

edit di 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>

Selamat bersenang-senang :) dan terima kasih banyak kepada Cedric Pabst

AnnaBanana
sumber
2

Beberapa jawaban sebelumnya tidak berfungsi dan yang lainnya terlalu rumit. Coba solusi berikut sebagai gantinya ...

Instal modul node socket.io sisi server dan sisi klien:

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

Sisi server

Tambahkan kode berikut untuk bin / www setelah definisi 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' });
});

Sisi klien

Jika menggunakan webpack, tambahkan kode berikut ke file entry.js webpack Anda :

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)
});

Selesai. Kunjungi situs Anda dan periksa konsol pengembang js browser.

s2t2
sumber