【问题标题】:Run socket.io 2.0 and Express 4.0+ on the same port在同一个端口上运行 socket.io 2.0 和 Express 4.0+
【发布时间】:2017-06-24 09:36:14
【问题描述】:

我之前在 Node 项目上安装了 socket.io,不需要 express 模板框架。

问题

如果我添加这行代码:http.listen(3001, function() { console.log('listening on port 3001'); }); 然后在访问 localhost:3000 我的应用程序中 sockets 不起作用 并且 在 localhost:3001 我有 sockets 工作。如何合并这两者?

错误

socket.io.js:2 GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=LpQ6zKP net::ERR_CONNECTION_REFUSED

我正在尝试在 express 框架中添加 socket.io,如下所示:

app.js 文件

const express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var expressValidator = require('express-validator');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var multer = require('multer');
var upload = multer({ dest: './uploads' });
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection;

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

var app = express();
var http = require( "http" ).createServer( app );
var io = require( "socket.io" )( http );
http.listen(3000, "127.0.0.1");

var httpk = require('http');
var nsp = io.of('/channel1');
var connectCounter = 0;
var interval = undefined;

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');


app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js')); // redirect bootstrap JS
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist')); // redirect jQuery JS
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // redirect Bootstrap CSS

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

//Handle express sessions
app.use(session({
    secret:'secret',
    saveUninitialized: true,
    resave:true
}));

// Passport
app.use(passport.initialize());
app.use(passport.session());

// Validator
app.use(expressValidator({
  errorFormatter: function(param, msg, value) {
      var namespace = param.split('.')
      , root    = namespace.shift()
      , formParam = root;

    while(namespace.length) {
      formParam += '[' + namespace.shift() + ']';
    }
    return {
      param : formParam,
      msg   : msg,
      value : value
    };
  }
}));

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

//For flash messages
app.use(flash());
app.use(function (req, res, next) {
  res.locals.messages = require('express-messages')(req, res);
  next();
});

app.get('*', function(req, res, next){
    res.locals.user = req.user || null;
    next();
});

app.use('/', index);

function test() {
    httpk.get("api-url", function(res) {
        var body = '';
        res.on('data', function(data) {
            body += data;
        });

        res.on('end', function() {
            var parsed = JSON.parse(body);
            //console.log(parsed.data.product1);
            var dataArray = [];
            dataArray.push((parseFloat(parsed.data.product1) + Math.random() * 0.1 + 0.01).toFixed(2));
            dataArray.push((parseFloat(parsed.data.product2) + Math.random() * 0.1 + 0.01).toFixed(2));
            console.log(dataArray);
            nsp.emit('live-quote', dataArray);
        });
    });
}


nsp.on('connection', function(socket) {

    socket.on('pass_data', function(my) {
        console.log(my);
    });

    //Make a http call
    connectCounter++;
    if (interval === undefined) interval = setInterval(test, 1000);
    nsp.emit('live-users', connectCounter);
    console.log('1 user connected, Total Joined: ' + connectCounter);

    socket.on('disconnect', function() {
        connectCounter--;
    if (connectCounter <= 0 && interval !== undefined) interval = clearInterval(interval);
        nsp.emit('live-users', connectCounter);
        console.log('1 user disconnected, Total Left: ' + connectCounter);
    });
    console.log("total clients: " + io.engine.clientsCount);
});


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

head.ejs

<title><%= title %></title>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>

<link rel='stylesheet' href='/stylesheets/style.css' />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" >

jsdefaults.ejs

<script src="/javascripts/script.js" ></script>

<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>

  <script>
  $(function() {
    var socket = io('/channel1');
    var currentTime;

    socket.on('live', function(msg) {

        console.log("msg: "+msg);

    });

    socket.on('live-users', function(users) {
        $('#total').text(users);
    });
});

</script>

index.ejs

<!DOCTYPE html>
<html>
  <head><% include partials/head.ejs %></head>
  <body>
    <% include partials/header.ejs %>
    <div class="container" style="margin-top:20px;">

</div>
    <% include partials/footer.ejs %>
    <% include partials/jsdefaults.ejs %>
  </body>
</html>

【问题讨论】:

  • 你为服务器做一个监听器吗?喜欢server.listen(3000, () =&gt; {// lol})?
  • @FelixFong 我猜它正在监听端口 3000。我不确定我找不到 server.listen 的代码,但是当我输入 npm start 时。我正在访问 localhost:3000 所以在后台某处它正在监听端口 3000
  • @FelixFong 如果我添加这行代码:http.listen(3001, function() { });然后在访问 localhost:3000 时,我的应用程序中的套接字无法正常工作,而在 localhost:3001 上,我的套接字正在工作。如何合并这两者?
  • @MurlidharFichadia 如果您使用过express-generator(我认为您已经使用过),您需要将io 的内容移至bin/www,因为这是创建HTTP 服务器的位置 开始(不是一个理想的解决方案,但那是因为你必须解决express-generator 构建应用程序的方式)
  • @robertklep 是的,我使用过 express-generator。我不介意将代码移动到 bin/www 但如果你能告诉我我要准确移动代码的哪一部分以及在 jsdefaults.js 上修改代码的哪一部分?我已经更新了我的问题和代码。如果您能帮我解决问题,我会接受您的回答

标签: node.js sockets express socket.io


【解决方案1】:

您似乎使用express-generator 来设置您的Express 应用程序,在这种情况下,HTTP 服务器将设置在bin/www 中,而socket.io 服务器也应该设置在此处(因为您想要在 Express 和 socket.io 之间共享 HTTP 服务器。

默认的bin/www 包含以下内容:

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

这就是您添加socket.io 服务器的地方:

var server = http.createServer(app);
var io     = require('socket.io')(server);
var nsp    = io.of('/channel1');

nsp.on('connection', ...);

【讨论】:

  • 效果很好。但现在我有功能测试和 nsp.on('connection', ...); www 文件中的代码。我还将连接到 db 并与之交互。有没有办法我可以在 www 文件上只保留那 2 或 3 行代码而仍然在 app.js 文件上?我现在不确定如何用 mongo 组织这个
  • @MurlidharFichadia tbh,express-generator 的默认结构是 PITA,您可能需要考虑完全重构您的应用程序并完全取出 bin/www
  • 我明白你的意思。我的项目不是很大,我想我会摆脱 express-generator 。谢谢
猜你喜欢
  • 2015-01-07
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 2013-12-18
  • 1970-01-01
  • 2017-11-04
相关资源
最近更新 更多