2017-07-28 3 views
0

Ich habe einen Controller, der mit bis zu 100MB an Daten antworten muss, die von einer anderen Quelle im Netzwerk kommen (also zB ein HTTP-, FTP- oder benutzerdefinierter Protokoll-Socket), und ich versuche herauszufinden, wie ich diese Antwort ohne die beträchtliche Latenz des Schreibens einer temporären Datei und dann das Rendern/Senden dieser Antwort wiedergeben sollte.Rails render/stream IO-ähnliches Objekt ohne Pufferung

Es ist auch wichtig, dass ich den Strom "schließen" kann, wenn Schienen durchgeführt wird, so kann ich die Anzahl der aktiven Verbindungen begrenzen oder Pools verwenden (z. B. weil einige Protokolle eine langsame "Verbindung" haben).

Eine IO übergeben direkt zum Rendern funktioniert nicht. render sock

'#<TCPSocket:fd 20>' is not an ActiveModel-compatible object 

Für Vorlagen sah ich die Dokumentation nur render stream: true Pufferung zu deaktivieren verwenden sagen, aber für diese Id müssen noch akzeptieren Rails (und Puffer vielleicht) mein Objekt sowieso.

Antwort

0

Eine mögliche Lösung wäre die Verwendung der eingebauten in live streaming support in Rails mit dem ActionController::Live Modul zu machen:

Rails ermöglicht es Ihnen, mehr zu streamen als nur Dateien. Tatsächlich können Sie alles, was Sie möchten, in ein Antwortobjekt streamen. Mit dem Modul ActionController::Live können Sie eine permanente Verbindung mit einem Browser erstellen. Mit diesem Modul können Sie zu bestimmten Zeitpunkten beliebige Daten an den Browser senden.

class MyController < ActionController::Base 
    include ActionController::Live 

    def my_action 
    response.headers["Content-Type"] = "your/content-type" 

    TCPSocket.open("server", 1234) do |socket| 
     # for each chunk of data you read: 
     response.stream.write data 
    end 
    ensure 
    response.stream.close 
    end 
end 
+0

Ah, das gut aussieht. Das muss ich irgendwo vergessen haben, da "ActionController :: Live" nie beim Suchen und Überprüfen von Referenzen auftauchte :) –