Socket.io'yu Express 4 ve express-generator / bin / www'da kullanma


93

İşte anlaşma: socket.io'yu hızlı bir projede kullanmaya çalışıyorum. Express Js 4 lauch edildikten sonra, ekspres oluşturucumu güncelledim ve şimdi ./bin/wwwbu değişkenler de dahil olmak üzere uygulamanın ilk işlevleri dosyaya giriyor (www dosya içeriği: http://jsfiddle.net/avMa5/ )

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

(kontrol edin npm install -g express-generatorve sonraexpress myApp

Soket.io belgelerinin bizden onu nasıl çalıştırmamızı istediğini hatırlayalım:

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

Tamam ama tavsiye edildiği gibi app.js içinde yapamıyorum. Bu, çalışmak için ./bin/www içinde yapılmalıdır. ./bin/www içinde, onu çalıştırmak için yapabileceğim şey bu:

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

Tamam bu işe yarıyor, ancak io var'ı başka hiçbir yerde kullanamıyorum ve gerçekten socket.io işlevlerimi wwwdosyaya koymak istemiyorum .

Bu sadece temel sözdizimi tahmin ediyorum, ama, işe bu olsun bile kullanmıyor olabilir module.exports = serverveya server.exports = serverne de module.exports.io = app(io)www dosya üzerinde

Öyleyse soru şu: Bu / bin / www dosyasını uygulamamın başlangıç ​​noktası olarak soket.io'yu nasıl kullanabilirim?


İçeri aktarmanız gerekmiyor ./bin/www.. Sadece senin var appolduğu yere koy .
alandarev

15
Keşke insanlar ekspres-io önermeyi bıraksalar. Modası geçmiş ve artık korunmuyor.
Ben Fortune

@Mritunjay teşekkür ederim, ama çözmedi: /
user1576978

@BenFortune üzgünüm bunu aklımda tutacağım.
Mritunjay

@alandarev var app = express () ?? Aslında denedim, başarı yok
user1576978

Yanıtlar:


161

Socket.io'yu app.js'de kullanılabilir hale getirmek için bir çözümüm var.

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

(...)

Bu şekilde, app.js'nizdeki io ​​değişkenine erişebilir ve hatta module.exports'u io'yu bir parametre olarak kabul eden bir işlev olarak tanımlayarak rotalarınızda kullanılabilir hale getirebilirsiniz.

index.js

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

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

    return router;
}

Ardından, kurulumdan sonra io'yu modüle geçirin:

app.js

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

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

1
NodeJS'de yeniyim. Eğer tam olarak bu hat üzerinde neler olduğunu açıklayabilir misiniz app.io = io;içinde app.jsdosyanın
Aryak Sengupta

3
Bu basitçe io değişkenini uygulama nesnesine yerleştirme meselesidir. Ayrıca şunlar da olabilir: app.io = socket_io ();
Gabriel Hautclocq

7
"... ve hatta isterseniz rotalarınız için kullanılabilir hale getirin." Tamam ama nasıl? Nasıl yapılacağına dair bir örnek verebilirseniz harika olur.
scaryguy

2
Nesneye özel bir özellik eklemek kötü değil appmi? Sembolleri veya app.set().
Alexander Gonchiy

3
Neden bunun yerine app.io = ione zaman kullanabilirsiniz?module.exports = { app, io }
Manan Mehta

60

Başlamak için biraz farklı bir yaklaşım socket.io, tüm ilgili kodları tek bir yerde gruplandırır:

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

Bu şekilde socket.io, bir modüldeki tüm ilgili kodlar ve ondan işlev, uygulamanın herhangi bir yerinden çağırabilirim.


4
Bu cevap daha fazla oyu hak ediyor! Çok basit ve temiz, soket yollarını www , app.js dışında ve ayrıca index.js dışında (evet, index.js dışında ) tutar, bu dosya yalnızca Express HTTP yollarını içermelidir.
adelriosantiago

1
Harika, çok temiz
sanket

3
Herkes bunu socket.io 2.0 için güncelleyebilir mi? Benim için çalışmıyor. io.attach (sunucu) ve io.listen (sunucu) her ikisi de "tanımsız X özelliğini okuyamıyor" atar.
Ürdün

1
Ayrıca @ tsujp ile konuşmak benim de aynı şekilde çalışıyor. Doğru url'yi bulup socket.io istemcisini eklemelisiniz ve çalıştığını göreceksiniz
Tamb

@Tsujp ile benzer bir sorunum var, socket.io 2.3.0 kullanıyorum ve alıyorumio.attach is not a function
raquelhortab

43

Gerçekten temel bir sintax sorunu olduğu ortaya çıktı .... Bu satırları bu socket.io sohbet öğreticisinden aldım ...

./bin/www üzerinde, hemen sonra var server = app.listen(.....)

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

şimdi ../sockets/base.js dosyasını oluşturuyorum ve bu küçük adamı içine koyuyorum:

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

Evet! Şimdi işe yarıyor ... Yani sanırım socket.io'yu / bin / www içinde başlatmaktan başka seçeneğim yoktu, çünkü http sunucumun başladığı yer burası. Amacım, artık diğer dosyalarda soket işlevselliği oluşturabilir ve bu şeyi modüler tutarak,require('fileHere')(io);

<3


1
Sorun gibi bir şey yapamaz, olduğuio.on('connection', function(socket) { res.render('connection.jade') });
Gofilord

3
@Gofilord, çünkü soketlerin tüm amacını ortadan kaldırır ... İhtiyacınız olan şey, oluşturmayı içeren düzenli yönlendirmedir. Soketler, http istekleri olmadan istemci ve sunucu arasında mesaj göndermek için buradadır. belki bu makaleyi okuyun enterprisewebbook.com/ch8_websockets.html
Unispaw

19

Eski "expressjs", her şey "app.js" dosyasında gerçekleşiyor. Yani socket.io'nun sunucuya bağlanması da bu dosyada gerçekleşir. (BTW, yine de eski yöntemle yapılabilir ve bin / www kaldırılabilir)

Şimdi yeni expressj'lerde bunun "bin / www" dosyasında olması gerekiyor.

Neyse ki, javascript / requirejs, nesnelerin etrafta dolaşmasını kolaylaştırdı. Gabriel Hautclocq'un belirttiği gibi, socket.io hala "app.js" içinde "içe aktarılıyor" ve bir özellik aracılığıyla "uygulama" nesnesine ekleniyor

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

Socket.io "bin / www" içindeki sunucuya eklenerek canlı hale getirilir.

app.io.attach(server); 

çünkü "uygulama" nesnesi daha önce "bin / www" içine aktarılır

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

Gerçekten de bu kadar basit

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

Ancak bunu "zor" yolla yapmak app.ioartık socke.io nesnesinin tutulmasını sağlar .

Şimdi bu socket.io nesnesine örneğin "route / index.js" içinde de ihtiyacınız varsa, o nesneyi etrafından geçirmek için aynı prensibi kullanın.

Önce "app.js" de

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

Sonra "yollar / index.js" de

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

    var router = express.Router();



    return router;
 }

Yani "io", "index.js" ye enjekte edilir.


9

Güncelle Gabriel Hautclocq bireyin tepkisi:

Www dosyasında, Socket.io ile yapılan güncellemeler nedeniyle kod aşağıdaki gibi görünmelidir. İliştir artık Dinle.

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

Ek olarak, bu bağlantının çalışması için istemci tarafı API'nin de uygulanması gerekir. Bu Eksprese özgü değildir, ancak onsuz bağlantı çağrısı çalışmayacaktır. API aşağıdakilere dahildir:

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

Bu dosyayı ön uca ekleyin ve aşağıdakilerle test edin:

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

7

Tüm yorumları okuduktan sonra Socket.io Sunucu Sürümü'nü kullanarak aşağıdakileri buldum: 1.5.0

Karşılaştığım sorunlar:

  1. var sockIO = require ('socket.io') , var sockIO = require ('socket.io') () olmalıdır . (Kredi: Zhe Hu )

  2. sockIO.attach, sockIO olmalıdır. listen (Kredi: rickrizzo )

Adımlar

  1. Socket.io'yu aşağıdaki komutla yükleyin:

    npm install --save socket.io
    
  2. Aşağıdakileri app.js'ye ekleyin :

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
    
  3. In bin / www , sonra var sunucu = http.createServer (uygulama) , şunları ekleyin:

    var sockIO = app.sockIO;
    sockIO.listen(server);
    
  4. İşlevselliği test etmek için app.js'de şu satırı ekleyebilirsiniz:

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

5

Cedric Pabst'tan yeni başlayanlar için bir öğretici,
bir uygulama sohbeti bağlantısının kısa temellerini burada bulabilirsiniz:

express-generate ve express-generate'daki her .ejs dosyası standart yönlendirmesinde kullanılabilen ejs motorunu kullanma

bin \ www dosyasını düzenleyin ve bu app.io.attach (sunucu) ekleyin; bunun gibi

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

düzenlemek 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;

düzenlemek 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>

İyi eğlenceler :) ve çok teşekkürler Cedric Pabst


2

Bazı önceki cevaplar işe yaramıyor ve diğerleri aşırı derecede karmaşık. Bunun yerine aşağıdaki çözümü deneyin ...

Sunucu tarafı ve istemci tarafı socket.io düğüm modüllerini kurun:

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

Sunucu tarafı

Aşağıdaki kodu ekleyin bin / www , sunucu tanımı sonra 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' });
});

İstemci tarafı

Webpack kullanıyorsanız, webpack entry.js dosyanıza aşağıdaki kodu ekleyin :

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

Bitti. Sitenizi ziyaret edin ve tarayıcının js geliştirici konsolunu kontrol edin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.