diff --git a/lib/mail_catcher/web/application.rb b/lib/mail_catcher/web/application.rb index 3a2246ff..a8338421 100644 --- a/lib/mail_catcher/web/application.rb +++ b/lib/mail_catcher/web/application.rb @@ -4,14 +4,31 @@ require "net/http" require "uri" +require "faye/websocket" require "sinatra" -require "skinny" require "mail_catcher/bus" require "mail_catcher/mail" +Faye::WebSocket.load_adapter("thin") + +# Faye's adapter isn't smart enough to close websockets when thin is stopped, +# so we teach it to do so. +class Thin::Backends::Base + alias :thin_stop :stop + + def stop + thin_stop + @connections.each_value do |connection| + if connection.socket_stream + connection.socket_stream.close_connection_after_writing + end + end + end +end + class Sinatra::Request - include Skinny::Helpers + include Faye::WebSocket::Adapter end module MailCatcher @@ -62,20 +79,24 @@ def asset_path(filename) get "/messages" do if request.websocket? - request.websocket!( - :on_start => proc do |websocket| - bus_subscription = MailCatcher::Bus.subscribe do |message| - begin - websocket.send_message(JSON.generate(message)) - rescue => exception - MailCatcher.log_exception("Error sending message through websocket", message, exception) - end + bus_subscription = nil + + ws = Faye::WebSocket.new(request.env) + ws.on(:open) do |_| + bus_subscription = MailCatcher::Bus.subscribe do |message| + begin + ws.send(JSON.generate(message)) + rescue => exception + MailCatcher.log_exception("Error sending message through websocket", message, exception) end + end + end - websocket.on_close do |*| - MailCatcher::Bus.unsubscribe bus_subscription - end - end) + ws.on(:close) do |_| + MailCatcher::Bus.unsubscribe(bus_subscription) if bus_subscription + end + + ws.rack_response else content_type :json JSON.generate(Mail.messages) diff --git a/mailcatcher.gemspec b/mailcatcher.gemspec index 642f52ed..88c38c1e 100644 --- a/mailcatcher.gemspec +++ b/mailcatcher.gemspec @@ -33,13 +33,13 @@ Gem::Specification.new do |s| s.required_ruby_version = ">= 2.6.0" s.add_dependency "eventmachine", "1.0.9.1" + s.add_dependency "faye-websocket", "~> 0.11.1" s.add_dependency "mail", "~> 2.3" s.add_dependency "net-smtp" s.add_dependency "rack", "~> 1.5" s.add_dependency "sinatra", "~> 1.2" s.add_dependency "sqlite3", "~> 1.3" s.add_dependency "thin", "~> 1.5.0" - s.add_dependency "skinny", "~> 0.2.3" s.add_development_dependency "capybara" s.add_development_dependency "capybara-screenshot"