在Express 4和express-generator的/ bin / www中使用socket.io


93

所以这是交易:我正在尝试在一个快速项目中使用socket.io。发布Express Js 4之后,我更新了express-generator,现在应用程序的初始功能进入了./bin/www文件,包括那些var(www文件内容:http : //jsfiddle.net/avMa5/

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

(检查通过npm install -g express-generator,然后express myApp

话虽这么说,让我们记住socket.io文档如何要求我们将其触发:

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

好的,但是我无法像推荐的那样在app.js中执行此操作。为了正常工作,这应该在./bin/www中完成。在./bin/www中,这是我可以做的事情:

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

好的,这行得通,但是我不能在其他任何地方使用io var,我真的不想将我的socket.io函数放在www文件中。

我想这只是基本语法,但我什至无法使用它,甚至不能在www文件上使用module.exports = serverserver.exports = servermodule.exports.io = app(io)

因此,问题是:如何使用具有该/ bin / www文件的socket.io作为我的应用程序的起点?


您不必将导入内容放入./bin/www.。只需将它放在您所在的var app位置即可。
alandarev 2014年

15
希望人们不再建议Express-io。它已过时,不再维护。
Ben Fortune

@Mritunjay谢谢您,但它没有解决问题:/
user1576978 2014年

@BenFortune很抱歉,我会记住这一点。
Mritunjay 2014年

@alandarev var app = express()?? 我尝试了一下,但没有成功
user1576978 2014年

Answers:


160

我有一个使socket.io在app.js中可用的解决方案。

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

(...)

这样,您可以通过在app.js中访问io变量,甚至通过将module.exports定义为接受io作为参数的函数来使其对路由可用。

index.js

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

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

    return router;
}

然后,在设置后将io传递到模块中:

app.js

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

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

1
我是NodeJS的新手。能否请您解释究竟是该线路上发生 app.io = io;的在app.js文件
Aryak森古普塔

3
只需将io变量放入app对象即可。也可能是:app.io = socket_io();
加百利Hautclocq 2015年

7
“ ...甚至可以根据需要将其提供给您的路线。” 好的,但是如何?如果您可以举一个例子来做,那就太好了。
scaryguy

2
是不是到自定义属性附加到app对象?最好使用符号或app.set()
亚历山大·贡奇

3
为什么app.io = io当您可以使用它module.exports = { app, io }代替时
Manan Mehta

56

稍微不同的启动方法socket.io,它将所有相关代码集中在一个位置:

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

这样socket.io,我可以从应用程序中的任何位置调用一个模块中的所有相关代码和功能。


4
这个答案值得更多的投票!非常简单和干净,它将套接字路由保留在wwwapp.js以及index.js之外(是的,在index.js之外),此文件应仅包含Express HTTP路由。
adelriosantiago


3
谁能为socket.io 2.0更新它?它对我不起作用。io.attach(server)和io.listen(server)都抛出“无法读取未定义的属性X”。
tsujp

1
也跟@tsujp我的作品说话一样。您必须单击正确的URL并添加socket.io客户端,然后它才能正常工作
Tamb

我有一个与@tsujp类似的问题,我正在使用socket.io 2.3.0,并且正在获取io.attach is not a function
raquelhortab

42

事实证明,这确实是一些基本的sintax问题。...我从这个socket.io聊天教程中获得了这些代码...

在./bin/www之后 var server = app.listen(.....)

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

所以现在我创建../sockets/base.js文件,并将这个小家伙放进去:

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

是的 现在可以正常工作了……所以我想除了在/ bin / www内部启动socket.io之外,我别无选择,因为那是我的http服务器启动的地方。目标是,现在我可以在其他文件中构建套接字功能,通过以下方式保持事物的模块化require('fileHere')(io);

<3


1
问题是,您不能做类似的事情io.on('connection', function(socket) { res.render('connection.jade') });
Gofilord 2014年

3
@Gofilord这是因为它违反了套接字的全部目的……您需要的是包含渲染的常规路由。套接字就在这里,无需HTTP请求即可在客户端和服务器之间发送消息。也许读这篇文章enterprisewebbook.com/ch8_websockets.html
Unispaw

19

旧的“ expressjs”,一切都在文件“ app.js”中进行。因此,套接字.io与服务器的绑定也发生在该文件中。(顺便说一句,仍然可以使用旧方法,并删除bin / www)

现在使用新的expressjs,它需要在“ bin / www”文件中进行。

幸运的是,javascript / requirejs使传递对象变得容易。正如Gabriel Hautclocq指出的那样,socket.io仍被“导入”到“ app.js”中,并且通过属性附加到“ app”对象上

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

通过将服务器附加到“ bin / www”中,使socket.io生效

app.io.attach(server); 

因为“ app”对象早先传递到“ bin / www”中

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

真的很简单

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

但是以“困难”的方式进行操作可以确保app.io现在保存socke.io对象。

现在,例如,如果您还需要在“ routes / index.js”中使用此socket.io对象,只需使用相同的原理来传递该对象即可。

首先在“ app.js”中,

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

然后在“ routes / index.js”中

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

    var router = express.Router();



    return router;
 }

因此,“ io”被注入到“ index.js”中。


9

更新Gabriel Hautclocq的回复:

在www文件中,由于Socket.io的更新,代码应显示如下。附件现在为监听。

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

另外,要使该连接正常工作,还需要实现客户端API。这不是Express特有的,但是如果没有Express,则connect调用将无法工作。该API包含在

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

将此文件包括在前端,并进行以下测试:

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

7

阅读完所有注释后,我使用Socket.io Server版本提出了以下建议:1.5.0

我遇到的问题:

  1. var sockIO = require('socket.io')应该是 var sockIO = require('socket.io')()。(提供给:浙沪

  2. sockIO.attach应该是sockIO。(提供给rickrizzo

脚步

  1. 使用以下命令安装Socket.io:

    npm install --save socket.io
  2. 将以下内容添加到app.js

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
  3. bin / www中,在var server = http.createServer(app)之后,添加以下内容:

    var sockIO = app.sockIO;
    sockIO.listen(server);
  4. 要测试功能,可以在app.js中添加以下行:

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

5

来自Cedric Pabst的初学者教程,
这里是应用程序聊天链接的简短基础知识:

使用express-generate和可在express-generate的每个.ejs文件标准路由中使用的ejs引擎

编辑文件bin \ www并添加此app.io.attach(server); 像这样

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

app.js中编辑

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

index.ejs中编辑

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

玩得开心:),并感谢塞德里克·帕布斯特Cedric Pabst)


2

先前的某些答案无效,而另一些则过于复杂。请尝试以下解决方案...

安装服务器端和客户端socket.io节点模块:

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

服务器端

在服务器定义之后,将以下代码添加到bin / www中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' });
});

客户端

如果使用webpack,请将以下代码添加到webpack entry.js文件中:

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

做完了 访问您的网站并检查浏览器的js开发者控制台。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.