Module: DangoFrameworkModule

Includes:
DangoLoggerModule, ErrorMessage
Included in:
DangoClientFramework, DangoServerFramework
Defined in:
lib/dango/framework_base.rb,
lib/dango/shared/memory_store.rb

Overview

クライアントとサーバーで共有するモジュール

Defined Under Namespace

Classes: SharedMemoryStore

Constant Summary collapse

CommMaxDigit =

通信の最大桁数

5
MaxLenRecv =

通信の一度の送信バイト数

1024
MaxLenSend =

通信の一度の送信バイト数

1024 * 1024
EncodeTypeJSON =

4294967296 # 本当はuint最大値なんだけれど、policyファイルの都合で変えてある

1886350440 
1886350441
0
EncodeTypeYAML =

エンコードのタイプのJSON

1
EncodeTypeMarshal =

エンコードのタイプのYAML

2
DefaultEncodeType =

エンコードのタイプのMarshal

EncodeTypeJSON
ReadTimeoutSec =

デフォルトのエンコードのタイプ

10.0

Instance Method Summary collapse

Methods included from DangoLoggerModule

#logger

Methods included from ErrorMessage

#error_message

Instance Method Details

#dango_receive_data(sock) ⇒ Object

データ受信処理



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/dango/framework_base.rb', line 184

def dango_receive_data(sock)
  ret_data = ""
  
  begin
    size_str = sock.recv(CommMaxDigit + 1)
    logger.debug "dango_receive_data:read header:sock=#{sock}"
    
  rescue EOFError, IOError, Errno::ECONNRESET, Errno::ETIMEDOUT, Errno::ECONNABORTED
    # 接続終了時の切断と思われるものはDangoFrameworkConnectionExceptionにしない
    raise(DangoFrameworkDisconnectException, "failed to read sock for EOF reached (and so on). " + 
                                             "sock=#{sock.inspect} #{$!.class} toid=#{Thread.current.object_id}")
  rescue
    raise(DangoFrameworkConnectionException, "failed to read sock. sock=#{sock.inspect} " + 
                                             "toid=#{Thread.current.object_id}\n#{error_message($!, 'u')}")
  end
  
  if size_str == ""
    raise(DangoFrameworkReadNoDataException, "toid=#{Thread.current.object_id}:size_str=#{size_str.inspect}") 
  end
  
  ## Flash のpolicyファイルだった場合(特殊)
  if size_str == "<polic"
    logger.debug "size_str=#{size_str.inspect}"
    receive_data = sock.recv(18)
    logger.info "flash policy file: dango_receive_data:receive_data=#{receive_data}"
    raise(DangoFrameworkFlashPolicyException) 
  end
  
  ## サイズとデータタイプを取得
  encode_type, size = size_str[0, 5].unpack("cN")
  
  ## データがない場合
  if size == nil || size == 0
    raise(DangoFrameworkConnectionException, "toid=#{Thread.current.object_id}" + 
                                             ":size=#{size}:size_str=#{size_str.inspect}") 
  end
  
  ## データが大きすぎる場合
  if size >= MaxLenSend
    raise(DangoFrameworkConnectionException, "too big... size=#{size}:size_str=#{size_str.inspect}")
  end
  
  logger.warn "warn size is too big ? size=#{size}:size_str=#{size_str.inspect}" if size > 10000
  
  
  recv_data_orig = ""
  
  # 10秒でタイムアウトを起こす
  timeout(ReadTimeoutSec, DangoFrameworkReadTimeoutException) do 
    
    # サイズが0になるまで受信し続ける
    while size > 0
      read_len = MaxLenRecv > size ? size : MaxLenRecv
      begin
        this_recv_data_orig = sock.recv(read_len)
      rescue
        raise(DangoFrameworkConnectionException, "failed to read sock(data).\n#{error_message($!, 'u')}")
      end
      
      recv_data_orig += this_recv_data_orig
      
      size -= this_recv_data_orig.size
    end
  end
  
  recv_data = receive_decrypt(recv_data_orig[0..-2])
  
  @recv_count += 1 if @recv_count # 受信回数カウント
  
  begin
    if recv_data == "" || recv_data == "{}" # データが空ならparseしない
      ret_data = []
    elsif encode_type == EncodeTypeJSON
      ret_data = JSON.parse(recv_data)
    elsif encode_type == EncodeTypeYAML
      ret_data = YAML::load(recv_data)
    elsif encode_type == EncodeTypeMarshal
      ret_data = Marshal.load(recv_data)
    end
    
    if ret_data.class != Array
      raise(DangoFrameworkConnectionException, "data is not array.#{$!.class}\nret_data=#{ret_data}") 
    end
    
  rescue
    raise(DangoFrameworkConnectionException, "data parse error.#{$!.class}\nret_data=#{ret_data}")
  end
  
  ret_data
end

#dango_send_data(sock, send_objs, options = {}) ⇒ Object

データ送信処理



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/dango/framework_base.rb', line 276

def dango_send_data(sock, send_objs, options = {})
  encode_type = options[:encode_type] || DefaultEncodeType
  
  if send_objs == []
    send_data_orig = ""
  elsif encode_type == EncodeTypeJSON
    begin
      send_data_orig = JSON.generate(send_objs)
    rescue
      pp send_objs
      raise
    end
  elsif encode_type == EncodeTypeYAML
    send_data_orig = send_objs.to_yaml
  elsif encode_type == EncodeTypeMarshal
    send_data_orig = Marshal.dump(send_objs)
  else
    send_data_orig = JSON.generate(send_objs)
  end
  
  send_data = send_encrypt(send_data_orig) + "\n"
  
  size = send_data.size
  
  if size >= MaxLenSend
    raise(DangoFrameworkException, "max size over. size:#{size} >= #{MaxLenSend}") 
  end
  
  size_str = [encode_type, size].pack("cN")
  send_buf = size_str + "\n" + send_data
  begin
    sock.write send_buf
    sock.flush
  rescue
    raise(DangoFrameworkConnectionException, "sock write failed.\n#{error_message($!, 'u')}")
  end
  
  @send_count += 1 if @send_count # 受信回数カウント
  
  sock
end

#debug_print(str) ⇒ Object

デバッグ出力用のメソッド



172
173
174
175
# File 'lib/dango/framework_base.rb', line 172

def debug_print(str)
  logger.debug str
  puts str if $VERBOSE
end

#error_print(str) ⇒ Object

エラー出力用のメソッド



178
179
180
181
# File 'lib/dango/framework_base.rb', line 178

def error_print(str)
  logger.error str
  puts str
end