问题
I've got a working configuration of websocket-rack in a sinatra app that is intended for a physical installation with multiple screens. There is functionality working where messages are getting passed back and forth through the websockets just fine.
My problem is this: I have one page with a standard web form (i.e. not a websocket form), and my goal is to collect the params from that form, turn the params into a string variable, then send the contents of that variable (a string) to a different page/screen through a websocket. For the life of me, I can't figure out how to do what should be a relatively simple task, because from the main class in my app, I can't communicate with my Socket class, which from what i understand is basically a rack app.
I tried to resolve it by setting up resque as a middle-man, but quickly discovered that my problem hadn't changed. I can't figure out how to call a method and/or pass a variable to the Socket from another class so that it will push to the browser.
Basically, I have an app.rb that is like this:
module SomeThing
class App < Sinatra::Base
get '/' do
#show a form
end
post '/submit' do
#receive params
#save params
new_message = params.inspect
#dream up some way to pass new_message to websocket
end
post '/otherscreen' do
#have an open websocket to receive new_message
end
end
class Socket < Rack::WebSocket::Application
def on_open(env)
puts "Client connected"
send_data "Oh hai!"
end
def on_close(env)
puts "Client disconnected"
end
def on_message(env, msg)
puts "Received message from client: " + msg
end
def on_error(env, error)
puts "An error occured: " + error.message
end
def pass_message(env, new_message)
send_data new_message
end
end
end
Please let me know if you need more info to solve this. I'm happy to provide whatever is needed, just unsure what that might be right now.
Do you know how I can resolve this? It's killing me.
Thanks ahead of time!
回答1:
So, I wrote to the author of websocket-rack, Bernard Potocki, and he said this:
"What I usually do is save list of active connections to some kind of class variable. One of possible implementations might look like in this gist: https://gist.github.com/imanel/a00d6b65561ebba43b9a "
Contents of gist, in case it gets removed:
class Socket < Rack::WebSocket::Application
def self.connections
@connections ||= []
end
def self.send_to_all(message)
@connections.each {|connection| connection.send_data(message)
end
def on_open(env)
self.class.connections << self
end
def on_close(env)
self.class.connection.delete(self)
end
end
Ultimately, however, I did not test this solution as we were able to resolve this issue using Redis and Event Machine, so be aware that that is an option as well.
来源:https://stackoverflow.com/questions/14822726/how-can-i-pass-data-to-websocket-rack-from-a-class-in-my-sinatra-app