Javascript 如何将socket.io导出到nodejs中的其他模块中?
我有Javascript 如何将socket.io导出到nodejs中的其他模块中?,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,我有socket.io在app.js中工作,但是当我试图从其他模块调用它时,它没有创建io.connection不确定 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/consumer
socket.io
在app.js
中工作,但是当我试图从其他模块调用它时,它没有创建io.connection
不确定
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);
});
});
});
}
}
// 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);
});
});
};
}
const app=require('./app.js')
const io=app.getSocketIo()
如果要避免全局作用域,请将您的
io
放在一个单独的文件中,如下所示:
var sio = require('socket.io');
var io = null;
exports.io = function () {
return io;
};
exports.initialize = function(server) {
return io = sio(server);
};
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
然后在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(...);
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);
});
});
在consumer.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(...);
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);
});
});
由于app.js通常是应用程序中的主要初始化模块,因此它通常会初始化web服务器和socket.io,并加载应用程序所需的其他内容 因此,与其他模块共享
io
的典型方法是将它们传递给该模块构造函数中的其他模块。这将是这样的:
var sio = require('socket.io');
var io = null;
exports.io = function () {
return io;
};
exports.initialize = function(server) {
return io = sio(server);
};
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
然后,在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);
});
});
};
或者,如果您想使用
.start()
方法初始化内容,您可以使用该方法执行相同的操作(细微差别):
以及consumer.js中的start方法
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);
});
});
});
}
}
// 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);
});
});
};
}
const app=require('./app.js')
const io=app.getSocketIo()
这就是所谓的资源共享的“推送”模块。正在加载的模块通过在构造函数中传递一些共享信息来推送给您 还有一些“拉”模型,其中模块本身调用其他模块中的方法来检索共享信息(在本例中为
io
对象)
通常,这两种模型都可以正常工作,但考虑到模块的加载方式、谁拥有所需的信息以及您打算在其他情况下如何重用模块,这两种模型通常会感觉更自然。您可以在4行代码中创建一个单例实例 在websocket.js中编写服务器配置代码
const socketIO = require('socket.io');
const server = require('http').createServer();
server.listen(8000);
module.exports = socketIO(server);
然后在你的consumer.js中只需要这个文件
const socket = require('./websocket');
/* API logic here */
socket.emit('userRegistered', `${user.name} has registered.`);
我找到了一个简单的方法。
在app.js中使用全局变量,并从其他文件访问它
global.io=require('socket.io')。侦听(服务器)
我用一个类SocketService创建了一个文件socket.service.ts
,在app.ts
中,我用http调用了构造函数。这也适用于纯javascript,只需更改导入和导出
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');
});
}
}
在app.ts
中,调用类似于:
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;
请注意,每次调用构造函数时,都会创建一个新实例。为了避免这种情况,请使用singleton模式:)对我来说最有效的方法是使用一个回调函数来导出socket.io实例。 app.js: 在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);
});
});
});
}
}
// 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);
});
});
};
}
const app=require('./app.js')
const io=app.getSocketIo()
您可以很容易地做到这一点,您只需在app.js中编写套接字连接,然后就可以在任何地方使用套接字 在app.js文件中放入如下代码
var http = require('http').createServer(app);
const io = require('socket.io')(http);
io.sockets.on("connection", function (socket) {
// Everytime a client logs in, display a connected message
console.log("Server-Client Connected!");
socket.join("_room" + socket.handshake.query.room_id);
socket.on('connected', function (data) {
});
});
const socketIoObject = io;
module.exports.ioObject = socketIoObject;
http.listen(port, () => {
console.log('Magic happens on port ' + port); // shoutout to the user
});
const socket = require('../app'); //import socket from app.js
//you can emit or on the events as shown
socket.ioObject.sockets.in("_room" + req.body.id).emit("msg", "How are You ?");
在任何文件或controller
中,您都可以像下面那样导入该对象
var http = require('http').createServer(app);
const io = require('socket.io')(http);
io.sockets.on("connection", function (socket) {
// Everytime a client logs in, display a connected message
console.log("Server-Client Connected!");
socket.join("_room" + socket.handshake.query.room_id);
socket.on('connected', function (data) {
});
});
const socketIoObject = io;
module.exports.ioObject = socketIoObject;
http.listen(port, () => {
console.log('Magic happens on port ' + port); // shoutout to the user
});
const socket = require('../app'); //import socket from app.js
//you can emit or on the events as shown
socket.ioObject.sockets.in("_room" + req.body.id).emit("msg", "How are You ?");
这很容易解决了我的问题我在consumer.js中添加了
var socket=require('../index').io()
,但它的抛出错误是TypeError:require(…).io不是一个函数
是您添加的名为index.js
的新文件吗index.js
有代码exports.io=function(){return io;}代码>?您确定该文件位于相对于consumer.js
的正确位置吗?这家伙,这家伙f**ks#管接头引用。与这个小模块伙伴的出色合作,在我正在做的一个练习中帮了我不少忙。因此,如果我需要io
对象,我需要在每个模块中创建io.on
连接,就像你为consumer.js
@hussain所做的那样-如果你试图侦听来自连接套接字的传入消息,然后您需要io.on('connection,…)
才能访问连接的套接字。当然,还有其他方法可以构建这样的东西:您有一个中央的io.on('connection,…)
,其他模块可以提供消息侦听器,但这是您的代码中的一个更大的变化,我们必须更多地了解您在做什么,以了解最好的推荐。但是,拥有多个io.on('connection,…)
侦听器也没什么大不了的io
是一个eventEmitter
并且内置了很多监听器。实际上,我已经为消费者更新了问题代码,我已经将消费者导出到app.js中,是否可以在SDE消费者对象中添加module.export函数?是的。。我忘记了这个方法。事实上,我比我更喜欢这个建议。@hussain-你对消费者的修改完全符合这个总体方案。如果要保留导出的start
方法,只需将io
传递到start
方法并从那里获取它。关键是让app
模块将io
对象传递给consumer
模块,作为consumer
模块启动/初始化的一部分。但是,您所展示的内容看起来就像您可以用我建议的内容替换现有内容,并使用构造函数而不是start()
方法-尽管两者都可以很好地工作。这非常好。但是有人知道这有什么安全问题吗?