webentwicklung-frage-antwort-db.com.de

Wie kann ich socket.io in nodejs in andere Module exportieren?

Ich habe socket.io in app.js gearbeitet, aber wenn ich versuche, es von anderen Modulen aus aufzurufen, erstellt er nicht io.connection nicht sicher?

app.js

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var ditconsumer = require('./app/consumers/ditconsumer');
ditconsumer.start(io);
server.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});

consumer.js

module.exports = {
    start: function (io) {
        consumer.on('message', function (message) {
            logger.log('info', message.value);
            io.on('connection', function (socket) {
                socket.on('message', function(message) {
                    socket.emit('ditConsumer',message.value);
                    console.log('from console',message.value);
                });
            });
        });
}
}
15
hussain

Da app.js in der Regel eine Art Hauptinitialisierungsmodul in Ihrer App ist, initialisiert es normalerweise sowohl den Webserver als auch socket.io und lädt andere Dinge, die von der App benötigt werden. 

Ein typischer Weg, io mit anderen Modulen gemeinsam zu nutzen, besteht darin, sie an die anderen Module in der Konstruktorfunktion dieses Moduls zu übergeben. Das würde so funktionieren:

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

// load consumer.js and pass it the socket.io object
require('./consumer.js)(io);

// other app.js code follows

Dann in consumer.js:

// define constructor function that gets `io` send to it
module.exports = function(io) {
    io.on('connection', function(socket) {
        socket.on('message', function(message) {
            logger.log('info',message.value);
            socket.emit('ditConsumer',message.value);
            console.log('from console',message.value);
        });
    });
};

Oder, wenn Sie eine .start()-Methode zum Initialisieren von Dingen verwenden möchten, können Sie dasselbe tun (geringfügige Unterschiede):

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

// load consumer.js and pass it the socket.io object
var consumer = require('./consumer.js);
consumer.start(io);

// other app.js code follows

Und die Startmethode in consumer.js

// consumer.js
// define start method that gets `io` send to it
module.exports = {
    start: function(io) {
        io.on('connection', function(socket) {
            socket.on('message', function(message) {
                logger.log('info',message.value);
                socket.emit('ditConsumer',message.value);
                console.log('from console',message.value);
            });
        });
    };
}

Dies ist das sogenannte "Push" -Modul für die gemeinsame Nutzung von Ressourcen. Das von Ihnen geladene Modul sendet Ihnen einige gemeinsam genutzte Informationen, indem Sie diese im Konstruktor übergeben.

Es gibt auch "Pull" -Modelle, bei denen das Modul selbst eine Methode in einem anderen Modul aufruft, um die gemeinsam genutzten Informationen abzurufen (in diesem Fall das io-Objekt).

Häufig kann eines der Modelle zum Laufen gebracht werden, aber in der Regel wird sich das eine oder andere natürlicher fühlen, wenn Module geladen werden und wer über die gewünschten Informationen verfügt und wie Sie beabsichtigen, dass Module unter anderen Umständen wiederverwendet werden.

25
jfriend00

Wenn Sie den globalen Gültigkeitsbereich vermeiden möchten, müssen Sie Ihre io in einer separaten Datei wie der folgenden definieren:

var sio = require('socket.io');
var io = null;

exports.io = function () {
  return io;
};

exports.initialize = function(server) {
  return io = sio(server);
};

Dann in app.js:

var server = require('http').createServer(app);
var io = require('./io').initialize(server);
require('./app/consumers/ditconsumer'); // loading module will cause desired side-effect
server.listen(...);

und in consumer.js:

require('../io').io().on('connection', function(socket) {
  logger.log('info', message.value);
  socket.on('message', function(message) {
    socket.emit('ditConsumer',message.value);
    console.log('from console',message.value);
  });
});
19
Patrick Roberts

Sie können eine Singleton-Instanz in nur 4 Zeilen erstellen.

Schreiben Sie in websocket.js Ihren Server-Konfigurationscode.

const socketIO = require('socket.io');
const server = require('http').createServer();
server.listen(8000);

module.exports = socketIO(server);

Dann benötigen Sie in Ihrer consumer.js einfach die Datei

const socket = require('./websocket');

/* API logic here */

socket.emit('userRegistered', `${user.name} has registered.`);
1
Dušan Minić

Ich fand einfach Lösung Die Lösung ist recht einfach. Verwenden Sie die globale Variable in app.js und greifen Sie über andere Dateien darauf zu.

global.io = require('socket.io').listen(server);

1
Ko Man

Ich habe eine Datei erstellt socket.service.ts mit einer Klasse SocketService und in app.tsIch habe den Konstruktor mit dem http aufgerufen. Dies funktioniert auch mit reinem Javascript, nur die Importe und Exporte ändern ...

import * as socketIo from 'socket.io';

export class SocketService {

  io: any;

  constructor(http) {
    this.io = socketIo(http)
    this.io.set('origins', '*:*');
    this.io.on('connection', function (socket) {
      console.log('an user connected');
      socket.on('disconnect', function () {
        console.log('user disconnected');
      });
    });

    http.listen(3001, function () {
      console.log('socket listening on *:3001');
    });

  }

}

im app.ts Anruf ist wie:

import * as express from 'express';

import { SocketService } from './services/socket.service';

const app = express(); 
var http = require('http').Server(app);

// ...

new SocketService(http);

// ...

module.exports = app;

Beachten Sie, dass bei jedem Aufruf des Konstruktors eine neue Instanz erstellt wird. Um dies zu vermeiden, benutze das Singleton-Muster :)

0
kenny