Sử dụng socket.io trong Express 4 và express-generator's / bin / www


93

Vì vậy, đây là thỏa thuận: Tôi đang cố gắng sử dụng socket.io trong một dự án cấp tốc. Sau khi Express Js 4 được thành công, tôi đã cập nhật trình tạo express của mình và bây giờ các chức năng ban đầu của ứng dụng sẽ được đưa vào ./bin/wwwtệp, bao gồm cả các vars đó (nội dung tệp www: http://jsfiddle.net/avMa5/ )

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

(kiểm tra nó bằng cách npm install -g express-generatorvà sau đóexpress myApp

điều đó đang được nói, chúng ta hãy nhớ cách các tài liệu socket.io yêu cầu chúng ta kích hoạt nó:

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

Được nhưng tôi không thể làm điều đó trong app.js, như được khuyến nghị. Điều này phải được thực hiện trong ./bin/www để hoạt động. trong ./bin/www, đây là những gì tôi có thể làm để nó hoạt động:

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

Ok, điều này hoạt động, nhưng tôi không thể sử dụng io var ở bất kỳ nơi nào khác và tôi thực sự không muốn đặt các hàm socket.io của mình vào wwwtệp.

Tôi đoán đây chỉ là cú pháp cơ bản, nhưng tôi không thể làm cho nó hoạt động, thậm chí không sử dụng module.exports = serverhoặc server.exports = servercũng không sử dụng module.exports.io = app(io)tệp www

Vì vậy, câu hỏi đặt ra là: làm thế nào tôi có thể sử dụng socket.io có tệp / bin / www này làm điểm bắt đầu của ứng dụng của tôi?


Bạn không cần phải nhập vào ./bin/www.. Chỉ cần đặt nó vào cùng một nơi, nơi của bạn var app.
alandarev

15
Tôi ước mọi người sẽ ngừng đề xuất express-io. Nó đã lỗi thời và không còn được duy trì.
Ben Fortune

@Mritunjay cảm ơn bạn, nhưng nó không giải quyết nó: /
user1576978

@BenFortune xin lỗi, tôi sẽ ghi nhớ điều đó.
Mritunjay

@alandarev var app = express () ?? Tôi acctually thử nó, không thành công
user1576978

Câu trả lời:


160

Tôi có một giải pháp để cung cấp socket.io trong 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 );

(...)

Bằng cách này, bạn có thể truy cập biến io trong app.js của mình và thậm chí cung cấp nó cho các tuyến của bạn bằng cách xác định module.exports dưới dạng một hàm chấp nhận io làm tham số.

index.js

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

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

    return router;
}

Sau đó, chuyển io vào mô-đun sau khi nó được thiết lập:

app.js

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

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

1
Tôi mới sử dụng NodeJS. Bạn có thể vui lòng giải thích chính xác điều gì đang xảy ra trên dòng này app.io = io;trong app.jshồ sơ không
Aryak Sengupta

3
Nó chỉ đơn giản là một vấn đề của việc đưa biến io vào đối tượng ứng dụng. Nó cũng có thể là: app.io = socket_io ();
Gabriel Hautclocq

7
"... và thậm chí cung cấp nó cho các tuyến đường của bạn nếu bạn muốn." Được rồi, nhưng làm thế nào? Sẽ thật tuyệt nếu bạn có thể đưa ra một ví dụ về cách làm điều đó.
Fearguy

2
Không phải là xấu khi gắn một thuộc tính tùy chỉnh vào appđối tượng? Tốt hơn sử dụng các biểu tượng hoặc app.set().
Alexander Gonchiy

3
Tại sao app.io = iokhi bạn có thể sử dụng module.exports = { app, io }thay vì
Manan Mehta

56

Một cách tiếp cận khác nhau một chút để bắt đầu socket.io, nó nhóm tất cả các mã liên quan vào một nơi:

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

Bằng cách này, tất cả socket.iomã liên quan trong một mô-đun và chức năng từ nó, tôi có thể gọi từ bất kỳ đâu trong ứng dụng.


4
Câu trả lời này xứng đáng nhận được nhiều phiếu bầu hơn! Rất đơn giản và sạch sẽ, nó giữ các tuyến socket bên ngoài www , app.js và bên ngoài index.js (vâng, bên ngoài index.js ), tệp này chỉ nên chứa các tuyến Express HTTP.
adelriosantiago

1
Tuyệt vời, rất sạch sẽ
Sanket

3
Có ai có thể cập nhật cái này cho socket.io 2.0 không? Nó không làm việc cho tôi. io.attach (server) và io.listen (server) đều ném "không thể đọc thuộc tính X của undefined".
tsujp

1
Ngoài ra, nói chuyện với @tsujp của tôi cũng hoạt động như vậy. Bạn phải nhấn đúng url và thêm ứng dụng khách socket.io và bạn sẽ thấy nó hoạt động
Tamb

Tôi gặp sự cố tương tự như @tsujp, tôi đang sử dụng socket.io 2.3.0 và tôi đang gặp sự cốio.attach is not a function
raquelhortab

43

Hóa ra đó thực sự là một số vấn đề cơ bản về sintax .... Tôi nhận được những dòng này từ hướng dẫn trò chuyện socket.io này ...

trên ./bin/www, ngay sau var server = app.listen(.....)

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

vì vậy bây giờ tôi tạo tệp ../sockets/base.js và đặt bạn nhỏ này vào bên trong nó:

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

Vâng! Bây giờ nó hoạt động ... Vì vậy, tôi đoán tôi thực sự không có tùy chọn nào khác ngoài việc khởi động socket.io bên trong / bin / www, bởi vì đó là nơi máy chủ http của tôi được khởi động. Mục tiêu là bây giờ tôi có thể xây dựng chức năng socket trong (các) tệp khác, giữ mọi thứ theo mô-đun, bằng cáchrequire('fileHere')(io);

<3


1
Vấn đề là, bạn không thể làm một cái gì đó giống nhưio.on('connection', function(socket) { res.render('connection.jade') });
Gofilord

3
@Gofilord đó là vì nó đánh bại toàn bộ mục đích của các ổ cắm ... những gì bạn cần là định tuyến thường xuyên bao gồm cả kết xuất. Sockets chỉ ở đây để gửi tin nhắn giữa máy khách và máy chủ mà không có yêu cầu http. có thể đọc bài viết này enterprisewebbook.com/ch8_websockets.html
Unispaw

19

"Expressjs" cũ, mọi thứ đang diễn ra trong tệp "app.js". Vì vậy, liên kết socket.io với máy chủ cũng xảy ra trong tệp đó. (BTW, người ta vẫn có thể làm theo cách cũ và loại bỏ bin / www)

Bây giờ với expressjs mới, nó cần phải xảy ra trong tệp "bin / www".

May mắn thay, javascript / Requijs đã giúp dễ dàng chuyển các đối tượng xung quanh. Như Gabriel Hautclocq đã chỉ ra, socket.io vẫn được "nhập" trong "app.js" và nó được gắn vào đối tượng "app" thông qua một thuộc tính

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

Socket.io được tạo hoạt động bằng cách gắn vào nó máy chủ trong "bin / www"

app.io.attach(server); 

vì đối tượng "app" đã được chuyển vào "bin / www" trước đó

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

Nó thực sự đơn giản như

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

Nhưng làm theo cách "khó" đảm bảo rằng app.io bây giờ giữ đối tượng socke.io.

Bây giờ nếu bạn cần đối tượng socket.io này cũng trong "route / index.js" chẳng hạn, chỉ cần sử dụng nguyên tắc tương tự để truyền đối tượng đó xung quanh.

Đầu tiên trong "app.js", làm

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

Sau đó, trong "route / index.js"

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

    var router = express.Router();



    return router;
 }

Vì vậy, "io" được đưa vào "index.js".


9

Cập nhật phản hồi của Gabriel Hautclocq :

Trong tệp www, mã sẽ xuất hiện như sau do các bản cập nhật với Socket.io. Đính kèm bây giờ là Nghe.

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

Ngoài ra, để kết nối đó hoạt động cũng yêu cầu triển khai API phía máy khách. Đây không phải là Express cụ thể nhưng nếu không có nó, cuộc gọi kết nối sẽ không hoạt động. API được bao gồm trong

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

Bao gồm tệp này trên giao diện người dùng và kiểm tra những điều sau:

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

7

Sau khi đọc qua tất cả các nhận xét, tôi đã nghĩ ra cách sử dụng Socket.io Server Version: 1.5.0

Các vấn đề mà tôi gặp phải:

  1. var sockIO = demand ('socket.io') phải là var sockIO = demand ('socket.io') () . (Tín dụng cho: Zhe Hu )

  2. sockIO.attach phải là sockIO. lắng nghe (Tín dụng cho: rickrizzo )

Các bước

  1. Cài đặt Socket.io bằng lệnh sau:

    npm install --save socket.io
  2. Thêm phần sau vào app.js :

    var sockIO = require('socket.io')();
    app.sockIO = sockIO;
  3. Trong bin / www , sau var server = http.createServer (app) , hãy thêm thông tin sau:

    var sockIO = app.sockIO;
    sockIO.listen(server);
  4. Để kiểm tra chức năng, trong app.js , bạn có thể thêm dòng:

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

5

Hướng dẫn cho người mới bắt đầu từ Cedric Pabst
đây là những kiến ​​thức cơ bản ngắn tạo thành liên kết cho trò chuyện ứng dụng:

sử dụng express-create và công cụ ejs có thể sử dụng được trong mọi định tuyến tiêu chuẩn tệp .ejs trong express-create

chỉnh sửa tệp bin \ www và thêm app.io.attach này (máy chủ); như thế này

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

chỉnh sửa trong 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;

chỉnh sửa trong 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>

Chúc vui vẻ :) và cảm ơn rất nhiều đến Cedric Pabst


2

Một số câu trả lời trước đó không hoạt động và những câu trả lời khác quá phức tạp. Hãy thử giải pháp sau để thay thế ...

Cài đặt mô-đun nút socket.io phía máy chủ và phía máy khách:

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

Phía máy chủ

Thêm mã sau đây để bin / www sau khi định nghĩa máy chủ, 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' });
});

Phía khách hàng

Nếu sử dụng webpack, hãy thêm mã sau vào webpack của bạn tệp 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)
});

Làm xong. Truy cập trang web của bạn và kiểm tra bảng điều khiển dành cho nhà phát triển js của trình duyệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.