mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-09 15:08:04 -05:00
More efficient message passing in both directions
- Server batches up all output changes and sends them at the end - Client only sends input update messages if the value actually changed
This commit is contained in:
49
shiny.rb
49
shiny.rb
@@ -85,23 +85,30 @@ def run_shiny_app(shinyapp)
|
||||
shinyapp.websocket = ws
|
||||
ws.onclose { exit(0) }
|
||||
ws.onmessage do |msg|
|
||||
puts "RECV: #{msg}"
|
||||
begin
|
||||
puts "RECV: #{msg}"
|
||||
|
||||
msg_obj = JSON.parse(msg)
|
||||
case msg_obj['method']
|
||||
when 'init'
|
||||
msg_obj['data'].each do |k, v|
|
||||
shinyapp.session.set(k, v)
|
||||
msg_obj = JSON.parse(msg)
|
||||
case msg_obj['method']
|
||||
when 'init'
|
||||
msg_obj['data'].each do |k, v|
|
||||
shinyapp.session.set(k, v)
|
||||
end
|
||||
React::Context.flush
|
||||
shinyapp.instantiate_outputs
|
||||
when 'update'
|
||||
msg_obj['data'].each do |k, v|
|
||||
shinyapp.session.set(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
React::Context.flush
|
||||
shinyapp.instantiate_outputs
|
||||
when 'update'
|
||||
msg_obj['data'].each do |k, v|
|
||||
shinyapp.session.set(k, v)
|
||||
end
|
||||
shinyapp.flush_output
|
||||
rescue Exception => e
|
||||
puts "ERROR: #{e}"
|
||||
puts e.backtrace.collect {|x| "\t#{x}"}
|
||||
raise
|
||||
end
|
||||
|
||||
React::Context.flush
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -113,6 +120,7 @@ class ShinyApp
|
||||
def initialize
|
||||
@session = React::Session.new
|
||||
@outputs = {}
|
||||
@invalidated_output_values = Hash.new
|
||||
end
|
||||
|
||||
def websocket=(value)
|
||||
@@ -128,16 +136,21 @@ class ShinyApp
|
||||
proc = @outputs.delete(name)
|
||||
React::Observer.new do
|
||||
value = proc.call
|
||||
msg = {}
|
||||
msg[name] = value
|
||||
puts "SEND: #{JSON.generate(msg)}"
|
||||
@websocket.send(JSON.generate(msg))
|
||||
@invalidated_output_values[name] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def flush_output
|
||||
return if @invalidated_output_values.empty?
|
||||
|
||||
data = @invalidated_output_values
|
||||
@invalidated_output_values = Hash.new
|
||||
puts "SEND: #{JSON.generate(data)}"
|
||||
@websocket.send(JSON.generate(data))
|
||||
end
|
||||
|
||||
def run
|
||||
run_shiny_app self
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
16
www/shiny.js
16
www/shiny.js
@@ -124,13 +124,15 @@
|
||||
// TODO: If submit button is present, don't send anything
|
||||
// until submit button is pressed
|
||||
initialValues[name] = value;
|
||||
var onChange = function() {
|
||||
var data = {};
|
||||
data[name] = elementToValue(input);
|
||||
shinyapp.sendInput(data);
|
||||
};
|
||||
$(input).keyup(onChange);
|
||||
$(input).change(onChange);
|
||||
$(input).bind('change keyup input', function() {
|
||||
var newValue = elementToValue(input);
|
||||
if (value !== newValue) {
|
||||
value = newValue;
|
||||
var data = {};
|
||||
data[name] = value;
|
||||
shinyapp.sendInput(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
shinyapp.connect(initialValues);
|
||||
|
||||
Reference in New Issue
Block a user