Class: Rakie::SimpleServer

Inherits:
Object
  • Object
show all
Defined in:
lib/rakie/simple_server.rb

Constant Summary collapse

PARSE_ERROR =
-1
PARSE_OK =
0
PARSE_PENDING =
1
PARSE_COMPLETE =
2
PARSE_TYPE =
0
PARSE_LEN =
1
PARSE_ENTITY =
2

Instance Method Summary collapse

Constructor Details

#initialize(delegate = nil) ⇒ SimpleServer

Returns a new instance of SimpleServer.



12
13
14
15
16
# File 'lib/rakie/simple_server.rb', line 12

def initialize(delegate=nil)
  @channel = TCPServerChannel.new('127.0.0.1', 10086, self)
  @clients = {}
  @delegate = delegate
end

Instance Method Details

#on_accept(channel) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rakie/simple_server.rb', line 18

def on_accept(channel)
  channel.delegate = self
  @clients[channel] = {
    :parse_status => PARSE_TYPE,
    :parse_offset => 0,
    :request => {
      :type => 0,
      :len => 0,
      :entity => ""
    },
    :response => {
      :type => 0,
      :len => 0,
      :entity => ""
    }
  }
  Log.debug("SimpleServer accept client: #{channel}")
end

#on_recv(channel, data) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rakie/simple_server.rb', line 119

def on_recv(channel, data)
  Log.debug("SimpleServer recv: #{data}")
  client = @clients[channel]
  client[:parse_offset] = 0
  result = self.parse_data(client, data)

  if result == PARSE_COMPLETE
    if @delegate != nil
      @delegate.handle(client[:request], client[:response])

    else
      client[:response] = client[:request]
    end
    
    channel.write(self.pack_data(client[:response])) # Response data

  elsif result == PARSE_ERROR
    channel.close
    @clients.delete(channel)
    Log.debug("SimpleServer: Illegal request")
    return client[:parse_offset]
  end

  return client[:parse_offset]
end

#pack_data(response) ⇒ Object



112
113
114
115
116
117
# File 'lib/rakie/simple_server.rb', line 112

def pack_data(response)
  data = ""
  data += [response[:type]].pack('c')
  data += [response[:len]].pack('l')
  data += response[:entity]
end

#parse_data(client, data) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rakie/simple_server.rb', line 89

def parse_data(client, data)
  result = PARSE_OK

  while result == PARSE_OK
    current_status = client[:parse_status]

    case current_status
    when PARSE_TYPE
      result = self.parse_data_type(client, data)

    when PARSE_LEN
      result = self.parse_data_len(client, data)

    when PARSE_ENTITY
      result = self.parse_data_entity(client, data)
    end
  end

  Log.debug("SimpleServer parse data result #{result}")

  return result
end

#parse_data_entity(client, data) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rakie/simple_server.rb', line 73

def parse_data_entity(client, data)
  len = client[:request][:len]
  offset = client[:parse_offset]

  if data.length >= len + offset
    client[:request][:entity] = data[offset .. (offset + len - 1)]
    client[:parse_status] = PARSE_TYPE
    client[:parse_offset] = offset + len

    Log.debug("SimpleServer parse data entity ok")
    return PARSE_COMPLETE
  end

  return PARSE_PENDING
end

#parse_data_len(client, data) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rakie/simple_server.rb', line 51

def parse_data_len(client, data)
  offset = client[:parse_offset]

  if data.length >= 4 + offset
    len = data[offset .. (4 + offset - 1)]
    len = len.unpack('l')[0]

    if len == nil
      return PARSE_ERROR
    end

    client[:request][:len] = len
    client[:parse_status] = PARSE_ENTITY
    client[:parse_offset] = offset + 4

    Log.debug("SimpleServer parse data len ok")
    return PARSE_OK
  end

  return PARSE_PENDING
end

#parse_data_type(client, data) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rakie/simple_server.rb', line 37

def parse_data_type(client, data)
  if data.length >= 1
    type = data[0].ord
    client[:request][:type] = type
    client[:parse_status] = PARSE_LEN
    client[:parse_offset] += 1

    Log.debug("SimpleServer parse data type ok")
    return PARSE_OK
  end

  return PARSE_PENDING
end