Class: Protoplasm::EMServer

Inherits:
EventMachine::Connection
  • Object
show all
Defined in:
lib/protoplasm/server/em_server.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.for_types(types) ⇒ Object



5
6
7
8
9
10
11
# File 'lib/protoplasm/server/em_server.rb', line 5

def self.for_types(types)
  cls = Class.new(self)
  cls.class_eval do
    (class << self; self; end).send(:define_method, :_types) { types }
  end
  cls
end

.start(port) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/protoplasm/server/em_server.rb', line 14

def self.start(port)
  if EM.reactor_running?
    EM::start_server("0.0.0.0", port, self) do |srv|
      yield srv if block_given?
    end
  else
    begin
      EM.run do
        start(port)
      end
    rescue Interrupt
    end
  end
end

Instance Method Details

#data_readyObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/protoplasm/server/em_server.rb', line 49

def data_ready
  @control = @data.slice!(0, 1).unpack("C").first unless @control
  case @control
  when Types::Request::NORMAL
    @size = @data.slice!(0, 8).unpack("Q").first unless @size
    if @data.size >= @size
      buf = @data.slice!(0, @size)
      @size, @control = nil, nil
      obj = self.class._types.request_class.decode(buf)
      type = self.class._types.request_type_for_request(obj)
      @_response_types << type
      EM.next_tick do
        send(:"process_#{type.field}", obj.send(type.field))
      end
      data_ready unless @data.empty?
    end
  else
    # illegal char
    close_connection
  end
end

#finish_streamingObject



39
40
41
42
# File 'lib/protoplasm/server/em_server.rb', line 39

def finish_streaming
  @_response_types.shift
  send_data [Types::Response::STOP_STREAMING].pack("C")
end

#post_initObject



29
30
31
32
# File 'lib/protoplasm/server/em_server.rb', line 29

def post_init
  @_response_types = []
  @data = ''
end

#receive_data(data) ⇒ Object



34
35
36
37
# File 'lib/protoplasm/server/em_server.rb', line 34

def receive_data(data)
  @data << data
  data_ready
end

#send_response(*args) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
# File 'lib/protoplasm/server/em_server.rb', line 71

def send_response(*args)
  type = @_response_types.first
  @_response_types.shift unless type.streaming?
  obj = type.response_class.new(*args)
  s = ''
  obj.encode(s)
  s = s.force_encoding('BINARY')
  send_data [Types::Response::NORMAL].pack("C")
  send_data [s.size].pack("Q")
  send_data s
end

#send_voidObject



44
45
46
47
# File 'lib/protoplasm/server/em_server.rb', line 44

def send_void
  @_response_types.shift
  send_data [Types::Response::NORMAL].pack("C")
end