nng-ruby 0.1.2 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +78 -45
- data/Gemfile +10 -10
- data/LICENSE +21 -21
- data/README.md +1201 -1200
- data/Rakefile +22 -22
- data/examples/pair.rb +48 -48
- data/examples/protobuf_advanced.rb +322 -322
- data/examples/protobuf_demo.rb +340 -340
- data/examples/protobuf_example.rb +374 -374
- data/examples/protobuf_simple.rb +191 -191
- data/examples/protobuf_thread.rb +236 -236
- data/examples/pubsub.rb +51 -51
- data/examples/reqrep.rb +54 -54
- data/ext/nng/extconf.rb +80 -71
- data/ext/nng/libnng.so.1.11.0 +0 -0
- data/ext/nng/nng.dll +0 -0
- data/lib/nng/errors.rb +48 -48
- data/lib/nng/ffi.rb +508 -445
- data/lib/nng/message.rb +151 -151
- data/lib/nng/protocols.rb +96 -96
- data/lib/nng/socket.rb +196 -196
- data/lib/nng/version.rb +5 -5
- data/lib/nng.rb +52 -52
- data/nng.gemspec +67 -67
- metadata +5 -4
- data/ext/nng/libnng.so.1.8.0 +0 -0
data/lib/nng/ffi.rb
CHANGED
@@ -1,445 +1,508 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'ffi'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# Priority
|
42
|
-
if
|
43
|
-
paths <<
|
44
|
-
puts "NNG: Using library from
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
puts "NNG: Searching in
|
53
|
-
end
|
54
|
-
|
55
|
-
# Priority
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
#
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
end
|
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
|
-
|
274
|
-
|
275
|
-
|
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
|
-
attach_function :
|
315
|
-
|
316
|
-
|
317
|
-
attach_function :
|
318
|
-
|
319
|
-
|
320
|
-
attach_function :
|
321
|
-
|
322
|
-
|
323
|
-
attach_function :
|
324
|
-
attach_function :
|
325
|
-
|
326
|
-
|
327
|
-
attach_function :
|
328
|
-
attach_function :
|
329
|
-
attach_function :
|
330
|
-
attach_function :
|
331
|
-
attach_function :
|
332
|
-
|
333
|
-
|
334
|
-
attach_function :
|
335
|
-
|
336
|
-
|
337
|
-
attach_function :
|
338
|
-
attach_function :
|
339
|
-
attach_function :
|
340
|
-
attach_function :
|
341
|
-
|
342
|
-
|
343
|
-
attach_function :
|
344
|
-
attach_function :
|
345
|
-
|
346
|
-
|
347
|
-
attach_function :
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
attach_function :
|
352
|
-
attach_function :
|
353
|
-
attach_function :
|
354
|
-
attach_function :
|
355
|
-
|
356
|
-
|
357
|
-
attach_function :
|
358
|
-
attach_function :
|
359
|
-
attach_function :
|
360
|
-
attach_function :
|
361
|
-
|
362
|
-
|
363
|
-
attach_function :
|
364
|
-
attach_function :
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
attach_function :
|
376
|
-
attach_function :
|
377
|
-
attach_function :
|
378
|
-
attach_function :
|
379
|
-
attach_function :
|
380
|
-
attach_function :
|
381
|
-
attach_function :
|
382
|
-
attach_function :
|
383
|
-
|
384
|
-
|
385
|
-
attach_function :
|
386
|
-
|
387
|
-
|
388
|
-
attach_function :
|
389
|
-
attach_function :
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
attach_function :
|
394
|
-
attach_function :
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
#
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
#
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
module NNG
|
7
|
+
# FFI bindings for libnng
|
8
|
+
module FFI
|
9
|
+
extend ::FFI::Library
|
10
|
+
|
11
|
+
# Load install-time configuration if available
|
12
|
+
@install_config = {}
|
13
|
+
config_file = File.expand_path('../../ext/nng/nng_config.rb', __dir__)
|
14
|
+
if File.exist?(config_file)
|
15
|
+
require config_file
|
16
|
+
@install_config = NNG::InstallConfig::CONFIG rescue {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Detect platform and return library file patterns
|
20
|
+
def self.platform_info
|
21
|
+
case RbConfig::CONFIG['host_os']
|
22
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
23
|
+
{ os: :windows, lib_pattern: 'nng*.dll', lib_name: 'nng.dll' }
|
24
|
+
when /darwin|mac os/
|
25
|
+
{ os: :macos, lib_pattern: 'libnng*.dylib', lib_name: 'libnng.dylib' }
|
26
|
+
else
|
27
|
+
{ os: :linux, lib_pattern: 'libnng.so*', lib_name: 'libnng.so' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Build library search paths with priority order:
|
32
|
+
# 1. ENV['NNG_LIB_PATH'] - Direct path to library file
|
33
|
+
# 2. ENV['NNG_LIB_DIR'] - Directory containing library
|
34
|
+
# 3. Install config (from gem install --with-nng-*)
|
35
|
+
# 4. Bundled library
|
36
|
+
# 5. System default paths
|
37
|
+
def self.build_lib_paths
|
38
|
+
paths = []
|
39
|
+
platform = platform_info
|
40
|
+
|
41
|
+
# Priority 1: Direct library path from environment
|
42
|
+
if ENV['NNG_LIB_PATH'] && !ENV['NNG_LIB_PATH'].empty?
|
43
|
+
paths << ENV['NNG_LIB_PATH']
|
44
|
+
puts "NNG: Using library from NNG_LIB_PATH: #{ENV['NNG_LIB_PATH']}" if ENV['NNG_DEBUG']
|
45
|
+
end
|
46
|
+
|
47
|
+
# Priority 2: Library directory from environment
|
48
|
+
if ENV['NNG_LIB_DIR'] && !ENV['NNG_LIB_DIR'].empty?
|
49
|
+
dir = ENV['NNG_LIB_DIR']
|
50
|
+
# Search for platform-specific library files in the directory
|
51
|
+
Dir.glob(File.join(dir, platform[:lib_pattern])).each { |lib| paths << lib }
|
52
|
+
puts "NNG: Searching in NNG_LIB_DIR: #{dir}" if ENV['NNG_DEBUG']
|
53
|
+
end
|
54
|
+
|
55
|
+
# Priority 3: Install-time configuration
|
56
|
+
if @install_config[:nng_lib]
|
57
|
+
paths << @install_config[:nng_lib]
|
58
|
+
puts "NNG: Using library from install config: #{@install_config[:nng_lib]}" if ENV['NNG_DEBUG']
|
59
|
+
elsif @install_config[:nng_dir]
|
60
|
+
nng_dir = @install_config[:nng_dir]
|
61
|
+
# Try common subdirectories based on platform
|
62
|
+
subdirs = case platform[:os]
|
63
|
+
when :windows
|
64
|
+
%w[bin lib]
|
65
|
+
when :macos
|
66
|
+
%w[lib]
|
67
|
+
else
|
68
|
+
%w[lib lib64 lib/x86_64-linux-gnu]
|
69
|
+
end
|
70
|
+
|
71
|
+
subdirs.each do |subdir|
|
72
|
+
lib_dir = File.join(nng_dir, subdir)
|
73
|
+
Dir.glob(File.join(lib_dir, platform[:lib_pattern])).each { |lib| paths << lib }
|
74
|
+
end
|
75
|
+
puts "NNG: Searching in install config dir: #{nng_dir}" if ENV['NNG_DEBUG']
|
76
|
+
end
|
77
|
+
|
78
|
+
# Priority 4: Bundled library (platform-specific)
|
79
|
+
bundled_libs = case platform[:os]
|
80
|
+
when :windows
|
81
|
+
[
|
82
|
+
File.expand_path('../../ext/nng/nng.dll', __dir__),
|
83
|
+
File.expand_path('../../ext/nng/libnng.dll', __dir__)
|
84
|
+
]
|
85
|
+
when :macos
|
86
|
+
[
|
87
|
+
File.expand_path('../../ext/nng/libnng.1.11.0.dylib', __dir__),
|
88
|
+
File.expand_path('../../ext/nng/libnng.dylib', __dir__)
|
89
|
+
]
|
90
|
+
else
|
91
|
+
[
|
92
|
+
File.expand_path('../../ext/nng/libnng.so.1.11.0', __dir__),
|
93
|
+
File.expand_path('../../ext/nng/libnng.so', __dir__)
|
94
|
+
]
|
95
|
+
end
|
96
|
+
paths += bundled_libs
|
97
|
+
|
98
|
+
# Priority 5: System default paths (platform-specific)
|
99
|
+
case platform[:os]
|
100
|
+
when :windows
|
101
|
+
# Windows: check common DLL locations
|
102
|
+
paths += [
|
103
|
+
File.join(ENV['WINDIR'] || 'C:/Windows', 'System32/nng.dll'),
|
104
|
+
File.join(ENV['ProgramFiles'] || 'C:/Program Files', 'nng/bin/nng.dll')
|
105
|
+
]
|
106
|
+
when :macos
|
107
|
+
# macOS: check common library locations
|
108
|
+
paths += [
|
109
|
+
'/usr/local/lib/libnng.dylib',
|
110
|
+
'/opt/homebrew/lib/libnng.dylib',
|
111
|
+
'/usr/lib/libnng.dylib'
|
112
|
+
]
|
113
|
+
else
|
114
|
+
# Linux: check common library locations
|
115
|
+
paths += [
|
116
|
+
'/usr/local/lib/libnng.so',
|
117
|
+
'/usr/lib/libnng.so',
|
118
|
+
'/usr/lib/x86_64-linux-gnu/libnng.so',
|
119
|
+
'/usr/lib/aarch64-linux-gnu/libnng.so'
|
120
|
+
]
|
121
|
+
end
|
122
|
+
|
123
|
+
paths.uniq
|
124
|
+
end
|
125
|
+
|
126
|
+
@lib_paths = build_lib_paths
|
127
|
+
@loaded_lib_path = nil
|
128
|
+
|
129
|
+
@lib_paths.each do |path|
|
130
|
+
if File.exist?(path)
|
131
|
+
begin
|
132
|
+
ffi_lib path
|
133
|
+
@loaded_lib_path = path
|
134
|
+
puts "NNG: Successfully loaded library from: #{path}" if ENV['NNG_DEBUG']
|
135
|
+
break
|
136
|
+
rescue LoadError => e
|
137
|
+
puts "NNG: Failed to load #{path}: #{e.message}" if ENV['NNG_DEBUG']
|
138
|
+
next
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
unless @loaded_lib_path
|
144
|
+
platform = platform_info
|
145
|
+
lib_name = platform[:lib_name]
|
146
|
+
error_msg = "Could not find NNG library (#{lib_name}) in any of the following locations:\n"
|
147
|
+
error_msg += @lib_paths.map { |p| " - #{p}" }.join("\n")
|
148
|
+
error_msg += "\n\nYou can specify a custom path using:\n"
|
149
|
+
error_msg += " - Environment variable: export NNG_LIB_PATH=/path/to/#{lib_name}\n"
|
150
|
+
error_msg += " - Environment variable: export NNG_LIB_DIR=/path/to/lib\n"
|
151
|
+
error_msg += " - Gem install option: gem install nng-ruby -- --with-nng-dir=/path/to/nng\n"
|
152
|
+
error_msg += " - Gem install option: gem install nng-ruby -- --with-nng-lib=/path/to/#{lib_name}"
|
153
|
+
raise LoadError, error_msg
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.loaded_lib_path
|
157
|
+
@loaded_lib_path
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.install_config
|
161
|
+
@install_config
|
162
|
+
end
|
163
|
+
|
164
|
+
# ============================================================================
|
165
|
+
# Constants
|
166
|
+
# ============================================================================
|
167
|
+
|
168
|
+
# NOTE: These are compile-time version constants for reference.
|
169
|
+
# Use nng_version() to get the actual runtime library version.
|
170
|
+
NNG_MAJOR_VERSION = 1
|
171
|
+
NNG_MINOR_VERSION = 8
|
172
|
+
NNG_PATCH_VERSION = 0
|
173
|
+
|
174
|
+
# Maximum address length
|
175
|
+
NNG_MAXADDRLEN = 128
|
176
|
+
|
177
|
+
# Error codes
|
178
|
+
NNG_OK = 0
|
179
|
+
NNG_EINTR = 1
|
180
|
+
NNG_ENOMEM = 2
|
181
|
+
NNG_EINVAL = 3
|
182
|
+
NNG_EBUSY = 4
|
183
|
+
NNG_ETIMEDOUT = 5
|
184
|
+
NNG_ECONNREFUSED = 6
|
185
|
+
NNG_ECLOSED = 7
|
186
|
+
NNG_EAGAIN = 8
|
187
|
+
NNG_ENOTSUP = 9
|
188
|
+
NNG_EADDRINUSE = 10
|
189
|
+
NNG_ESTATE = 11
|
190
|
+
NNG_ENOENT = 12
|
191
|
+
NNG_EPROTO = 13
|
192
|
+
NNG_EUNREACHABLE = 14
|
193
|
+
NNG_EADDRINVAL = 15
|
194
|
+
NNG_EPERM = 16
|
195
|
+
NNG_EMSGSIZE = 17
|
196
|
+
NNG_ECONNABORTED = 18
|
197
|
+
NNG_ECONNRESET = 19
|
198
|
+
NNG_ECANCELED = 20
|
199
|
+
NNG_ENOFILES = 21
|
200
|
+
NNG_ENOSPC = 22
|
201
|
+
NNG_EEXIST = 23
|
202
|
+
NNG_EREADONLY = 24
|
203
|
+
NNG_EWRITEONLY = 25
|
204
|
+
NNG_ECRYPTO = 26
|
205
|
+
NNG_EPEERAUTH = 27
|
206
|
+
NNG_ENOARG = 28
|
207
|
+
NNG_EAMBIGUOUS = 29
|
208
|
+
NNG_EBADTYPE = 30
|
209
|
+
NNG_ECONNSHUT = 31
|
210
|
+
NNG_EINTERNAL = 1000
|
211
|
+
|
212
|
+
# Flags
|
213
|
+
NNG_FLAG_ALLOC = 1 # Allocate receive buffer
|
214
|
+
NNG_FLAG_NONBLOCK = 2 # Non-blocking mode
|
215
|
+
|
216
|
+
# Socket address families
|
217
|
+
NNG_AF_UNSPEC = 0
|
218
|
+
NNG_AF_INPROC = 1
|
219
|
+
NNG_AF_IPC = 2
|
220
|
+
NNG_AF_INET = 3
|
221
|
+
NNG_AF_INET6 = 4
|
222
|
+
NNG_AF_ZT = 5
|
223
|
+
NNG_AF_ABSTRACT = 6
|
224
|
+
|
225
|
+
# Pipe events
|
226
|
+
NNG_PIPE_EV_ADD_PRE = 0
|
227
|
+
NNG_PIPE_EV_ADD_POST = 1
|
228
|
+
NNG_PIPE_EV_REM_POST = 2
|
229
|
+
NNG_PIPE_EV_NUM = 3
|
230
|
+
|
231
|
+
# ============================================================================
|
232
|
+
# Type definitions
|
233
|
+
# ============================================================================
|
234
|
+
|
235
|
+
# nng_socket structure
|
236
|
+
class NngSocket < ::FFI::Struct
|
237
|
+
layout :id, :uint32
|
238
|
+
end
|
239
|
+
|
240
|
+
# nng_dialer structure
|
241
|
+
class NngDialer < ::FFI::Struct
|
242
|
+
layout :id, :uint32
|
243
|
+
end
|
244
|
+
|
245
|
+
# nng_listener structure
|
246
|
+
class NngListener < ::FFI::Struct
|
247
|
+
layout :id, :uint32
|
248
|
+
end
|
249
|
+
|
250
|
+
# nng_ctx structure
|
251
|
+
class NngCtx < ::FFI::Struct
|
252
|
+
layout :id, :uint32
|
253
|
+
end
|
254
|
+
|
255
|
+
# nng_pipe structure
|
256
|
+
class NngPipe < ::FFI::Struct
|
257
|
+
layout :id, :uint32
|
258
|
+
end
|
259
|
+
|
260
|
+
# nng_duration - time interval in milliseconds
|
261
|
+
typedef :int32, :nng_duration
|
262
|
+
|
263
|
+
# nng_time - absolute time in milliseconds
|
264
|
+
typedef :uint64, :nng_time
|
265
|
+
|
266
|
+
# Opaque types
|
267
|
+
typedef :pointer, :nng_msg
|
268
|
+
typedef :pointer, :nng_aio
|
269
|
+
typedef :pointer, :nng_stat
|
270
|
+
|
271
|
+
# Socket address structures
|
272
|
+
class NngSockaddrInproc < ::FFI::Struct
|
273
|
+
layout :sa_family, :uint16,
|
274
|
+
:sa_name, [:char, NNG_MAXADDRLEN]
|
275
|
+
end
|
276
|
+
|
277
|
+
class NngSockaddrPath < ::FFI::Struct
|
278
|
+
layout :sa_family, :uint16,
|
279
|
+
:sa_path, [:char, NNG_MAXADDRLEN]
|
280
|
+
end
|
281
|
+
|
282
|
+
class NngSockaddrIn < ::FFI::Struct
|
283
|
+
layout :sa_family, :uint16,
|
284
|
+
:sa_port, :uint16,
|
285
|
+
:sa_addr, :uint32
|
286
|
+
end
|
287
|
+
|
288
|
+
class NngSockaddrIn6 < ::FFI::Struct
|
289
|
+
layout :sa_family, :uint16,
|
290
|
+
:sa_port, :uint16,
|
291
|
+
:sa_addr, [:uint8, 16],
|
292
|
+
:sa_scope, :uint32
|
293
|
+
end
|
294
|
+
|
295
|
+
class NngSockaddrStorage < ::FFI::Struct
|
296
|
+
layout :sa_family, :uint16,
|
297
|
+
:sa_pad, [:uint64, 16]
|
298
|
+
end
|
299
|
+
|
300
|
+
class NngSockaddr < ::FFI::Union
|
301
|
+
layout :s_family, :uint16,
|
302
|
+
:s_inproc, NngSockaddrInproc,
|
303
|
+
:s_ipc, NngSockaddrPath,
|
304
|
+
:s_in, NngSockaddrIn,
|
305
|
+
:s_in6, NngSockaddrIn6,
|
306
|
+
:s_storage, NngSockaddrStorage
|
307
|
+
end
|
308
|
+
|
309
|
+
# ============================================================================
|
310
|
+
# Core functions
|
311
|
+
# ============================================================================
|
312
|
+
|
313
|
+
# Library version
|
314
|
+
attach_function :nng_version, [], :string
|
315
|
+
|
316
|
+
# Library finalization
|
317
|
+
attach_function :nng_fini, [], :void
|
318
|
+
|
319
|
+
# Error handling
|
320
|
+
attach_function :nng_strerror, [:int], :string
|
321
|
+
|
322
|
+
# Socket functions
|
323
|
+
attach_function :nng_close, [NngSocket.by_value], :int
|
324
|
+
attach_function :nng_socket_id, [NngSocket.by_value], :int
|
325
|
+
|
326
|
+
# Socket options - set
|
327
|
+
attach_function :nng_setopt, [NngSocket.by_value, :string, :pointer, :size_t], :int
|
328
|
+
attach_function :nng_setopt_bool, [NngSocket.by_value, :string, :bool], :int
|
329
|
+
attach_function :nng_setopt_int, [NngSocket.by_value, :string, :int], :int
|
330
|
+
attach_function :nng_setopt_size, [NngSocket.by_value, :string, :size_t], :int
|
331
|
+
attach_function :nng_setopt_uint64, [NngSocket.by_value, :string, :uint64], :int
|
332
|
+
attach_function :nng_setopt_string, [NngSocket.by_value, :string, :string], :int
|
333
|
+
attach_function :nng_setopt_ptr, [NngSocket.by_value, :string, :pointer], :int
|
334
|
+
attach_function :nng_setopt_ms, [NngSocket.by_value, :string, :nng_duration], :int
|
335
|
+
|
336
|
+
# Socket options - get
|
337
|
+
attach_function :nng_getopt, [NngSocket.by_value, :string, :pointer, :pointer], :int
|
338
|
+
attach_function :nng_getopt_bool, [NngSocket.by_value, :string, :pointer], :int
|
339
|
+
attach_function :nng_getopt_int, [NngSocket.by_value, :string, :pointer], :int
|
340
|
+
attach_function :nng_getopt_size, [NngSocket.by_value, :string, :pointer], :int
|
341
|
+
attach_function :nng_getopt_uint64, [NngSocket.by_value, :string, :pointer], :int
|
342
|
+
attach_function :nng_getopt_string, [NngSocket.by_value, :string, :pointer], :int
|
343
|
+
attach_function :nng_getopt_ptr, [NngSocket.by_value, :string, :pointer], :int
|
344
|
+
attach_function :nng_getopt_ms, [NngSocket.by_value, :string, :pointer], :int
|
345
|
+
|
346
|
+
# Connection management
|
347
|
+
attach_function :nng_listen, [NngSocket.by_value, :string, :pointer, :int], :int
|
348
|
+
attach_function :nng_dial, [NngSocket.by_value, :string, :pointer, :int], :int
|
349
|
+
|
350
|
+
# Dialer functions
|
351
|
+
attach_function :nng_dialer_create, [:pointer, NngSocket.by_value, :string], :int
|
352
|
+
attach_function :nng_dialer_start, [NngDialer.by_value, :int], :int
|
353
|
+
attach_function :nng_dialer_close, [NngDialer.by_value], :int
|
354
|
+
attach_function :nng_dialer_id, [NngDialer.by_value], :int
|
355
|
+
|
356
|
+
# Listener functions
|
357
|
+
attach_function :nng_listener_create, [:pointer, NngSocket.by_value, :string], :int
|
358
|
+
attach_function :nng_listener_start, [NngListener.by_value, :int], :int
|
359
|
+
attach_function :nng_listener_close, [NngListener.by_value], :int
|
360
|
+
attach_function :nng_listener_id, [NngListener.by_value], :int
|
361
|
+
|
362
|
+
# Send and receive (synchronous)
|
363
|
+
attach_function :nng_send, [NngSocket.by_value, :pointer, :size_t, :int], :int
|
364
|
+
attach_function :nng_recv, [NngSocket.by_value, :pointer, :pointer, :int], :int
|
365
|
+
|
366
|
+
# Message-based send/receive
|
367
|
+
attach_function :nng_sendmsg, [NngSocket.by_value, :nng_msg, :int], :int
|
368
|
+
attach_function :nng_recvmsg, [NngSocket.by_value, :pointer, :int], :int
|
369
|
+
|
370
|
+
# Memory management
|
371
|
+
attach_function :nng_free, [:pointer, :size_t], :void
|
372
|
+
attach_function :nng_strfree, [:pointer], :void
|
373
|
+
|
374
|
+
# Message functions
|
375
|
+
attach_function :nng_msg_alloc, [:pointer, :size_t], :int
|
376
|
+
attach_function :nng_msg_free, [:nng_msg], :void
|
377
|
+
attach_function :nng_msg_realloc, [:nng_msg, :size_t], :int
|
378
|
+
attach_function :nng_msg_header, [:nng_msg], :pointer
|
379
|
+
attach_function :nng_msg_header_len, [:nng_msg], :size_t
|
380
|
+
attach_function :nng_msg_body, [:nng_msg], :pointer
|
381
|
+
attach_function :nng_msg_len, [:nng_msg], :size_t
|
382
|
+
attach_function :nng_msg_append, [:nng_msg, :pointer, :size_t], :int
|
383
|
+
attach_function :nng_msg_insert, [:nng_msg, :pointer, :size_t], :int
|
384
|
+
attach_function :nng_msg_trim, [:nng_msg, :size_t], :int
|
385
|
+
attach_function :nng_msg_chop, [:nng_msg, :size_t], :int
|
386
|
+
attach_function :nng_msg_header_append, [:nng_msg, :pointer, :size_t], :int
|
387
|
+
attach_function :nng_msg_header_insert, [:nng_msg, :pointer, :size_t], :int
|
388
|
+
attach_function :nng_msg_header_trim, [:nng_msg, :size_t], :int
|
389
|
+
attach_function :nng_msg_header_chop, [:nng_msg, :size_t], :int
|
390
|
+
attach_function :nng_msg_clear, [:nng_msg], :void
|
391
|
+
attach_function :nng_msg_header_clear, [:nng_msg], :void
|
392
|
+
attach_function :nng_msg_dup, [:pointer, :nng_msg], :int
|
393
|
+
attach_function :nng_msg_get_pipe, [:nng_msg], NngPipe.by_value
|
394
|
+
attach_function :nng_msg_set_pipe, [:nng_msg, NngPipe.by_value], :void
|
395
|
+
|
396
|
+
# Context functions
|
397
|
+
attach_function :nng_ctx_open, [:pointer, NngSocket.by_value], :int
|
398
|
+
attach_function :nng_ctx_close, [NngCtx.by_value], :int
|
399
|
+
attach_function :nng_ctx_id, [NngCtx.by_value], :int
|
400
|
+
attach_function :nng_ctx_send, [NngCtx.by_value, :nng_aio], :void
|
401
|
+
attach_function :nng_ctx_recv, [NngCtx.by_value, :nng_aio], :void
|
402
|
+
attach_function :nng_ctx_sendmsg, [NngCtx.by_value, :nng_msg, :int], :int
|
403
|
+
attach_function :nng_ctx_recvmsg, [NngCtx.by_value, :pointer, :int], :int
|
404
|
+
|
405
|
+
# Pipe functions
|
406
|
+
attach_function :nng_pipe_id, [NngPipe.by_value], :int
|
407
|
+
attach_function :nng_pipe_socket, [NngPipe.by_value], NngSocket.by_value
|
408
|
+
attach_function :nng_pipe_dialer, [NngPipe.by_value], NngDialer.by_value
|
409
|
+
attach_function :nng_pipe_listener, [NngPipe.by_value], NngListener.by_value
|
410
|
+
attach_function :nng_pipe_close, [NngPipe.by_value], :int
|
411
|
+
|
412
|
+
# Asynchronous I/O functions
|
413
|
+
attach_function :nng_aio_alloc, [:pointer, :pointer, :pointer], :int
|
414
|
+
attach_function :nng_aio_free, [:nng_aio], :void
|
415
|
+
attach_function :nng_aio_stop, [:nng_aio], :void
|
416
|
+
attach_function :nng_aio_result, [:nng_aio], :int
|
417
|
+
attach_function :nng_aio_count, [:nng_aio], :size_t
|
418
|
+
attach_function :nng_aio_cancel, [:nng_aio], :void
|
419
|
+
attach_function :nng_aio_abort, [:nng_aio, :int], :void
|
420
|
+
attach_function :nng_aio_wait, [:nng_aio], :void
|
421
|
+
attach_function :nng_aio_set_msg, [:nng_aio, :nng_msg], :void
|
422
|
+
attach_function :nng_aio_get_msg, [:nng_aio], :nng_msg
|
423
|
+
attach_function :nng_aio_set_input, [:nng_aio, :uint, :pointer], :int
|
424
|
+
attach_function :nng_aio_set_output, [:nng_aio, :uint, :pointer], :int
|
425
|
+
attach_function :nng_aio_set_timeout, [:nng_aio, :nng_duration], :void
|
426
|
+
attach_function :nng_aio_set_iov, [:nng_aio, :uint, :pointer], :int
|
427
|
+
attach_function :nng_aio_begin, [:nng_aio], :bool
|
428
|
+
attach_function :nng_aio_finish, [:nng_aio, :int], :void
|
429
|
+
attach_function :nng_aio_defer, [:nng_aio, :pointer, :pointer], :void
|
430
|
+
|
431
|
+
# Asynchronous send/receive
|
432
|
+
attach_function :nng_send_aio, [NngSocket.by_value, :nng_aio], :void
|
433
|
+
attach_function :nng_recv_aio, [NngSocket.by_value, :nng_aio], :void
|
434
|
+
|
435
|
+
# Statistics functions
|
436
|
+
attach_function :nng_stats_get, [:pointer], :int
|
437
|
+
attach_function :nng_stats_free, [:nng_stat], :void
|
438
|
+
attach_function :nng_stats_dump, [:nng_stat], :void
|
439
|
+
attach_function :nng_stat_next, [:nng_stat], :nng_stat
|
440
|
+
attach_function :nng_stat_child, [:nng_stat], :nng_stat
|
441
|
+
attach_function :nng_stat_name, [:nng_stat], :string
|
442
|
+
attach_function :nng_stat_type, [:nng_stat], :int
|
443
|
+
attach_function :nng_stat_unit, [:nng_stat], :int
|
444
|
+
attach_function :nng_stat_value, [:nng_stat], :uint64
|
445
|
+
attach_function :nng_stat_desc, [:nng_stat], :string
|
446
|
+
|
447
|
+
# Device functions (forwarder/reflector)
|
448
|
+
attach_function :nng_device, [NngSocket.by_value, NngSocket.by_value], :int
|
449
|
+
|
450
|
+
# Utility functions
|
451
|
+
attach_function :nng_sleep_aio, [:nng_duration, :nng_aio], :void
|
452
|
+
attach_function :nng_msleep, [:nng_duration], :void
|
453
|
+
|
454
|
+
# URL parsing
|
455
|
+
typedef :pointer, :nng_url
|
456
|
+
attach_function :nng_url_parse, [:pointer, :string], :int
|
457
|
+
attach_function :nng_url_free, [:nng_url], :void
|
458
|
+
attach_function :nng_url_clone, [:pointer, :nng_url], :int
|
459
|
+
|
460
|
+
# ============================================================================
|
461
|
+
# Protocol-specific functions (will be attached when protocol is loaded)
|
462
|
+
# ============================================================================
|
463
|
+
|
464
|
+
# These will be attached by specific protocol modules:
|
465
|
+
# - nng_pair0_open, nng_pair1_open
|
466
|
+
# - nng_push0_open, nng_pull0_open
|
467
|
+
# - nng_pub0_open, nng_sub0_open
|
468
|
+
# - nng_req0_open, nng_rep0_open
|
469
|
+
# - nng_surveyor0_open, nng_respondent0_open
|
470
|
+
# - nng_bus0_open
|
471
|
+
|
472
|
+
# ============================================================================
|
473
|
+
# Helper methods
|
474
|
+
# ============================================================================
|
475
|
+
|
476
|
+
# Check error code and raise exception if not OK
|
477
|
+
def self.check_error(ret, operation = "NNG operation")
|
478
|
+
return if ret == NNG_OK
|
479
|
+
error_msg = nng_strerror(ret)
|
480
|
+
raise NNG::Error, "#{operation} failed: #{error_msg} (code: #{ret})"
|
481
|
+
end
|
482
|
+
|
483
|
+
# Create initialized socket
|
484
|
+
def self.socket_initializer
|
485
|
+
NngSocket.new.tap { |s| s[:id] = 0 }
|
486
|
+
end
|
487
|
+
|
488
|
+
# Create initialized dialer
|
489
|
+
def self.dialer_initializer
|
490
|
+
NngDialer.new.tap { |d| d[:id] = 0 }
|
491
|
+
end
|
492
|
+
|
493
|
+
# Create initialized listener
|
494
|
+
def self.listener_initializer
|
495
|
+
NngListener.new.tap { |l| l[:id] = 0 }
|
496
|
+
end
|
497
|
+
|
498
|
+
# Create initialized context
|
499
|
+
def self.ctx_initializer
|
500
|
+
NngCtx.new.tap { |c| c[:id] = 0 }
|
501
|
+
end
|
502
|
+
|
503
|
+
# Create initialized pipe
|
504
|
+
def self.pipe_initializer
|
505
|
+
NngPipe.new.tap { |p| p[:id] = 0 }
|
506
|
+
end
|
507
|
+
end
|
508
|
+
end
|