Any success with Sinatra working together with EventMachine WebSockets?
Did not try it, but should not be too hard:
require 'em-websocket'
require 'sinatra/base'
require 'thin'
EM.run do
class App < Sinatra::Base
# Sinatra code here
end
EM::WebSocket.start(:host => '0.0.0.0', :port => 3001) do
# Websocket code here
end
# You could also use Rainbows! instead of Thin.
# Any EM based Rack handler should do.
Thin::Server.start App, '0.0.0.0', 3000
end
Also, Cramp has a websocket implementation that works directly with Thin/Rainbows! you might be able to extract, so you won't even need to run the server on another port.
Accessing an EventMachine channel from a Sinatra route
In case others don't know what we're talking about in the comments, here's an example of using a class instance variable in the way I suggested. This runs, but I don't know if it does what's expected:
require 'em-websocket'
require 'sinatra'
require 'haml'
module Example
def self.em_channel
@em_channel ||= EM::Channel.new
end
EventMachine.run do
class App < Sinatra::Base
configure do
enable :inline_templates
end
get '/' do
haml :index
end
get '/test' do
Example.em_channel.push "Test request hit endpoint"
status 200
end
end
EventMachine::WebSocket.start :host => '0.0.0.0', :port => 8080 do |socket|
socket.onopen do
sid = Example.em_channel.subscribe { |msg| socket.send msg }
Example.em_channel.push "Subscriber ID #{sid} connected!"
socket.onmessage do |msg|
Example.em_channel.push "Subscriber <#{sid}> sent message: #{msg}"
end
socket.onclose do
Example.em_channel.unsubscribe(sid)
end
end
end
App.run!
end
end
__END__
@@ layout
%html
= yield
@@ index
%div.title Hello world.
Use eventmachine with sinatra, why it will always quit?
Just run your Sinatra app under thin
server and it will be fired with Eventmachine
padrino && websockets
Maybe you need to install daemons:
Edit your Gemfile:
# Adding this
gem 'daemons'
Install missing gems:
$ bundle install
EventMachine WebSockets - Subscribe ws to EM channels vs Keeping sockets in collection
The EventMachine::Channel class is simply an abstraction that handles the iteration of a subscribers array. If you look at the Ruby source code for EventMachine::Channel#push, you see it is similar to what you propose:
def push(*items)
items = items.dup
EM.schedule { @subs.values.each { |s| items.each { |i| s.call i } } }
end
In fact, if you don't need to duplicate your items array, it is actually slower than manually iterating the list. However, I doubt that the performance impact is significant. EventMachine::Channel is simply an abstraction that makes managing lists of clients easier.
EventMachine Web-socket Client TLS Connections
It turns out that currently EventMachine::WebSocketClient
does NOT support wss://
connections. The server does, but that is a separate project.
I ended up using faye-websocket-ruby which does support wss://
There are examples in the README.md on how to use.
Related Topics
How to Download via Http Only Piece of Big File with Ruby
Activerecord::Adapternotspecified Database Configuration Does Not Specify Adapter
How to Check a Word Is Already All Uppercase
Ruby: Accessing Rake Task from a Gem Without Rails
Always Getting 401 Unauthorized with New Install of Rails + Devise
Tell Ruby Program to Wait Some Amount of Time
How to Invoke an Instance Method on a Ruby Module Without Including It
Rvm Is Not a Function, Selecting Rubies with 'Rvm Use ...' Will Not Work
How to Know What Is Not Thread-Safe in Ruby
Where to Define Custom Error Types in Ruby And/Or Rails
Heroku and Rails: Gem Load Error with Postgres, However It Is Specified in Gemfile
Why Does Ruby /[[:Punct:]]/ Miss Some Punctuation Characters
Why Isn't 'Method=' Treated the Same as Any Other Method
Call Controller from Rake Task
Base64 Photo and Paperclip -Rails
Is There Goto Statement in Ruby