class Wunderbar::Channel

Attributes

complete[R]
connected[R]
port[R]

Public Class Methods

new(port, limit, locals=nil) click to toggle source
Calls superclass method
# File lib/wunderbar/websocket.rb, line 12
def initialize(port, limit, locals=nil)
  # verify that the port is available
  TCPServer.new('0.0.0.0', port).close 

  super()
  @port = port
  @connected = @complete = false
  @onopen = @onmessage = @onerror = @onclose = Proc.new {}
  @_scope = Struct.new(:params).new({})
  @channel1 = EM::Channel.new
  @channel2 = EM::Channel.new
  @memory = []
  @memory_channel = @channel1.subscribe do |msg| 
    @memory << msg.chomp unless Symbol === msg
    @memory.shift while @connected and limit and @memory.length > limit
  end

  if locals
    @_scope = locals['_scope'] || @_scope
    set_variables_from_params(locals)
    _ :type => 'stdout', :line => locals['_scope'].methods.inspect
  end

  websocket.run
end

Public Instance Methods

<<(value) click to toggle source
# File lib/wunderbar/websocket.rb, line 138
def <<(value)
  @channel1.push(value.to_json)
end
_(*args, &block) click to toggle source
# File lib/wunderbar/websocket.rb, line 122
def _(*args, &block)
  if block or args.length > 1 
    begin
      builder = Wunderbar::JsonBuilder.new(Struct.new(:params).new({}))
      builder._! self
      builder._(*args, &block)
    rescue Exception => e
      self << {:type=>'stderr', :line=>e.inspect}
    end
  elsif args.length == 1
    @channel1.push(args.first.to_json)
  else
    self
  end
end
close() click to toggle source
# File lib/wunderbar/websocket.rb, line 164
def close
  @channel1.unsubscribe @memory_channel if @memory_channel
  EM::WebSocket.stop
  websocket.join    
end
complete=(value) click to toggle source
# File lib/wunderbar/websocket.rb, line 159
def complete=(value)
  @channel1.push :shutdown if value
  @complete = value
end
method_missing(method, *args, &block) click to toggle source
Calls superclass method
# File lib/wunderbar/websocket.rb, line 114
def method_missing(method, *args, &block)
  if @_scope and @_scope.respond_to? :method
    @_scope.__send__ method, *args, &block
  else
    super
  end
end
onclose(&block) click to toggle source
# File lib/wunderbar/websocket.rb, line 110
def onclose(&block)
  @onclose = block
end
onerror(&block) click to toggle source
# File lib/wunderbar/websocket.rb, line 106
def onerror(&block)
  @onerror = block
end
onmessage(&block) click to toggle source
# File lib/wunderbar/websocket.rb, line 102
def onmessage(&block)
  @onmessage = block
end
onopen(&block) click to toggle source
# File lib/wunderbar/websocket.rb, line 98
def onopen(&block)
  @onopen = block
end
pop(*args) click to toggle source
# File lib/wunderbar/websocket.rb, line 90
def pop(*args)
  @channel2.pop(*args)
end
push(*args) click to toggle source
# File lib/wunderbar/websocket.rb, line 82
def push(*args)
  @channel1.push(*args)
end
recv(*args) click to toggle source
# File lib/wunderbar/websocket.rb, line 94
def recv(*args)
  @channel2.pop(*args)
end
send(*args) click to toggle source
# File lib/wunderbar/websocket.rb, line 86
def send(*args)
  @channel1.push(*args)
end
subscribe(*args, &block) click to toggle source
# File lib/wunderbar/websocket.rb, line 74
def subscribe(*args, &block)
  @channel2.subscribe(*args, &block)
end
system(command) click to toggle source
# File lib/wunderbar/websocket.rb, line 142
def system(command)
  Open3.popen3(command) do |pin, pout, perr|
    _ :type=>:stdin, :line=>command
    [
      Thread.new do
        pout.sync=true
        _ :type=>:stdout, :line=>pout.readline.chomp until pout.eof?
      end,
      Thread.new do
        perr.sync=true
        _ :type=>:stderr, :line=>perr.readline.chomp until perr.eof?
      end,
      Thread.new { pin.close }
    ].each {|thread| thread.join}
  end
end
unsubscribe(*args, &block) click to toggle source
# File lib/wunderbar/websocket.rb, line 78
def unsubscribe(*args, &block)
  @channel2.unsubscribe(*args, &block)
end
websocket() click to toggle source
# File lib/wunderbar/websocket.rb, line 38
def websocket
  return @websocket if @websocket
  ready = false
  @websocket = Thread.new do
    EM.epoll
    EM.run do
      connection = EventMachine::WebSocket::Connection
      EM.start_server('0.0.0.0', @port, connection, {}) do |ws|
        ws.onopen do
          @onopen.call(ws)
          @memory.each {|msg| ws.send msg }
          @connected = true
          ws.close_websocket if complete
        end
    
        sid = @channel1.subscribe do |msg| 
          if msg == :shutdown
            ws.close_websocket
          else
            ws.send msg
          end
        end
    
        ws.onmessage {|msg| @onmessage.call(msg); @channel2.push msg}

        ws.onerror {|e| @onerror.call(e)}

        ws.onclose {@onclose.call(ws); @channel1.unsubscribe sid}
      end
      EM.add_timer(0.1) {ready = true}
    end
  end
  sleep 0.2 until ready
  @websocket
end