Verwenden von socket.io in Express 4 und / bin / www des Expressgenerators

92

Also hier ist der Deal: Ich versuche, socket.io in einem Express-Projekt zu verwenden. Nachdem Express Js 4 gestartet wurde, habe ich meinen Express-Generator aktualisiert und jetzt gehen die anfänglichen Funktionen der App in die ./bin/wwwDatei, einschließlich dieser Variablen (www-Dateiinhalt: http://jsfiddle.net/avMa5/ ).

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

(Überprüfen Sie es bis npm install -g express-generatorund dannexpress myApp

Lassen Sie uns trotzdem daran denken, wie die Dokumente von socket.io uns bitten, sie abzufeuern:

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

Ok, aber ich kann es nicht in app.js machen, wie empfohlen. Dies sollte in ./bin/www erfolgen, um zu funktionieren. in ./bin/www ist dies, was ich tun kann, um es zum Laufen zu bringen:

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

Ok, das funktioniert, aber ich kann das io var nirgendwo anders verwenden, und ich möchte meine socket.io-Funktionen wirklich nicht in eine wwwDatei einfügen .

Ich denke , das nur grundlegende Syntax ist, aber ich kann das nicht an der Arbeit, nicht einmal mit module.exports = serveroder server.exports = servernoch module.exports.io = app(io)auf www - Datei

Die Frage ist also: Wie kann ich socket.io verwenden, wenn diese / bin / www-Datei als Ausgangspunkt für meine App dient?

user1576978
quelle
Sie müssen den Import nicht eingeben ./bin/www.. Stellen Sie es einfach an den gleichen Ort, an dem Sie sich var appbefinden.
Alandarev
15
Ich wünschte, die Leute würden aufhören, Express-Io vorzuschlagen. Es ist veraltet und wird nicht mehr gewartet.
Ben Fortune
@Mritunjay danke, aber es hat es nicht gelöst: /
user1576978
@ BenFortune Entschuldigung, das werde ich mir merken.
Mritunjay
@alandarev var app = express () ?? Ich habe es tatsächlich versucht, kein Erfolg
user1576978

Antworten:

160

Ich habe eine Lösung, um socket.io in app.js verfügbar zu machen.

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

(...)

Auf diese Weise können Sie auf die Variable io in Ihrer app.js zugreifen und sie sogar Ihren Routen zur Verfügung stellen, indem Sie module.exports als eine Funktion definieren, die io als Parameter akzeptiert.

index.js

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

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

    return router;
}

Übergeben Sie dann io in das Modul, nachdem es eingerichtet wurde:

app.js.

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

var routes = require('./routes/index')(io);
Gabriel Hautclocq
quelle
1
Ich bin neu bei NodeJS. Können Sie bitte erklären, was genau in dieser Zeile app.io = io;in der app.jsDatei
passiert
3
Es geht einfach darum, die Variable io in das App-Objekt einzufügen. Es könnte auch sein: app.io = socket_io ();
Gabriel Hautclocq
7
"... und stellen Sie es sogar Ihren Routen zur Verfügung, wenn Sie möchten." Okay, aber wie? Es wäre großartig, wenn Sie ein Beispiel dafür geben könnten.
Scaryguy
2
Ist es nicht schlecht , eine benutzerdefinierte Eigenschaft an das appObjekt anzuhängen ? Verwenden Sie besser Symbole oder app.set().
Alexander Gonchiy
3
Warum, app.io = iowenn Sie module.exports = { app, io }stattdessen verwenden könnten
Manan Mehta
56

Ein etwas anderer Ansatz zum Initiieren socket.io: Er gruppiert den gesamten zugehörigen Code an einem Ort:

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

Auf diese Weise socket.iokann ich den gesamten zugehörigen Code in einem Modul und dessen Funktion von überall in der Anwendung aufrufen.

Anatoly
quelle
4
Diese Antwort verdient mehr positive Stimmen! Sehr einfach und sauber, es hält Socket-Routen außerhalb von www , app.js und auch außerhalb von index.js (ja, außerhalb von index.js ). Diese Datei sollte nur Express-HTTP-Routen enthalten.
Adelriosantiago
1
Erstaunlich, sehr sauber
Sanket
3
Kann jemand dies für socket.io 2.0 aktualisieren? Es funktioniert nicht für mich. io.attach (Server) und io.listen (Server) werfen beide "Eigenschaft X von undefined kann nicht gelesen werden".
Tsujp
1
Auch mit @tsujp zu sprechen, funktioniert genauso. Sie müssen die richtige URL treffen und den socket.io-Client hinzufügen, und Sie werden sehen, dass es funktioniert
Tamb
Ich habe ein ähnliches Problem wie @tsujp, ich verwende socket.io 2.3.0 und bekommeio.attach is not a function
raquelhortab
42

Es stellt sich heraus, dass es wirklich ein grundlegendes Problem mit der Sintax war ... Ich habe diese Zeilen aus diesem Chat-Tutorial für socket.io erhalten ...

am ./bin/www, gleich danach var server = app.listen(.....)

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

Jetzt erstelle ich die Datei ../sockets/base.js und lege diesen kleinen Kerl hinein:

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

Ja! Jetzt funktioniert es ... Ich glaube, ich hatte wirklich keine andere Option als das Starten von socket.io in / bin / www, da dort mein http-Server gestartet wurde. Das Ziel ist, dass ich jetzt Socket-Funktionalität in anderen Dateien erstellen kann, wobei das Ding modular bleibtrequire('fileHere')(io);

<3

user1576978
quelle
1
Das Problem ist, Sie können so etwas nicht tunio.on('connection', function(socket) { res.render('connection.jade') });
Gofilord
3
@Gofilord, weil es den gesamten Zweck von Sockets zunichte macht ... was Sie brauchen, ist reguläres Routing, einschließlich Rendering. Sockets sind nur hier, um Nachrichten zwischen Client und Server ohne http-Anforderungen zu senden. Vielleicht lesen Sie diesen Artikel enterprisewebbook.com/ch8_websockets.html
Unispaw
19

Bei den alten "expressjs" passiert alles in der Datei "app.js". Die Bindung von socket.io an den Server erfolgt also auch in dieser Datei. (Übrigens kann man es immer noch auf die alte Art machen und bin / www entfernen)

Jetzt mit den neuen Expressjs muss es in der "bin / www" -Datei geschehen.

Glücklicherweise machte es Javascript / requirejs einfach, Objekte weiterzugeben. Wie Gabriel Hautclocq betonte, wird socket.io immer noch in "app.js" "importiert" und über eine Eigenschaft an das "app" -Objekt angehängt

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

Die socket.io wird live geschaltet, indem der Server in "bin / www" daran angeschlossen wird.

app.io.attach(server); 

weil das Objekt "app" früher an "bin / www" übergeben wurde

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

Es ist wirklich genauso einfach wie

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

Aber es "schwierig" zu machen, stellt das sicher app.ioWenn jetzt das Objekt socke.io gespeichert ist.

Wenn Sie dieses socket.io-Objekt beispielsweise auch in "routen / index.js" benötigen, verwenden Sie einfach dasselbe Prinzip, um dieses Objekt weiterzugeben.

Zuerst in "app.js"

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

Dann in "routen / index.js"

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

    var router = express.Router();



    return router;
 }

Also wird "io" in "index.js" eingefügt.

Zhe Hu
quelle
9

Update zu Gabriel Hautclocqs Antwort:

In der WWW-Datei sollte der Code aufgrund von Aktualisierungen mit Socket.io wie folgt aussehen. Anhängen ist jetzt Hören.

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

Um diese Verbindung zum Laufen zu bringen, muss außerdem die clientseitige API implementiert werden. Dies ist nicht Express-spezifisch, aber ohne es funktioniert der Verbindungsaufruf nicht. Die API ist in enthalten

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

Fügen Sie diese Datei in das Frontend ein und testen Sie Folgendes:

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

Nachdem ich alle Kommentare gelesen hatte, kam ich mit Socket.io Server Version: 1.5.0 auf Folgendes

Probleme, auf die ich gestoßen bin:

  1. var sockIO = require ('socket.io') sollte var sockIO = require ('socket.io') () sein . (Bildnachweis an: Zhe Hu )

  2. sockIO.attach sollte sockIO sein. hören ( Bildnachweis : rickrizzo )

Schritte

  1. Installieren Sie Socket.io mit dem folgenden Befehl:

    npm install --save socket.io
  2. Fügen Sie app.js Folgendes hinzu :

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
  3. In bin / www nach var server = http.createServer (app) Folgendes hinzu:

    var sockIO = app.sockIO;
    sockIO.listen(server);
  4. Um die Funktionalität zu testen , können Sie in app.js die folgende Zeile hinzufügen:

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

Ein Tutorial für Anfänger von Cedric Pabst
hier sind die kurzen Grundlagen des Links für einen App-Chat:

Verwenden von Express-Generieren und der EJS-Engine, die in jedem Standard-Routing von .ejs-Dateien in Express-Generieren verwendet werden kann

Bearbeiten Sie die Datei bin \ www und fügen Sie diese app.io.attach (Server) hinzu. so was

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

in app.js bearbeiten

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

in index.ejs bearbeiten

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

Viel Spaß :) und vielen Dank an Cedric Pabst

AnnaBanana
quelle
2

Einige frühere Antworten funktionieren nicht und andere sind zu kompliziert. Versuchen Sie stattdessen die folgende Lösung ...

Installieren Sie serverseitige und clientseitige socket.io-Knotenmodule:

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

Serverseitig

Fügen Sie den folgenden Code ist / www nach der Serverdefinition, 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' });
});

Client-Seite

Wenn Sie webpack verwenden, fügen Sie der Datei webpack entry.js den folgenden Code hinzu :

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

Getan. Besuchen Sie Ihre Website und überprüfen Sie die js-Entwicklerkonsole des Browsers.

s2t2
quelle