【发布时间】:2016-05-20 17:29:55
【问题描述】:
请见谅,我正在学习。 :)
我已经设置了 Socket.IO,这样我就可以在我的路由中使用 io.sockets.emit,并且我可以正常工作。有一些问题。
-
(已解决?查看编辑 3) 要使用,我不能以
李>socket开头。我必须从io开始,否则我得到“ReferenceError:未定义套接字”。我希望能够使用socket.broadcast.emit将事件发送给除当前用户之外的所有客户端。现在,如果是当前用户,我必须在客户端进行检查以不执行该事件,并且随着项目的进行,我不得不发出更多事件,这变得非常头疼。 (已解决,请参见编辑 1 和 2) 每次我进行服务器端更改时,我都必须使用
node app.js运行应用程序并手动重新启动服务器。当我运行 nodemon 时,我得到“端口 3000 已在使用中”。我觉得这一定和以下有关……(已解决,请参阅编辑 2) 推送到 Heroku 时,我在 bin/www 和 app.js 中将以下代码中的端口从 3000 更改为 80,但确实如此不起作用(我可以在控制台中看到套接字的 404 错误)。如果这和 #2 是由在两个地方处理 http/ports 引起的,我该如何正确设置它以及为什么
node app.js工作?我只需要在下图(战场)的路线上运行Socket.IO即可。我已经用
require('./routes/battlefield')(io)做这个了吗?
bin/www
var app = require('../app');
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
var server = http.createServer(app);
server.listen(port);
app.js
var app = express();
var http = require('http').Server(app);
http.listen(3000);
var io = require('socket.io')(http);
app.set('socketio', io);
var battlefield = require('./routes/battlefield')(io);
battlefield.js
var express = require('express');
var router = express.Router();
var returnRouter = function(io) {
router.get('/', function(req, res, next) {
// other stuff
io.sockets.emit('message', 'This works');
socket.broadcast.emit('message', 'Socket is undefined');
})
return router;
};
module.exports = returnRouter;
我尝试将我的路由包装在io.on('connection', function (socket) { 中以便能够使用socket,而不是“套接字未定义”,该事件不会发生。
var returnRouter = function(io) {
io.on('connection', function (socket) {
router.get('/', function(req, res, next) {
// other stuff
socket.emit('message', 'This is never emitted');
})
})
return router;
};
对于这么长的问题,我深表歉意。感谢您的任何帮助! ????
EDIT1:写出这个问题帮助我更好地理解了这个问题。我在我的 bin/www 中注释掉了server.listen(port);,nodemon 现在可以工作了。但是,该应用程序在 Heroku 上崩溃了。我的 Procfile 是 web: node ./bin/www... 需要更改吗?
EDIT2:在弄清楚Edit1和谷歌搜索后,我发现我不能拥有server.listen();(bin/www)和http.listen(3000);(应用程序.js)。
在 bin/www 中,我删除了server.listen();。
在 app.js 中,为了清楚起见,我将 var http = ... 更改为 var server = ... 并让它监听来自 bin/www 的 process.env.PORT || '3000';。我还删除了app.set('socketio', io);,因为它看起来好像什么都没做......我想知道它为什么在那里。
app.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var port = process.env.PORT || '3000';
server.listen(port);
这也让 Heroku 工作,因为 process.env.PORT,万岁!我猜node app.js 起作用了,因为我正在使用 app.js 初始化应用程序,我猜你这样做时 bin/www 没有执行?
我仍然需要关于 #1 的帮助(使用 socket.broadcast.emit)????.
编辑 3: 好吧,我确实花了一整天的时间,但我相信我有一个怪癖。当然我不能使用socket,它是连接时给出的参数。我还需要跨不同路由访问套接字并找到this SO question。这就是我最终在 Battleground.js 中所做的:
var returnRouter = function(io) {
var socket;
router.get('/', authenticatedUser, function(req, res, next) {
io.on('connection', function(client){
socket = client;
});
// other stuff
res.render('battlefield', {/* data */});
setTimeout(function(){socket.emit('test', 'It works!')}, 500);
});
router.post('/', function(req, res, next) {
// socket can be accessed
});
return router;
};
module.exports = returnRouter;
(注意:我取出了很多我自己的代码,所以我不知道这是否可以复制和粘贴,你可能应该检查套接字是否不为空)
如果没有setTimeout,则在 GET '/' 上未定义套接字。据我了解,页面必须首先呈现......奇怪的是,200 有时对我不起作用,而 500 则可以。我可以将其保留为 500,但这是为了游戏,所以时间非常重要。
我现在的问题是:
这可以改进吗/有没有办法在没有 setTimeout 的情况下做到这一点?我是否用这段代码正确地“连接”了客户端,我(上面的问题#4^)是否有效地使用了 Socket.IO?
附:如果没有人回答 ^ 这些问题,我将对此进行编辑,回答问题,并接受我的回答作为最佳答案。
【问题讨论】: