dango 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,66 @@
1
+ #!ruby -Ku
2
+
3
+ =begin
4
+ = Dangoサーバーのメンテナンス用モニタ
5
+ =end
6
+
7
+ #$LOAD_PATH.push("../../../../svn/rubyforge/dango/lib")
8
+
9
+ #gem "dango"
10
+
11
+ require 'dango/client_framework' # コネクションサーバーフレームワークの呼び出し
12
+
13
+ #
14
+
15
+ # メインクラス
16
+ class DangoMonitorClient < DangoClientFramework
17
+ ConnTimeout = 6
18
+
19
+ def initialize()
20
+ super(ENV['RAILS_ENV'])
21
+ end
22
+
23
+ public
24
+
25
+ # 起動処理
26
+ def cs_client_init
27
+ # ログ出力情報
28
+ @connection_client_log_file = "log/dango_monitor_#{ENV['RAILS_ENV']}.log"
29
+ @connection_client_log_level = Logger::DEBUG
30
+ end
31
+
32
+ # アクセサの定義
33
+ # 読み込みのみ
34
+ attr_reader(:is_session_closed)
35
+
36
+ # サーバーの全情報取得
37
+ def get_all_info
38
+ cs_logger.debug "DangoMonitorClient:get_all_info"
39
+ begin
40
+ ret_obj = cs_client_send_receive_data('monitor_all_info', {})
41
+ rescue DangoFrameworkConnectionError
42
+ raise("monitor_all_info Connection error")
43
+ rescue DangoFrameworkTimeoutError
44
+ raise("monitor_all_info Timeout error")
45
+ end
46
+ raise("code is not 0 (faild). :code=#{ret_obj['code']}") if ret_obj['code'] != 0
47
+ ret_obj['all_info']
48
+ end
49
+
50
+ # サーバーのデータリロード
51
+ def server_reload
52
+ cs_logger.debug "DangoMonitorClient:server_reload"
53
+ begin
54
+ ret_obj = cs_client_send_receive_data('monitor_server_reload', {})
55
+ rescue DangoFrameworkConnectionError
56
+ raise("monitor_server_reload Connection error")
57
+ rescue DangoFrameworkTimeoutError
58
+ raise("monitor_server_reload Timeout error")
59
+ end
60
+ raise("code is not 0 (faild). :code=#{ret_obj['code']}") if ret_obj['code'] != 0
61
+ ret_obj['all_info']
62
+ end
63
+ end
64
+
65
+
66
+
@@ -0,0 +1,42 @@
1
+ #!ruby -Ku
2
+
3
+ #module Dango
4
+ require 'yaml'
5
+ require 'pp'
6
+
7
+ require 'dango/server_framework'
8
+
9
+ # require RAILS_ROOT + '/config/boot'
10
+ require RAILS_ROOT + '/config/environment'
11
+
12
+ # 環境によるコンフィグ読み込み
13
+ env = ENV['RAILS_ENV'] || 'development'
14
+
15
+ config = YAML.load(open("dango/config/#{env}.yml", "rb"){|fh| fh.read})
16
+
17
+ # serverファイル名一覧を取得
18
+ load_files = []
19
+ glob_str = 'dango/server/*.rb'
20
+ Dir.glob(glob_str) do |srv_file|
21
+ load_files.push({:file=>srv_file, :mtime=>File.mtime(srv_file)})
22
+ end
23
+
24
+ # ファイル名順にソート
25
+ load_files = load_files.sort_by{|f| f[:file] }
26
+ #p load_files
27
+
28
+ # config['load_files'] = load_files
29
+
30
+ # config:cache_classesによる処理分け
31
+ # if config['server']['cache_classes'] == true
32
+ # load_files.each do |f|
33
+ # require f[:file]
34
+ # end
35
+ # else
36
+ load_files.each do |f|
37
+ load f[:file]
38
+ end
39
+ # end
40
+
41
+ DangoServer.start(config)
42
+ #end
@@ -0,0 +1,661 @@
1
+ #!ruby -Ku
2
+
3
+ =begin
4
+ = コネクション型サーバーフレームワーク
5
+ =end
6
+
7
+ require 'gserver'
8
+ require 'ipaddr'
9
+
10
+ require "dango/framework_base"
11
+
12
+ # フレームワーククラス
13
+ class DangoServerFramework
14
+ include DangoFrameworkModule
15
+
16
+ SendReceiveSleepIntervalSec = 0.1 # データ送信後の順の際のタイムアウトチェック間隔秒
17
+
18
+ # cs_client_send_receive_data用の共有メモリ
19
+ def send_receive_shared_init
20
+ @send_receive_shared = SharedMemoryStore.new
21
+ end
22
+ def send_receive_shared
23
+ @send_receive_shared
24
+ end
25
+
26
+ class DangoGServer < GServer
27
+ def initialize(parent, *args)
28
+ @parent = parent
29
+ super(*args)
30
+ end
31
+
32
+ def serve(sock)
33
+ @parent.thread_main(sock)
34
+ end
35
+
36
+ def connecting(sock)
37
+ @parent.connecting(sock)
38
+ end
39
+
40
+ def disconnecting(sock)
41
+ @parent.disconnecting(sock)
42
+ end
43
+ end
44
+
45
+ def initialize(config)
46
+ @config = config
47
+
48
+ @gserver = nil # Gserver用の変数
49
+ @server_reload = nil # サーバーのリロード用フラグ
50
+
51
+ # SIGINT の捕捉
52
+ Signal.trap(:INT) do
53
+ puts "shutdown"
54
+ exit!
55
+ end
56
+
57
+ # サーバー開始
58
+ server_start()
59
+
60
+ loop do # 待ちで無限ループに入る
61
+ sleep 3
62
+ # p( Time.now.to_s + ":#{@server_reload.inspect}")
63
+ check_reload_class()
64
+ end
65
+ end
66
+
67
+ attr_reader(:log_file, :shared) # 読み書き
68
+
69
+ # 起動用のインスタンスメソッド
70
+ def self.start(config = {})
71
+ self.new(config)
72
+ end
73
+
74
+
75
+ # サーバー開始処理
76
+ def server_start()
77
+ set_server_variables() # 各種サーバー仕様の変数設定
78
+ shared_init() # 共有メモリを初期化
79
+ notice_shared_init() # 通知共有メモリを初期化
80
+ socket_list_init() # ソケット一覧を初期化
81
+ mutex_socket_list_init(cs_logger()) # ソケット毎用のmutexを初期化
82
+ send_receive_shared_init() # データ送受信用の共有メモリ初期化
83
+ cs_server_init() # 初期設定読み込み
84
+
85
+ cs_logger.debug("===== server initialize =====") # loggerの準備
86
+ cs_logger.debug("port=#{@connection_server_port}")
87
+ cs_logger.debug("host=#{@connection_server_host}")
88
+ cs_logger.debug("max_connections=#{@connection_server_max_connections}")
89
+
90
+ @gserver = DangoGServer.new(self, @connection_server_port,
91
+ @connection_server_host,
92
+ @connection_server_max_connections)
93
+ @gserver.audit = true # Turn logging on.
94
+ @gserver.start
95
+ end
96
+
97
+ # サーバーのループ時のクラス読み直し処理
98
+ def check_reload_class()
99
+ begin
100
+ # @config:cache_classesによる処理分け
101
+ # if @config['server']['cache_classes'] != true
102
+
103
+ # ロードファイルの変更確認
104
+ # changed = false
105
+ # @config['load_files'].each do |f|
106
+ # this_mtime = File.mtime(f[:file])
107
+ # if this_mtime > f[:mtime]
108
+ # f[:mtime] = this_mtime
109
+ # changed = true
110
+ # end
111
+ # end
112
+
113
+ # 変更していたら
114
+ # changed = nil
115
+ # if changed
116
+ if @server_reload
117
+ @server_reload = nil
118
+
119
+ puts "-- stopping server"
120
+
121
+ # 強制的に接続しているsocketをクローズ
122
+ cs_logger.debug "socket_list.keys:#{socket_list.keys.inspect}"
123
+ socket_list.keys.each do |sk|
124
+ cs_logger.debug "sk:#{socket_list[sk].inspect}"
125
+ socket_list[sk].close if ! socket_list[sk].closed?
126
+ socket_list[sk]
127
+ end
128
+
129
+ # サーバーを停止
130
+ @gserver.shutdown
131
+ @gserver.stop
132
+ while(!@gserver.stopped?) do
133
+ sleep 1
134
+ puts "waiting... #{@gserver.stopped?}"
135
+ cs_logger.debug "waiting... #{@gserver.stopped?} #{@gserver.connections}"
136
+ end
137
+
138
+ @gserver = nil
139
+
140
+ puts "-- stopped server"
141
+
142
+ # GCを行う
143
+ GC.start
144
+
145
+ # サーバーファイルを読み直し
146
+ puts "-- reload classes"
147
+ tmp_verbose = $VERBOSE
148
+ $VERBOSE = nil
149
+
150
+ # serverファイル名一覧を取得
151
+ load_files = []
152
+ glob_str = 'dango/server/*.rb'
153
+ Dir.glob(glob_str) do |srv_file|
154
+ load_files.push({:file=>srv_file, :mtime=>File.mtime(srv_file)})
155
+ end
156
+
157
+ # ファイル名順にソート
158
+ load_files = load_files.sort_by{|f| f[:file] }
159
+ load_files.each do |f|
160
+ begin
161
+ load f[:file]
162
+ rescue Exception
163
+ p $!.class
164
+ p $!.message
165
+ p $!.backtrace
166
+ end
167
+ end
168
+
169
+ $VERBOSE = tmp_verbose
170
+
171
+ # サーバーを再度起動
172
+ puts "-- start server"
173
+ server_start() # サーバー開始
174
+ end
175
+ # end
176
+ rescue Exception
177
+ cs_logger.error "#{$!.class}:#{$!.message}\n#{$!.backtrace.pretty_inspect}"
178
+ end
179
+ end
180
+
181
+ # gserver接続開始処理
182
+ def connecting(sock)
183
+ cs_logger.debug "connecting:sock=#{sock}"
184
+ end
185
+
186
+ # gserver接続開始処理
187
+ def disconnecting(port)
188
+ cs_logger.debug "disconnecting:port=#{port}"
189
+ end
190
+
191
+ # gserverのserveメソッド:スレッド開始処理
192
+ def thread_main(sock)
193
+ cs_logger.debug "thread_main:start"
194
+ cs_logger.debug "#{sock} is accepted. key=#{Thread.current.object_id}"
195
+
196
+ begin
197
+ session[:session_id] = Thread.current.object_id
198
+ socket_list.add(session[:session_id], sock)
199
+ mutex_socket_list.add(session[:session_id])
200
+
201
+ sock.binmode
202
+ sock.sync = true
203
+
204
+ cs_connect() # 接続時メソッド呼び出し
205
+
206
+ # メインループ入り
207
+ loop do
208
+ if sock.closed?
209
+ cs_logger.debug "#{sock.inspect}:sock is closed..."
210
+ break
211
+ end
212
+
213
+ cs_logger.debug "start cs_receive_data"
214
+ ret_obj = nil
215
+ # mutex_socket_list.synchronize(session[:session_id]) do
216
+ ret_obj = cs_receive_data(sock) # データ受信処理
217
+ # end
218
+ cs_logger.debug "finished cs_receive_data"
219
+
220
+ if ret_obj != {} # 受信データがあれば
221
+ if !(ret_obj && ret_obj["action"]) # actionが無い場合はエラー
222
+ cs_logger.error "no action error:#{ret_obj.inspect}"
223
+ raise(DangoFrameworkError, "no action error")
224
+ end
225
+
226
+ # アクション名
227
+ action_name = ret_obj["action"].to_s
228
+ cs_logger.debug "action_name=#{action_name}"
229
+
230
+ if action_name == 'monitor_all_info' # メンテナンスアクション名なら
231
+ cs_check_monitor_error(sock, "return_monitor_all_info")
232
+ cs_server_monitor_all_info()
233
+ elsif action_name == 'monitor_server_reload' # メンテナンスアクション名なら
234
+ cs_check_monitor_error(sock, "return_monitor_server_reload")
235
+ cs_server_monitor_server_reload()
236
+ else # メンテナンスコマンド以外のユーザーアクション名なら
237
+ begin
238
+ __send__("cs_receive_#{action_name}", ret_obj)
239
+ rescue NoMethodError
240
+ @recv_fail_count += 1 if @recv_fail_count # 受信失敗回数カウント
241
+ cs_logger.error "not find action #{action_name}:#{error_message($!, 'u')}"
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+ rescue DangoFrameworkConnectionError
248
+ @recv_fail_count += 1 if @recv_fail_count # 受信失敗回数カウント
249
+ cs_logger.debug "connection error. \n#{error_message($!, 'u')}"
250
+
251
+ rescue Exception
252
+ cs_logger.error "#{error_message($!, 'u')}"
253
+
254
+ ensure
255
+ cs_logger.debug "#{sock.inspect} is gone"
256
+
257
+ begin
258
+ cs_close() # 接続解除時に呼び出されるメソッド
259
+ rescue
260
+ cs_logger.error "#{error_message($!, 'u')}"
261
+ ensure
262
+ socket_list.delete(Thread.current.object_id) # ソケットリストから削除
263
+ sock.close # ソケットを閉じる
264
+
265
+ cs_logger.debug "#{sock.inspect} is gone 2"
266
+ end
267
+
268
+ end
269
+ end
270
+
271
+ # 各種サーバー仕様の変数設定
272
+ def set_server_variables()
273
+ # 変数の初期設定
274
+ @connection_server_port = @config['network']['port'] || 15000
275
+ @connection_server_host = @config['server']['host'] || "localhost"
276
+ @connection_server_max_connections = @config['server']['max_connections'] || 10
277
+ @log_file = @config['server']['log_file'] || ""
278
+
279
+ log_level_hash = {
280
+ "FATAL" => Logger::FATAL,
281
+ "ERROR" => Logger::ERROR,
282
+ "WARN" => Logger::WARN,
283
+ "INFO" => Logger::INFO,
284
+ "DEBUG" => Logger::DEBUG,
285
+ }
286
+ @log_level = log_level_hash.find do |level|
287
+ level == @config['server']['log_level']
288
+ end
289
+ @log_level = @connection_server_log_level || Logger::DEBUG
290
+
291
+ @start_time = Time.now # サーバー起動時間
292
+ @recv_count = 0 # 受信回数
293
+ @send_count = 0 # 送信回数
294
+ @recv_fail_count = 0 # 受信失敗回数
295
+ @send_fail_count = 0 # 送信失敗回数
296
+ end
297
+
298
+ def cs_server_init # 初期設定
299
+ end
300
+
301
+ # コンフィグのshared_database_managerによる使用クラスの選択
302
+ def select_shared_database_manager()
303
+ if @config['server']['shared_database_manager'] == 'MemoryStore'
304
+ SharedMemoryStore.new
305
+ else
306
+ SharedMemoryStore.new
307
+ end
308
+ end
309
+
310
+ # 共有メモリ
311
+ def shared_init
312
+ @shared = select_shared_database_manager()
313
+ end
314
+ def shared
315
+ @shared
316
+ end
317
+
318
+ # 通知共有メモリ
319
+
320
+ def notice_shared_init
321
+ # @notice_shared = NoticeShared.new(self)
322
+ @notice_shared = select_shared_database_manager()
323
+
324
+ class << @notice_shared ## 各種メソッド追加
325
+ def initialize2(parent)
326
+ @parent = parent
327
+ self[:notice_list] = {}
328
+ end
329
+
330
+ def init_key(key) # そのキーを作成する
331
+ if self[:notice_list].has_key?(key) || key == :notice_list # キーがすでにあるか予約語なら
332
+ raise(DangoFrameworkError, "notice_list already has key. key=#{key.inspect}")
333
+ end
334
+
335
+ self.transaction(:notice_list) do |notice_list|
336
+ notice_list[key] = []
337
+ notice_list
338
+ end
339
+ end
340
+
341
+ def add_connectable(key, session_id) # 接続許可にする
342
+ if !self[:notice_list].has_key?(key) # キーがなければ
343
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
344
+ end
345
+
346
+ self.transaction(:notice_list) do |notice_list|
347
+ notice_list[key] << session_id
348
+ notice_list
349
+ end
350
+ end
351
+
352
+ def remove_connectable(key, session_id) # 接続を不許可にする
353
+ if !self[:notice_list].has_key?(key) # キーがなければ
354
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
355
+ end
356
+
357
+ self.transaction(:notice_list) do |notice_list|
358
+ notice_list[key].delete(session_id)
359
+ notice_list
360
+ end
361
+ end
362
+
363
+ def get_connectables(key) # 接続許可一覧を返す
364
+ if !self[:notice_list].has_key?(key) # キーがなければ
365
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
366
+ end
367
+
368
+ self[:notice_list][key]
369
+ end
370
+
371
+ def notice_change(key, value) # 変更時に通知する変更
372
+ if !self[:notice_list].has_key?(key) # キーがなければ
373
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
374
+ end
375
+
376
+ self[key] = value
377
+
378
+ @parent.cs_logger.debug "self.get_connectables(key):#{self.get_connectables(key).inspect}"
379
+
380
+ self.get_connectables(key).each do |session_id|
381
+ @parent.cs_server_send_data(session_id, "notice_shared_#{key}".to_sym, value)
382
+ end
383
+ end
384
+
385
+ def not_notice_change(key, value) # 変更時に通知しない変更
386
+ if !self[:notice_list].has_key?(key) # キーがなければ
387
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
388
+ end
389
+
390
+ self[key] = value
391
+ end
392
+
393
+ def []=(key, value) # データの変更
394
+ if key != :notice_list && !self[:notice_list].has_key?(key) # キーがなければ
395
+ raise(DangoFrameworkError, "notice_list not has key. key=#{key.inspect}")
396
+ end
397
+
398
+ super(key, value) # データの変更
399
+ end
400
+ end
401
+ end
402
+
403
+ def notice_shared
404
+ @notice_shared
405
+ end
406
+
407
+ # セッション
408
+ class Session < Hash
409
+ end
410
+ def session
411
+ Thread.current[:session] = Session.new if !Thread.current[:session]
412
+ Thread.current[:session]
413
+ end
414
+
415
+ # ソケットとIDの対応
416
+ class SocketList
417
+ def initialize
418
+ @sl_hash = Hash.new
419
+ @sl_mutex = Mutex.new
420
+ end
421
+ def keys()
422
+ @sl_mutex.synchronize do
423
+ @sl_hash.keys
424
+ end
425
+ end
426
+ def delete(key)
427
+ @sl_mutex.synchronize do
428
+ @sl_hash.delete(key)
429
+ end
430
+ end
431
+ def add(key, sock)
432
+ @sl_mutex.synchronize do
433
+ raise("already exist key(#{key})") if @sl_hash.has_key?(key)
434
+ raise("sock(#{sock.ins}) is not Socket") if sock.kind_of?(Socket)
435
+ @sl_hash[key] = sock
436
+ end
437
+ end
438
+ def [](key)
439
+ @sl_mutex.synchronize do
440
+ raise("not exist key(#{key})") if ! @sl_hash.has_key?(key)
441
+ @sl_hash[key]
442
+ end
443
+ end
444
+ def []=(key, sock)
445
+ @sl_mutex.synchronize do
446
+ raise("not exist key(#{key})") if ! @sl_hash.has_key?(key)
447
+ raise("sock(#{sock.class}) is not Socket") if sock.kind_of?(Socket)
448
+ @sl_hash[key] = sock
449
+ end
450
+ end
451
+ end
452
+ def socket_list_init
453
+ @socket_list = SocketList.new
454
+ end
455
+ def socket_list
456
+ @socket_list
457
+ end
458
+
459
+ # ソケット毎用のmutex
460
+ class MutexSocketList
461
+ def initialize(cs_logger)
462
+ @cs_logger = cs_logger
463
+ @msl_hash = Hash.new
464
+ end
465
+ def keys()
466
+ @msl_hash.keys
467
+ end
468
+ def delete(key)
469
+ @msl_hash.delete(key)
470
+ end
471
+ def add(key)
472
+ @msl_hash[key] = Mutex.new
473
+ end
474
+ # def [](key)
475
+ # raise("not exist key(#{key})") if ! @msl_hash.has_key?(key)
476
+ ## add(key) if @msl_hash.has_key?(key)
477
+ # @msl_hash[key]
478
+ # end
479
+ def synchronize(key)
480
+ raise("not exist key(#{key})") if ! @msl_hash.has_key?(key)
481
+ @cs_logger.debug("mutex_socket_list starting synchronize. key=#{key}")
482
+ ret = nil
483
+ @msl_hash[key].synchronize do
484
+ @cs_logger.debug("mutex_socket_list started synchronize. key=#{key}")
485
+ ret = yield
486
+ @cs_logger.debug("mutex_socket_list finished synchronize. key=#{key}")
487
+ end
488
+ ret
489
+ end
490
+ end
491
+ def mutex_socket_list_init(cs_logger)
492
+ @mutex_sock_list = MutexSocketList.new(cs_logger) # ソケット毎用のmutex
493
+ end
494
+ def mutex_socket_list
495
+ @mutex_sock_list
496
+ end
497
+
498
+ # 接続時に呼び出されるメソッド
499
+ def cs_connect; end
500
+
501
+ # 接続解除時に呼び出されるメソッド
502
+ def cs_close; end
503
+
504
+
505
+ # サーバーの暗号化処理
506
+ def cs_server_send_encrypt(str) # 継承用
507
+ str
508
+ end
509
+ def cs_send_encrypt(str) # フレームワークから呼ばれる部分
510
+ cs_server_send_encrypt(str)
511
+ end
512
+
513
+ # サーバーの復号化処理
514
+ def cs_server_receive_decrypt(str) # 継承用
515
+ str
516
+ end
517
+ def cs_receive_decrypt(str) # フレームワークから呼ばれる部分
518
+ cs_server_receive_decrypt(str)
519
+ end
520
+
521
+ # サーバーからクライアントへのデータ送信
522
+ def cs_server_send_data(session_id, notice_name, send_obj, options = {})
523
+ cs_logger.debug "cs_server_send_data(#{session_id.inspect}, #{notice_name.inspect}, #{send_obj.inspect}, #{options.inspect})"
524
+
525
+ timeout = options[:timeout] || 6
526
+ dtype = options[:type] || 0
527
+
528
+ sock = socket_list[session_id]
529
+ raise(DangoFrameworkError, "not found session_id=#{session_id}") if !sock
530
+ raise(DangoFrameworkConnectionError, "socket closed. s_id=#{session_id}") if sock.closed?
531
+
532
+ cs_logger.debug "cs_server_send_data:sending data notice_name=#{notice_name.inspect}"
533
+ send_obj_dup = send_obj.deep_dup
534
+ send_obj_dup["notice"] = notice_name.to_s
535
+
536
+ # データ送信時にクライアントからのレスポンスを確認する(Flashのバグらしきもの対策)
537
+ if notice_name.to_s =~ /^return_/
538
+ cs_send_data(sock, send_obj_dup, :type=>dtype) # データ送信
539
+ cs_logger.debug "cs_server_send_data:finish send data notice_name=#{notice_name.inspect}\n"
540
+ else
541
+ Thread.start do
542
+ mutex_socket_list.synchronize(session_id) do
543
+ send_receive_shared[notice_name] = nil
544
+
545
+ receive_thread = nil
546
+ end_reserved_time = Time.now + timeout
547
+
548
+ # 戻ってきたデータのチェック
549
+ notice_name_sym = (notice_name.class == Symbol) ? (":"+notice_name.to_s) : ('"'+notice_name+'"')
550
+ instance_method_name = "cs_receive_response_#{notice_name}"
551
+ expr = <<-EOF
552
+ def self.#{instance_method_name}(ret_obj)
553
+ cs_logger.debug "ret_obj:" + ret_obj.inspect
554
+ send_receive_shared[#{notice_name_sym}] = ret_obj
555
+ end
556
+ cs_logger.debug "defined:#{instance_method_name}"
557
+ EOF
558
+ instance_eval expr
559
+
560
+ # タイムアウトチェック
561
+ (timeout.to_f / SendReceiveSleepIntervalSec).to_i.times do
562
+ raise(DangoFrameworkTimeoutError, "timeout:#{notice_name}") if Time.now > end_reserved_time
563
+
564
+ # 送信スレッドが開始していなければ開始
565
+ if !receive_thread
566
+ receive_thread = Thread.start do
567
+ cs_send_data(sock, send_obj_dup, :type=>dtype) # データ送信
568
+ cs_logger.debug "cs_server_send_data:finish send data notice_name=#{notice_name.inspect}\n"
569
+ end
570
+ end
571
+
572
+ # 戻ってきたデータがあれば
573
+ if send_receive_shared[notice_name]
574
+ cs_logger.debug "notice_name:#{send_receive_shared[notice_name].inspect}"
575
+ break
576
+ end
577
+
578
+ cs_logger.debug "sleep:#{SendReceiveSleepIntervalSec}"
579
+ sleep SendReceiveSleepIntervalSec # スリープ
580
+ end
581
+
582
+ if !send_receive_shared[notice_name] # 戻ってきたデータがあるかどうかチェック
583
+ raise(DangoFrameworkError, "received data is none")
584
+ end
585
+
586
+ remove_method(instance_method_name) # 定義したインスタンスメソッドを削除しておく
587
+ end
588
+ end
589
+ end
590
+
591
+ self
592
+ end
593
+
594
+ # メンテナンスコマンド:エラーの場合
595
+ def cs_check_monitor_error(sock, return_command)
596
+ peerhost, peeraddr = sock.peeraddr[2, 2]
597
+ backdoor_host = @config['server']['backdoor_host']
598
+ match = false
599
+ if peerhost == backdoor_host # ホスト名で書いてある時の一致確認
600
+ match = true
601
+ else
602
+ begin # IPアドレスの一致確認
603
+ match = true if IPAddr.new(peeraddr) == IPAddr.new(backdoor_host)
604
+ rescue
605
+ end
606
+ end
607
+
608
+ if !match
609
+ send_obj = {'code'=>1, 'message'=>"error your ip address"}
610
+ cs_server_send_data(session[:session_id], return_command, send_obj, :type=>2)
611
+ raise(DangoFrameworkError)
612
+ end
613
+ end
614
+
615
+ # メンテナンスコマンド:サーバーからクライアントへのデータ送信
616
+ def cs_server_monitor_all_info()
617
+ all_info = {
618
+ 'shareds' => shared.to_hash,
619
+ 'socket_list' => socket_list.keys,
620
+
621
+ 'server_start_time' => @start_time.strftime("%Y-%m-%d %H:%M:%S"),
622
+ 'up_time' => Time.now - @start_time,
623
+
624
+ 'recv_count' => @recv_count, # 受信回数
625
+ 'send_count' => @send_count, # 送信回数
626
+ 'recv_fail_count' => @recv_fail_count, # 受信失敗回数
627
+ 'send_fail_count' => @send_fail_count, # 送信失敗回数
628
+ # 'dummy' => "dummy "*1000, # ダミー情報
629
+ }
630
+
631
+ send_obj = {'code'=>0, 'all_info'=>all_info}
632
+ cs_server_send_data(session[:session_id], 'return_monitor_all_info', send_obj, :type=>2)
633
+ end
634
+
635
+ # メンテナンスコマンド:サーバーからクライアントへのデータ送信
636
+ def cs_server_monitor_server_reload()
637
+ cs_logger.debug "cs_server_monitor_server_reload"
638
+ @server_reload = true
639
+ cs_logger.debug "@server_reload=#{@server_reload.inspect}"
640
+ send_obj = {'code'=>0, 'message'=>'success'}
641
+ cs_server_send_data(session[:session_id], 'return_monitor_server_reload', send_obj, :type=>2)
642
+ end
643
+
644
+ # 必要に応じて追加するメソッド
645
+ def method_missing(name, *args)
646
+ if name.to_s =~ /^cs_receive_action_notice_shared_(.+)/ # 共有メモリ変更通知なら
647
+ key = $1
648
+ method_action_notice_shared(key, name, *args)
649
+ else
650
+ # raise(NameError, "method not found. #{name.inspect} #{args.inspect}")
651
+ end
652
+ end
653
+
654
+ def method_action_notice_shared(key, name, *args) # 共有メモリ変更通知のメソッド
655
+ cs_logger.debug "method_name:#{name}"
656
+ send_obj = args[0]
657
+ notice_shared.notice_change(key.to_sym, send_obj)
658
+ end
659
+
660
+ end
661
+