2013-06-04 40 views
7

Tôi cần thêm thời gian thực để ứng dụng của tôi (Ruby On Rails), vì vậy, tôi nghĩ rằng cách tốt hơn để làm điều đó là sử dụng Node.js + ổ cắm .io + redis.Node.js + socket.io + redis + ray - ứng dụng RealTime

Tôi có điều này application.js tập tin trong một backend (Node.js)

var app = require('http').createServer(); 
var io = require('socket.io'); 
var redis = require('redis').createClient(); 
var _ = require('underscore')._; 

io = io.listen(app); 
io.configure(function() { 
    io.set("transports", ["xhr-polling"]); 
    io.set("polling duration", 10); 
    io.set("close timeout", 10); 
    io.set("log level", 1); 
}) 

redis.subscribe('rt-change'); 

io.on('connection', function(socket) { 
    redis.on('message', function(channel, message) { 
     socket.emit('rt-change', message) 
    }); 
}); 

var port = process.env.PORT || 5001; 
app.listen(port); 

Và messages.js trong frontend

var socket = io.connect('http://localhost:5001/socket.io'); 
socket.on('rt-change', function (data) { 
    console.log(data); 
}); 

Tôi đang tung ra application.js với ứng dụng nút .js lệnh và nó hoạt động!

MacBook-Pro-Zhirayr: rt zhirayr $ node application.js thông tin - socket.io bắt đầu

Nhưng khi tôi đang cố gắng để gửi tin nhắn với redis ($ rt redis.publish' -Thay đổi', {hello: 'thế giới'}) từ ứng dụng Rails, trình duyệt của tôi không đăng bất cứ điều gì trong giao diện điều khiển. Tôi chắc chắn rằng kết nối từ trình duyệt thành lập, nguyên nhân khi tôi dừng nút, nó ném kết nối từ chối lỗi. Và tôi chắc chắn rằng kết nối giữa redis và nút thiết lập, nguyên nhân console.log (message) trong application.js bản ghi nó. Nhưng console.log trong trình duyệt không đăng bất cứ điều gì.

Mọi ý tưởng tại sao?

Cảm ơn.

UPD cho #Antoine

Added console.log trong application.js io.on ('kết nối', function (socket) { redis.on ('thông báo', function (kênh, message) { console.log ('tin nhắn mới từ redis'); socket.emit ('rt-thay đổi', tin nhắn); }); });

Khi r.publish 'rt-thay đổi', {: hello => 'thế giới'} trở thành thực hiện, các bản ghi nút này:

new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 
new message from redis 

Thật kỳ lạ, nút đăng nhập 11 lần cho 1 bài viết.

+0

Từ nơi nào bạn gửi tin nhắn này '$ redis.publish 'rt-thay đổi', {hello: 'thế giới' } '? – udidu

+0

Từ ứng dụng Rails. –

+1

Bạn có thể đăng nhập vào redis đăng ký gọi lại để đảm bảo rằng nó được kích hoạt? – Antoine

Trả lời

11
var socket = io.connect('http://localhost:5001/socket.io'); 
socket.on('rt-change', function (data) { 
    console.log(data); 
}); 

Phần này của mã dường như không đúng, theo doc trên http://socket.io, bạn nên làm một cái gì đó như:

<script src="http://localhost:5001/socket.io/socket.io.js"></script> 
<script> 
    var socket = io.connect('http://localhost:5001'); 
</script> 
+0

Giải quyết bởi bản thân mình 10 phút trước, sau đó tôi chuyển sang stackoverflow để đóng vé, và đây là bạn trả lời :) Cảm ơn anyway. –

5

Lý do tại sao bạn đang nhận được nhiều hành cho một đơn xuất bản là do xử lý sự kiện lồng nhau trong mã của bạn. Tôi sẽ cố gắng giải thích điều này đơn giản nhất có thể.

Khi bạn gọi

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

bạn nghe cho connection sự kiện và thêm chức năng đưa ra là xử lý sự kiện. Nó được thực hiện bất cứ khi nào một người dùng mới kết nối. Điều này tạo ra một phạm vi riêng biệt, để thực hiện xử lý mỗi lần.

Khi bạn gọi đây là

io.on('connection', function(socket) { 
    redis.on('message', function(channel, message) { 
     console.log('new message from redis'); 
     socket.emit('rt-change', message); 
    }); 
}); 

bạn thêm người nghe cho sự kiện redis thuê bao message cho mỗi người trong số những người sử dụng kết nối riêng biệt. Đây là lý do tại sao bạn nhận được nhiều nhật ký và người dùng được kết nối nhận được nhiều bản sao của cùng một thư. Bạn nhận được 11 tin nhắn có nghĩa là đã có 11 người dùng khác nhau được kết nối tại thời điểm đó.

Để giải quyết vấn đề này, bạn có thể gọi once thay vì on cho các sự kiện nghe. Như thế này

io.once('connection', function(socket) { 
    redis.on('message', function(channel, message) { 
     console.log('new message from redis'); 
     socket.emit('rt-change', message); 
    }); 
}); 

Điều này cũng áp dụng cho khách hàng socket.io. Xem câu trả lời trước của tôi để có được sự rõ ràng về vấn đề này:

  1. socket.io code structure: where to place methods?
  2. socket.io creates one more connection after reconnecting
Các vấn đề liên quan