2013-01-10 26 views
17

Tôi đang cố gắng triển khai luồng văn bản/sự kiện bằng phát trực tuyến của Rails 4. Nó hoạt động tuyệt vời và rắc rối duy nhất tôi gặp là tôi không thể kiểm tra xem kết nối có còn sống mà không gửi bất kỳ tin nhắn nào không.ActionController :: LIve Có thể kiểm tra xem kết nối vẫn còn sống không?

Giải pháp duy nhất tôi đã tìm ra là tạo kênh hỗ trợ bằng trình tạo dấu cyclic, để một số tác vụ nền sẽ gửi tin nhắn định kỳ. Nhưng nó có vẻ lộn xộn và không đáng tin cậy. Bất kỳ giải pháp tốt hơn?

Đây là bộ điều khiển của tôi:

require 'persistency/sse' 
require 'persistency/track' 

class PersistencyController < ApplicationController 
    include ActionController::Live 

    def stream 
    response.headers['Content-Type'] = 'text/event-stream' 

    sse = Persistency::SSE.new(response.stream) 
    track = Persistency::Track.new(current_user) 
    redis = Redis.new 

    begin 
     redis.subscribe(:info, :chat) do |on| 
     on.message do |channel, message| 
      sse.write({ :message => message }, :event => channel) 
     end 
     end 
    rescue IOError 
    ensure 
     track.close 
     sse.close 
    end 
    end 
end 
+0

Tùy chọn khác được nêu chi tiết tại đây: http://stackoverflow.com/a/19485363/928963 –

+0

Trông giống y như hình bên dưới, ngoại trừ việc sử dụng redis để phát tín hiệu đồng hồ phức tạp hơn. Và sau khi tất cả làm thế nào nó sẽ làm việc theo tải? Không phải bộ khởi tạo kích hoạt trên mọi yêu cầu? Điều này có thể quá tải pub/kênh phụ và mỗi khách hàng sẽ nhận được tin nhắn từ tất cả các khách hàng. –

+0

Giải pháp bạn có bên dưới là kích hoạt một chuỗi bổ sung cho mỗi kết nối khách hàng. Các giải pháp tôi đề xuất trong câu trả lời của tôi tôi tham chiếu có một thread duy nhất để đẩy các mã này ra, mà quy mô tốt hơn một chút. (Và, đặt nó trong initializer tạo ra một thread cho mỗi quá trình rails, không phải cho mỗi kết nối khách hàng) –

Trả lời

10

Ok, tôi thấy hai lựa chọn:

1) Hài hước nhưng không tốt (như tôi đã không nhận được những gì sever tôi nên sử dụng để xử lý 1000 của song song kết nối):

begin 
    ticker = Thread.new { loop { sse.write 0; sleep 5 } } 
    sender = Thread.new do 
    redis.subscribe(:info, :chat) do |on| 
     on.message do |event, message| 
     sse.write(message, :event => event.to_s) 
     end 
    end 
    end 
    ticker.join 
    sender.join 
rescue IOError 
ensure 
    Thread.kill(ticker) if ticker 
    Thread.kill(sender) if sender 
    track.close 
    sse.close 
end 

2) Tuyệt vời. Để sử dụng máy chủ Goliath. Nó bật ra rằng nó có thể kiểm tra xem kết nối bị mất mà không có bất kỳ ticker. Trên đường đến Goliath tìm thấy Cramp. Nó nhẹ và hy vọng nhanh, nhưng dường như bị bỏ rơi.

Các vấn đề liên quan