dango 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +13 -0
- data/README.txt +47 -0
- data/lib/dango/client_framework.rb +260 -0
- data/lib/dango/framework_base.rb +247 -0
- data/lib/dango/monitor/dango_monitor_client.rb +66 -0
- data/lib/dango/script/dango_server.rb +42 -0
- data/lib/dango/server_framework.rb +661 -0
- data/lib/dango/shared/memory_store.rb +91 -0
- data/lib/dango/tasks/dango_rake.rb +38 -0
- data/lib/dango/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_dango.rb +13 -0
- data/test/test_helper.rb +2 -0
- metadata +67 -0
data/Manifest.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Manifest.txt
|
2
|
+
README.txt
|
3
|
+
lib/dango/client_framework.rb
|
4
|
+
lib/dango/framework_base.rb
|
5
|
+
lib/dango/server_framework.rb
|
6
|
+
lib/dango/monitor/dango_monitor_client.rb
|
7
|
+
lib/dango/script/dango_server.rb
|
8
|
+
lib/dango/shared/memory_store.rb
|
9
|
+
lib/dango/tasks/dango_rake.rb
|
10
|
+
lib/dango/version.rb
|
11
|
+
setup.rb
|
12
|
+
test/test_helper.rb
|
13
|
+
test/test_dango.rb
|
data/README.txt
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= dango -- Ruby - Flash conneciton network flamework
|
2
|
+
|
3
|
+
|
4
|
+
== Download
|
5
|
+
|
6
|
+
The latest version of dango can be found at
|
7
|
+
|
8
|
+
* http://rubyforge.org/frs/?group_id=****
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
=== Normal Installation
|
13
|
+
|
14
|
+
You can install dango with the following command.
|
15
|
+
|
16
|
+
% ruby setup.rb
|
17
|
+
|
18
|
+
from its distribution directory.
|
19
|
+
|
20
|
+
=== GEM Installation
|
21
|
+
|
22
|
+
Download and install dango with the following.
|
23
|
+
|
24
|
+
gem install dango
|
25
|
+
|
26
|
+
== dango References
|
27
|
+
|
28
|
+
* dango Project Page: http://rubyforge.org/projects/dango
|
29
|
+
* dango API Documents: http://dango.rubyforge.org
|
30
|
+
|
31
|
+
== Simple Example
|
32
|
+
|
33
|
+
ruby "rubygems" # you use rubygems
|
34
|
+
ruby "image_size"
|
35
|
+
ruby "open-uri"
|
36
|
+
open("http://www.rubycgi.org/image/ruby_gtk_book_title.jpg", "rb") do |fh|
|
37
|
+
p ImageSize.new(fh.read).get_size
|
38
|
+
end
|
39
|
+
|
40
|
+
== Licence
|
41
|
+
|
42
|
+
This code is free to use under the terms of the Ruby's licence.
|
43
|
+
|
44
|
+
== Contact
|
45
|
+
|
46
|
+
Comments are welcome. Send an email to "Keisuke Minami":mailto:keisuke@rccn.com
|
47
|
+
|
@@ -0,0 +1,260 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
=begin
|
4
|
+
= コネクション型クライアントフレームワーク
|
5
|
+
=end
|
6
|
+
|
7
|
+
require "dango/framework_base"
|
8
|
+
|
9
|
+
# フレームワーククラス
|
10
|
+
class DangoClientFramework
|
11
|
+
include DangoFrameworkModule
|
12
|
+
|
13
|
+
SendReceiveSleepIntervalSec = 0.1 # データ送信後の順の際のタイムアウトチェック間隔秒
|
14
|
+
|
15
|
+
# cs_client_send_receive_data用の共有メモリ
|
16
|
+
def send_receive_shared_init
|
17
|
+
@send_receive_shared = SharedMemoryStore.new
|
18
|
+
end
|
19
|
+
def send_receive_shared
|
20
|
+
@send_receive_shared
|
21
|
+
end
|
22
|
+
|
23
|
+
# 起動処理
|
24
|
+
def cs_client_init
|
25
|
+
end
|
26
|
+
|
27
|
+
# セッションが切れると呼ばれる処理
|
28
|
+
def cs_session_closed
|
29
|
+
end
|
30
|
+
|
31
|
+
# メイン処理
|
32
|
+
def initialize(env, config = nil)
|
33
|
+
if !config
|
34
|
+
config = YAML.load(open("dango/config/#{env}.yml", "rb"){|fh| fh.read})
|
35
|
+
end
|
36
|
+
|
37
|
+
@config = config
|
38
|
+
|
39
|
+
# 変数の初期設定
|
40
|
+
@connection_client_host = @config['client']['host'] || 'localhost'
|
41
|
+
@connection_client_port = @config['network']['port'] || 15000
|
42
|
+
|
43
|
+
@connection_client_host = 'localhost' # 未定義時にこのホスト名でサーバー開始
|
44
|
+
@connection_client_port = 15000 # 未定義時にこのポートでサーバー開始
|
45
|
+
@connection_client_log_file = "" # 未定義時にこのログファイル名を使う
|
46
|
+
@connection_client_log_level = Logger::DEBUG # 未定義時にこのログレベルになる
|
47
|
+
|
48
|
+
@recv_count = 0 # 受信回数
|
49
|
+
@send_count = 0 # 送信回数
|
50
|
+
|
51
|
+
Signal.trap('INT') do # SIGINT を捕捉する。
|
52
|
+
puts "shutdown"
|
53
|
+
# exit
|
54
|
+
exit!
|
55
|
+
end
|
56
|
+
|
57
|
+
cs_client_init() # 初期設定読み込み
|
58
|
+
|
59
|
+
@log_file = @connection_client_log_file
|
60
|
+
@log_level = @connection_client_log_level
|
61
|
+
|
62
|
+
# loggerの準備
|
63
|
+
cs_logger.debug("client initialize")
|
64
|
+
|
65
|
+
# データ送受信用の共有メモリ初期化
|
66
|
+
send_receive_shared_init()
|
67
|
+
@send_receive_mutex = Mutex.new # 送受信用の排他処理
|
68
|
+
|
69
|
+
# 通知共有メモリの初期化
|
70
|
+
cs_client_notice_shared_init()
|
71
|
+
|
72
|
+
# ソケットの準備
|
73
|
+
@sock = nil
|
74
|
+
|
75
|
+
# サーバーへ接続
|
76
|
+
begin
|
77
|
+
@sock = TCPSocket.new(@connection_client_host, @connection_client_port)
|
78
|
+
rescue Errno::EBADF
|
79
|
+
raise DangoFrameworkConnectionError
|
80
|
+
end
|
81
|
+
|
82
|
+
@sock.binmode
|
83
|
+
@sock.sync = true
|
84
|
+
@tmutex = Mutex.new # sockの排他処理用
|
85
|
+
cs_logger.debug("addr:#{@sock.addr.inspect}")
|
86
|
+
|
87
|
+
# データ受信用のスレッドの開始
|
88
|
+
@thread_receive = Thread.start{ thread_main() }
|
89
|
+
end
|
90
|
+
|
91
|
+
# データ受信用のスレッド処理
|
92
|
+
def thread_main()
|
93
|
+
catch(:session_closed) do
|
94
|
+
loop do
|
95
|
+
begin
|
96
|
+
if @sock
|
97
|
+
cs_logger.debug "start receive_data"
|
98
|
+
ret_obj = nil
|
99
|
+
begin
|
100
|
+
ret_obj = cs_receive_data(@sock) # データ受信処理
|
101
|
+
rescue DangoFrameworkConnectionError
|
102
|
+
cs_logger.debug "sock error:#{error_message($!, 'u')}"
|
103
|
+
throw(:session_closed)
|
104
|
+
rescue DangoFrameworkError
|
105
|
+
cs_logger.debug "sock error:#{error_message($!, 'u')}"
|
106
|
+
throw(:session_closed)
|
107
|
+
end
|
108
|
+
cs_logger.debug "finished cs_receive_data:#{ret_obj.inspect}"
|
109
|
+
|
110
|
+
if !(ret_obj && ret_obj["notice"])
|
111
|
+
cs_logger.info "no notice:#{ret_obj["notice"].inspect}"
|
112
|
+
end
|
113
|
+
|
114
|
+
# メソッド呼び出し
|
115
|
+
cs_logger.info "calling method=#{ret_obj["notice"].inspect}"
|
116
|
+
begin
|
117
|
+
__send__("cs_receive_#{ret_obj["notice"]}", ret_obj)
|
118
|
+
rescue
|
119
|
+
cs_logger.error "error in cs_receive_#{ret_obj["notice"]}\n#{error_message($!, 'u')}"
|
120
|
+
end
|
121
|
+
cs_logger.debug "called method=#{ret_obj["notice"].inspect}"
|
122
|
+
|
123
|
+
else
|
124
|
+
sleep 0.1
|
125
|
+
end
|
126
|
+
|
127
|
+
rescue Exception
|
128
|
+
cs_logger.debug "#{error_message($!, 'u')}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
client_quit() # クライアントの終了処理
|
134
|
+
end
|
135
|
+
private :thread_main
|
136
|
+
|
137
|
+
# ユーザーが終了させたい時に呼び出すメソッド(セッションを切る)
|
138
|
+
def cs_client_close
|
139
|
+
client_quit() # クライアントの終了処理
|
140
|
+
end
|
141
|
+
|
142
|
+
# クライアントの終了処理
|
143
|
+
def client_quit()
|
144
|
+
begin
|
145
|
+
@sock.close if @sock
|
146
|
+
rescue
|
147
|
+
cs_logger.debug "sock close failed. #{$!}"
|
148
|
+
end
|
149
|
+
@sock = nil
|
150
|
+
|
151
|
+
@is_session_closed = true
|
152
|
+
cs_logger.info "calling cs_session_closed()"
|
153
|
+
cs_session_closed() # セッションが切れると呼ばれる処理
|
154
|
+
end
|
155
|
+
private :client_quit
|
156
|
+
|
157
|
+
# クライアントの暗号化処理
|
158
|
+
def cs_client_send_encrypt(str) # 継承用
|
159
|
+
str
|
160
|
+
end
|
161
|
+
def cs_send_encrypt(str) # フレームワークから呼ばれる部分
|
162
|
+
cs_client_send_encrypt(str)
|
163
|
+
end
|
164
|
+
|
165
|
+
# クライアントの復号化処理
|
166
|
+
def cs_client_receive_decrypt(str) # 継承用
|
167
|
+
str
|
168
|
+
end
|
169
|
+
def cs_receive_decrypt(str) # フレームワークから呼ばれる部分
|
170
|
+
cs_client_receive_decrypt(str)
|
171
|
+
end
|
172
|
+
|
173
|
+
# クライアントからサーバーへのデータ送信
|
174
|
+
def cs_client_send_data(action_name, send_obj)
|
175
|
+
send_obj_dup = send_obj.dup
|
176
|
+
send_obj_dup["action"] = action_name.to_s
|
177
|
+
cs_send_data(@sock, send_obj_dup)
|
178
|
+
end
|
179
|
+
|
180
|
+
# サーバーからクライアントへのデータ送信
|
181
|
+
# 自動でreturn_nameに対応したcs_receive_メソッドが出来上がるので注意
|
182
|
+
# options = {:return_name=> :timeout => }
|
183
|
+
# return_nameは省略時は、action_nameの頭にreturnを付けたもののシンボルになる
|
184
|
+
# timeoutは省略時は6秒
|
185
|
+
def cs_client_send_receive_data(action_name, send_obj, options = {})
|
186
|
+
cs_logger.debug "cs_client_send_receive_data(#{action_name.inspect}, #{send_obj.inspect}, #{options.inspect})"
|
187
|
+
|
188
|
+
return_name = options[:return_name] || ("return_" + action_name.to_s).to_sym
|
189
|
+
timeout = options[:timeout] || 6
|
190
|
+
|
191
|
+
@send_receive_mutex.synchronize do
|
192
|
+
send_receive_shared[action_name] = nil
|
193
|
+
|
194
|
+
receive_thread = nil
|
195
|
+
end_reserved_time = Time.now + timeout
|
196
|
+
|
197
|
+
# 戻ってきたデータのチェック
|
198
|
+
action_name_sym = (action_name.class == Symbol) ? (":"+action_name.to_s) : ('"'+action_name+'"')
|
199
|
+
instance_method_name = "cs_receive_#{return_name}"
|
200
|
+
expr = <<-EOF
|
201
|
+
def self.#{instance_method_name}(ret_obj)
|
202
|
+
cs_logger.debug "ret_obj:" + ret_obj.inspect
|
203
|
+
send_receive_shared[#{action_name_sym}] = ret_obj
|
204
|
+
end
|
205
|
+
EOF
|
206
|
+
instance_eval expr
|
207
|
+
|
208
|
+
# タイムアウトチェック
|
209
|
+
(timeout.to_f / SendReceiveSleepIntervalSec).to_i.times do
|
210
|
+
raise(DangoFrameworkTimeoutError, "timeout:#{action_name}") if Time.now > end_reserved_time
|
211
|
+
|
212
|
+
# 送信スレッドが開始していなければ開始
|
213
|
+
if !receive_thread
|
214
|
+
receive_thread = Thread.start do
|
215
|
+
cs_client_send_data(action_name, send_obj)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# 戻ってきたデータがあれば
|
220
|
+
if send_receive_shared[action_name]
|
221
|
+
cs_logger.debug "action_name:#{send_receive_shared[action_name].inspect}"
|
222
|
+
break
|
223
|
+
end
|
224
|
+
|
225
|
+
sleep SendReceiveSleepIntervalSec # スリープ
|
226
|
+
end
|
227
|
+
|
228
|
+
if !send_receive_shared[action_name] # 戻ってきたデータがあるかどうかチェック
|
229
|
+
raise(DangoFrameworkError, "received data is none")
|
230
|
+
end
|
231
|
+
|
232
|
+
#remove_method(instance_method_name) # 定義したインスタンスメソッドを削除しておく
|
233
|
+
|
234
|
+
send_receive_shared[action_name]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# 通知共有メモリ情報の書き換えクラス
|
239
|
+
class ClientNoticeShared
|
240
|
+
def initialize(parent)
|
241
|
+
@parent = parent
|
242
|
+
end
|
243
|
+
|
244
|
+
def []=(key, value) # キーに対する書き込み(読み込みはないぞ)
|
245
|
+
action_name = "action_notice_shared_#{key}"
|
246
|
+
send_obj = {:data => value}
|
247
|
+
@parent.cs_client_send_data(action_name, send_obj)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def cs_client_notice_shared_init # 通知共有メモリの初期化
|
252
|
+
@client_notice_shared = ClientNoticeShared.new(self)
|
253
|
+
end
|
254
|
+
|
255
|
+
def cs_client_notice_shared # 通知共有メモリ
|
256
|
+
@client_notice_shared
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
@@ -0,0 +1,247 @@
|
|
1
|
+
#!ruby -Ku
|
2
|
+
|
3
|
+
=begin
|
4
|
+
= コネクションのサーバー、クライアントで使うモジュール
|
5
|
+
=end
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
|
9
|
+
require 'logger'
|
10
|
+
require 'socket'
|
11
|
+
require 'thread'
|
12
|
+
require 'timeout'
|
13
|
+
require 'yaml'
|
14
|
+
require "stringio"
|
15
|
+
require "pp"
|
16
|
+
require "kconv"
|
17
|
+
require "fcntl"
|
18
|
+
require "json"
|
19
|
+
|
20
|
+
require "dango/shared/memory_store.rb"
|
21
|
+
|
22
|
+
|
23
|
+
class Object
|
24
|
+
# 1.8.5では実装済みの機能を1.8.4でも使えるようにしたもの
|
25
|
+
if RUBY_VERSION < '1.8.5'
|
26
|
+
def pretty_inspect
|
27
|
+
str = StringIO.open("", "w+") do |sio|
|
28
|
+
PP.pp(self, sio)
|
29
|
+
sio.rewind
|
30
|
+
sio.read
|
31
|
+
end
|
32
|
+
|
33
|
+
str
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def deep_dup
|
38
|
+
Marshal.load(Marshal.dump(self))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Timeクラスの表示形式修正
|
43
|
+
#class Time
|
44
|
+
# def to_s
|
45
|
+
# self.strftime("%Y-%m-%d %H:%M:%S")
|
46
|
+
# end
|
47
|
+
#end
|
48
|
+
|
49
|
+
# 例外定義
|
50
|
+
class DangoFrameworkError < StandardError; end
|
51
|
+
class DangoFrameworkTimeoutError < DangoFrameworkError; end
|
52
|
+
class DangoFrameworkConnectionError < DangoFrameworkError; end
|
53
|
+
|
54
|
+
# エラー出力用モジュール
|
55
|
+
module ErrorMessage
|
56
|
+
# デバッグ出力用のメソッド
|
57
|
+
def error_message(exception_class, code = nil)
|
58
|
+
if exception_class.kind_of?(Exception)
|
59
|
+
"#{exception_class.class} is not Exception class"
|
60
|
+
end
|
61
|
+
|
62
|
+
str = "#{exception_class.class}:#{exception_class.message}\n#{exception_class.backtrace.pretty_inspect}"
|
63
|
+
if code.downcase == "u" || code.downcase == "utf8"
|
64
|
+
str = str.toutf8
|
65
|
+
elsif code.downcase == "s" || code.downcase == "sjis"
|
66
|
+
str = str.tosjis
|
67
|
+
end
|
68
|
+
str
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# ユーティティ
|
73
|
+
module DangoUtilModule
|
74
|
+
# 配列をランダムに並べ替え
|
75
|
+
# arrは順番を入れ替えたい配列
|
76
|
+
# numは入れ替え回数(省略時2、大きな数を入れると確実にランダムになるが時間が掛かる)
|
77
|
+
def array_random(arr, num = 2)
|
78
|
+
arr.sort_by{rand}
|
79
|
+
|
80
|
+
# ret_arr = arr.deep_dup
|
81
|
+
# (ret_arr.size * num).times do # メンバー数のnum倍の回数、入れ替え
|
82
|
+
# idx = rand(ret_arr.size)
|
83
|
+
# id = ret_arr.delete_at(idx)
|
84
|
+
# ret_arr.push(id)
|
85
|
+
# end
|
86
|
+
# ret_arr
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# クライアントとサーバーで共有するモジュール
|
91
|
+
module DangoFrameworkModule
|
92
|
+
include ErrorMessage
|
93
|
+
|
94
|
+
CommMaxDigit = 5 # 通信の最大桁数
|
95
|
+
MaxLen = 1024 # 通信の一度の送信バイト数
|
96
|
+
|
97
|
+
DefaultDataType = 0 # デフォルトのデータのタイプ
|
98
|
+
|
99
|
+
# 0 = JSON
|
100
|
+
# 1 = YAML
|
101
|
+
# 2 = Marshal
|
102
|
+
|
103
|
+
# デバッグ出力用のメソッド
|
104
|
+
def cs_debug_print(str)
|
105
|
+
cs_logger.debug str
|
106
|
+
puts str if $VERBOSE
|
107
|
+
end
|
108
|
+
|
109
|
+
# ロガーの定義
|
110
|
+
def cs_logger
|
111
|
+
# if !@cs_logger # これだと警告が出てうざいので
|
112
|
+
if !self.instance_variables.find{|iv| iv == '@cs_logger'} # @cs_loggerが未定義なら
|
113
|
+
if @log_file != ""
|
114
|
+
log_dir = File.dirname(@log_file)
|
115
|
+
Dir.mkdir(log_dir) if !File.exist?(log_dir)
|
116
|
+
@cs_logger = Logger.new(@log_file)
|
117
|
+
@cs_logger.level = @log_level
|
118
|
+
# @cs_logger.datetime_format = "%Y-%m-%dT%H:%M:%S"
|
119
|
+
@cs_logger.datetime_format = "aaaaa"
|
120
|
+
@cs_logger.progname = "#{Thread.current.object_id}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
@cs_logger
|
124
|
+
end
|
125
|
+
|
126
|
+
# データ受信処理
|
127
|
+
def cs_receive_data(sock)
|
128
|
+
ret_data = ""
|
129
|
+
|
130
|
+
cs_logger.debug "receive_data(#{sock})"
|
131
|
+
|
132
|
+
begin
|
133
|
+
# size_str = sock.readpartial(CommMaxDigit + 1)
|
134
|
+
# size_str = sock.sysread(CommMaxDigit + 1)
|
135
|
+
size_str = sock.recv(CommMaxDigit + 1)
|
136
|
+
rescue EOFError
|
137
|
+
# EOFErrorはその接続終了時の切断と思われるのでDangoFrameworkConnectionErrorにしない
|
138
|
+
#raise(DangoFrameworkError, "failed to read sock for EOF reached.\n#{error_message($!, 'u')}")
|
139
|
+
raise(DangoFrameworkError, "failed to read sock for EOF reached.")
|
140
|
+
rescue
|
141
|
+
raise(DangoFrameworkConnectionError, "failed to read sock.\n#{error_message($!, 'u')}")
|
142
|
+
end
|
143
|
+
|
144
|
+
dtype, size = size_str[0, 5].unpack("cN")
|
145
|
+
|
146
|
+
raise(DangoFrameworkError, "size=0:size_str=#{size_str.inspect}") if size == 0
|
147
|
+
|
148
|
+
cs_logger.debug "size=#{size}:size_str=#{size_str.inspect}"
|
149
|
+
|
150
|
+
ret_data_orig = ""
|
151
|
+
|
152
|
+
while size > 0
|
153
|
+
read_len = MaxLen > size ? size : MaxLen
|
154
|
+
begin
|
155
|
+
# this_ret_data_orig = sock.readpartial(read_len)
|
156
|
+
# this_ret_data_orig = sock.sysread(read_len)
|
157
|
+
this_ret_data_orig = sock.recv(read_len)
|
158
|
+
rescue
|
159
|
+
raise(DangoFrameworkConnectionError, "failed to read sock(data).\n#{error_message($!, 'u')}")
|
160
|
+
end
|
161
|
+
|
162
|
+
ret_data_orig += this_ret_data_orig
|
163
|
+
# cs_logger.debug "size:#{size.inspect}:this_ret_data_orig:#{this_ret_data_orig.inspect}"
|
164
|
+
|
165
|
+
size -= this_ret_data_orig.size
|
166
|
+
# cs_logger.debug "size:#{size.inspect}"
|
167
|
+
end
|
168
|
+
|
169
|
+
# cs_logger.debug "ret_data_orig:#{ret_data_orig.inspect}"
|
170
|
+
|
171
|
+
ret_data = cs_receive_decrypt(ret_data_orig[0..-2])
|
172
|
+
|
173
|
+
@recv_count += 1 if @recv_count # 受信回数カウント
|
174
|
+
# cs_logger.debug "ret_data:#{ret_data.inspect}"
|
175
|
+
|
176
|
+
begin
|
177
|
+
if ret_data == "\n" # データが空ならparseしない
|
178
|
+
data = {}
|
179
|
+
elsif dtype == 0
|
180
|
+
data = JSON.parse(ret_data)
|
181
|
+
elsif dtype == 1
|
182
|
+
data = YAML::load(ret_data)
|
183
|
+
elsif dtype == 2
|
184
|
+
data = Marshal.load(ret_data)
|
185
|
+
end
|
186
|
+
rescue
|
187
|
+
raise(DangoFrameworkError, "data parse error.\nret_data=#{ret_data}")
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# データ送信処理
|
192
|
+
def cs_send_data(sock, send_obj, options = {})
|
193
|
+
cs_logger.debug "cs_send_data"
|
194
|
+
|
195
|
+
dtype = options[:type] || DefaultDataType
|
196
|
+
|
197
|
+
if send_obj == {}
|
198
|
+
send_data_orig = ""
|
199
|
+
elsif dtype == 0
|
200
|
+
send_data_orig = JSON.generate(send_obj)
|
201
|
+
elsif dtype == 1
|
202
|
+
send_data_orig = send_obj.to_yaml
|
203
|
+
elsif dtype == 2
|
204
|
+
send_data_orig = Marshal.dump(send_obj)
|
205
|
+
end
|
206
|
+
|
207
|
+
send_data = cs_send_encrypt(send_data_orig) + "\n"
|
208
|
+
# send_data = cs_send_encrypt(send_data_orig) + "\r\n"
|
209
|
+
# send_data = cs_send_encrypt(send_data_orig) + "\015\012"
|
210
|
+
|
211
|
+
# cs_logger.debug "start send_data:#{send_data.inspect}"
|
212
|
+
|
213
|
+
size = send_data.size
|
214
|
+
|
215
|
+
if size >= 4294967296
|
216
|
+
raise(DangoFrameworkError, "max size over. size:#{size} >= 4294967296")
|
217
|
+
end
|
218
|
+
|
219
|
+
# size_str = sprintf("%0#{CommMaxDigit}d", size)
|
220
|
+
|
221
|
+
size_str = [dtype, size].pack("cN")
|
222
|
+
# cs_logger.debug "size=#{size}:size_str=#{size_str.inspect}"
|
223
|
+
|
224
|
+
send_buf = size_str + "\n" + send_data
|
225
|
+
# cs_logger.debug "send_buf:#{send_buf.inspect}"
|
226
|
+
|
227
|
+
begin
|
228
|
+
# sock.write send_buf
|
229
|
+
# sock.flush
|
230
|
+
|
231
|
+
# sock.send(size_str + "\n", 0)
|
232
|
+
# sock.flush
|
233
|
+
# sock.send(send_data, 0)
|
234
|
+
# sock.flush
|
235
|
+
|
236
|
+
sock.send(send_buf, 0)
|
237
|
+
sock.flush
|
238
|
+
rescue
|
239
|
+
raise(DangoFrameworkConnectionError, "sock write failed.\n#{error_message($!, 'u')}")
|
240
|
+
end
|
241
|
+
|
242
|
+
@send_count += 1 if @send_count # 受信回数カウント
|
243
|
+
# cs_logger.debug "finish send_data:#{send_data.inspect}"
|
244
|
+
sock
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|