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/examples/protobuf_simple.rb
CHANGED
@@ -1,191 +1,191 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# NNG + Protocol Buffers 简单示例
|
5
|
-
# 演示如何在 NNG 通信中使用 Protobuf 序列化
|
6
|
-
|
7
|
-
require 'nng'
|
8
|
-
require 'google/protobuf'
|
9
|
-
|
10
|
-
puts "=" * 70
|
11
|
-
puts "NNG + Protocol Buffers 简单示例"
|
12
|
-
puts "=" * 70
|
13
|
-
puts
|
14
|
-
|
15
|
-
# ============================================================================
|
16
|
-
# 1. 定义 Protobuf 消息格式
|
17
|
-
# ============================================================================
|
18
|
-
|
19
|
-
puts "步骤 1: 定义 Protobuf 消息"
|
20
|
-
puts "-" * 70
|
21
|
-
|
22
|
-
# 定义请求消息
|
23
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
24
|
-
add_file("request.proto", syntax: :proto3) do
|
25
|
-
add_message "Request" do
|
26
|
-
optional :id, :int32, 1
|
27
|
-
optional :rpc_method, :string, 2
|
28
|
-
optional :params, :string, 3
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# 定义响应消息
|
34
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
35
|
-
add_file("response.proto", syntax: :proto3) do
|
36
|
-
add_message "Response" do
|
37
|
-
optional :id, :int32, 1
|
38
|
-
optional :status, :int32, 2
|
39
|
-
optional :message, :string, 3
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
Request = Google::Protobuf::DescriptorPool.generated_pool.lookup("Request").msgclass
|
45
|
-
Response = Google::Protobuf::DescriptorPool.generated_pool.lookup("Response").msgclass
|
46
|
-
|
47
|
-
puts "✅ Protobuf 消息定义完成"
|
48
|
-
puts
|
49
|
-
|
50
|
-
# ============================================================================
|
51
|
-
# 2. 序列化和反序列化测试
|
52
|
-
# ============================================================================
|
53
|
-
|
54
|
-
puts "步骤 2: 测试 Protobuf 序列化"
|
55
|
-
puts "-" * 70
|
56
|
-
|
57
|
-
# 创建请求对象
|
58
|
-
request = Request.new(
|
59
|
-
id: 12345,
|
60
|
-
rpc_method: "getUserInfo",
|
61
|
-
params: '{"user_id": 888}'
|
62
|
-
)
|
63
|
-
|
64
|
-
puts "原始请求对象:"
|
65
|
-
puts " ID: #{request.id}"
|
66
|
-
puts " Method: #{request.rpc_method}"
|
67
|
-
puts " Params: #{request.params}"
|
68
|
-
puts
|
69
|
-
|
70
|
-
# 序列化为二进制
|
71
|
-
binary_data = Request.encode(request)
|
72
|
-
puts "序列化结果:"
|
73
|
-
puts " 大小: #{binary_data.bytesize} bytes"
|
74
|
-
puts " 十六进制: #{binary_data.unpack('H*').first}"
|
75
|
-
puts
|
76
|
-
|
77
|
-
# 反序列化
|
78
|
-
decoded_request = Request.decode(binary_data)
|
79
|
-
puts "反序列化结果:"
|
80
|
-
puts " ID: #{decoded_request.id}"
|
81
|
-
puts " Method: #{decoded_request.rpc_method}"
|
82
|
-
puts " Params: #{decoded_request.params}"
|
83
|
-
puts
|
84
|
-
|
85
|
-
# ============================================================================
|
86
|
-
# 3. 使用进程模拟客户端-服务器通信
|
87
|
-
# ============================================================================
|
88
|
-
|
89
|
-
puts "步骤 3: NNG + Protobuf 通信演示"
|
90
|
-
puts "-" * 70
|
91
|
-
|
92
|
-
url = "tcp://127.0.0.1:15557"
|
93
|
-
|
94
|
-
# 创建服务器进程
|
95
|
-
server_pid = fork do
|
96
|
-
begin
|
97
|
-
server = NNG::Socket.new(:pair1)
|
98
|
-
server.listen(url)
|
99
|
-
puts "[服务器] 监听: #{url}"
|
100
|
-
|
101
|
-
# 接收请求
|
102
|
-
request_data = server.recv
|
103
|
-
puts "[服务器] 收到 #{request_data.bytesize} bytes 数据"
|
104
|
-
|
105
|
-
# 反序列化请求
|
106
|
-
request = Request.decode(request_data)
|
107
|
-
puts "[服务器] 解析请求:"
|
108
|
-
puts "[服务器] ID: #{request.id}"
|
109
|
-
puts "[服务器] Method: #{request.rpc_method}"
|
110
|
-
puts "[服务器] Params: #{request.params}"
|
111
|
-
|
112
|
-
# 创建响应
|
113
|
-
response = Response.new(
|
114
|
-
id: request.id,
|
115
|
-
status: 200,
|
116
|
-
message: "处理成功: #{request.rpc_method}"
|
117
|
-
)
|
118
|
-
|
119
|
-
# 序列化并发送
|
120
|
-
response_data = Response.encode(response)
|
121
|
-
server.send(response_data)
|
122
|
-
puts "[服务器] 发送响应 #{response_data.bytesize} bytes"
|
123
|
-
|
124
|
-
server.close
|
125
|
-
rescue => e
|
126
|
-
puts "[服务器] 错误: #{e.message}"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
# 等待服务器启动
|
131
|
-
sleep 0.5
|
132
|
-
|
133
|
-
# 客户端
|
134
|
-
begin
|
135
|
-
client = NNG::Socket.new(:pair1)
|
136
|
-
client.dial(url)
|
137
|
-
puts "[客户端] 连接: #{url}"
|
138
|
-
|
139
|
-
# 创建请求
|
140
|
-
request = Request.new(
|
141
|
-
id: 99999,
|
142
|
-
rpc_method: "getContacts",
|
143
|
-
params: '{"limit": 100}'
|
144
|
-
)
|
145
|
-
|
146
|
-
# 序列化并发送
|
147
|
-
request_data = Request.encode(request)
|
148
|
-
puts "[客户端] 发送请求 #{request_data.bytesize} bytes"
|
149
|
-
client.send(request_data)
|
150
|
-
|
151
|
-
# 接收响应
|
152
|
-
response_data = client.recv
|
153
|
-
puts "[客户端] 收到响应 #{response_data.bytesize} bytes"
|
154
|
-
|
155
|
-
# 反序列化
|
156
|
-
response = Response.decode(response_data)
|
157
|
-
puts "[客户端] 解析响应:"
|
158
|
-
puts "[客户端] ID: #{response.id}"
|
159
|
-
puts "[客户端] Status: #{response.status}"
|
160
|
-
puts "[客户端] Message: #{response.message}"
|
161
|
-
|
162
|
-
client.close
|
163
|
-
rescue => e
|
164
|
-
puts "[客户端] 错误: #{e.message}"
|
165
|
-
puts e.backtrace.first(3)
|
166
|
-
end
|
167
|
-
|
168
|
-
# 等待服务器进程结束
|
169
|
-
Process.wait(server_pid)
|
170
|
-
|
171
|
-
puts
|
172
|
-
puts "=" * 70
|
173
|
-
puts "✅ 示例完成"
|
174
|
-
puts "=" * 70
|
175
|
-
puts
|
176
|
-
puts "关键代码:"
|
177
|
-
puts
|
178
|
-
puts " # 序列化"
|
179
|
-
puts " binary_data = Request.encode(request)"
|
180
|
-
puts " socket.send(binary_data)"
|
181
|
-
puts
|
182
|
-
puts " # 反序列化"
|
183
|
-
puts " binary_data = socket.recv"
|
184
|
-
puts " request = Request.decode(binary_data)"
|
185
|
-
puts
|
186
|
-
puts "优势:"
|
187
|
-
puts " ✅ 类型安全的消息定义"
|
188
|
-
puts " ✅ 高效的二进制序列化 (~50% 比 JSON 小)"
|
189
|
-
puts " ✅ 跨语言兼容 (Python, Java, Go, C++ 等)"
|
190
|
-
puts " ✅ 向后兼容的版本演进"
|
191
|
-
puts
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# NNG + Protocol Buffers 简单示例
|
5
|
+
# 演示如何在 NNG 通信中使用 Protobuf 序列化
|
6
|
+
|
7
|
+
require 'nng'
|
8
|
+
require 'google/protobuf'
|
9
|
+
|
10
|
+
puts "=" * 70
|
11
|
+
puts "NNG + Protocol Buffers 简单示例"
|
12
|
+
puts "=" * 70
|
13
|
+
puts
|
14
|
+
|
15
|
+
# ============================================================================
|
16
|
+
# 1. 定义 Protobuf 消息格式
|
17
|
+
# ============================================================================
|
18
|
+
|
19
|
+
puts "步骤 1: 定义 Protobuf 消息"
|
20
|
+
puts "-" * 70
|
21
|
+
|
22
|
+
# 定义请求消息
|
23
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
24
|
+
add_file("request.proto", syntax: :proto3) do
|
25
|
+
add_message "Request" do
|
26
|
+
optional :id, :int32, 1
|
27
|
+
optional :rpc_method, :string, 2
|
28
|
+
optional :params, :string, 3
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# 定义响应消息
|
34
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
35
|
+
add_file("response.proto", syntax: :proto3) do
|
36
|
+
add_message "Response" do
|
37
|
+
optional :id, :int32, 1
|
38
|
+
optional :status, :int32, 2
|
39
|
+
optional :message, :string, 3
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Request = Google::Protobuf::DescriptorPool.generated_pool.lookup("Request").msgclass
|
45
|
+
Response = Google::Protobuf::DescriptorPool.generated_pool.lookup("Response").msgclass
|
46
|
+
|
47
|
+
puts "✅ Protobuf 消息定义完成"
|
48
|
+
puts
|
49
|
+
|
50
|
+
# ============================================================================
|
51
|
+
# 2. 序列化和反序列化测试
|
52
|
+
# ============================================================================
|
53
|
+
|
54
|
+
puts "步骤 2: 测试 Protobuf 序列化"
|
55
|
+
puts "-" * 70
|
56
|
+
|
57
|
+
# 创建请求对象
|
58
|
+
request = Request.new(
|
59
|
+
id: 12345,
|
60
|
+
rpc_method: "getUserInfo",
|
61
|
+
params: '{"user_id": 888}'
|
62
|
+
)
|
63
|
+
|
64
|
+
puts "原始请求对象:"
|
65
|
+
puts " ID: #{request.id}"
|
66
|
+
puts " Method: #{request.rpc_method}"
|
67
|
+
puts " Params: #{request.params}"
|
68
|
+
puts
|
69
|
+
|
70
|
+
# 序列化为二进制
|
71
|
+
binary_data = Request.encode(request)
|
72
|
+
puts "序列化结果:"
|
73
|
+
puts " 大小: #{binary_data.bytesize} bytes"
|
74
|
+
puts " 十六进制: #{binary_data.unpack('H*').first}"
|
75
|
+
puts
|
76
|
+
|
77
|
+
# 反序列化
|
78
|
+
decoded_request = Request.decode(binary_data)
|
79
|
+
puts "反序列化结果:"
|
80
|
+
puts " ID: #{decoded_request.id}"
|
81
|
+
puts " Method: #{decoded_request.rpc_method}"
|
82
|
+
puts " Params: #{decoded_request.params}"
|
83
|
+
puts
|
84
|
+
|
85
|
+
# ============================================================================
|
86
|
+
# 3. 使用进程模拟客户端-服务器通信
|
87
|
+
# ============================================================================
|
88
|
+
|
89
|
+
puts "步骤 3: NNG + Protobuf 通信演示"
|
90
|
+
puts "-" * 70
|
91
|
+
|
92
|
+
url = "tcp://127.0.0.1:15557"
|
93
|
+
|
94
|
+
# 创建服务器进程
|
95
|
+
server_pid = fork do
|
96
|
+
begin
|
97
|
+
server = NNG::Socket.new(:pair1)
|
98
|
+
server.listen(url)
|
99
|
+
puts "[服务器] 监听: #{url}"
|
100
|
+
|
101
|
+
# 接收请求
|
102
|
+
request_data = server.recv
|
103
|
+
puts "[服务器] 收到 #{request_data.bytesize} bytes 数据"
|
104
|
+
|
105
|
+
# 反序列化请求
|
106
|
+
request = Request.decode(request_data)
|
107
|
+
puts "[服务器] 解析请求:"
|
108
|
+
puts "[服务器] ID: #{request.id}"
|
109
|
+
puts "[服务器] Method: #{request.rpc_method}"
|
110
|
+
puts "[服务器] Params: #{request.params}"
|
111
|
+
|
112
|
+
# 创建响应
|
113
|
+
response = Response.new(
|
114
|
+
id: request.id,
|
115
|
+
status: 200,
|
116
|
+
message: "处理成功: #{request.rpc_method}"
|
117
|
+
)
|
118
|
+
|
119
|
+
# 序列化并发送
|
120
|
+
response_data = Response.encode(response)
|
121
|
+
server.send(response_data)
|
122
|
+
puts "[服务器] 发送响应 #{response_data.bytesize} bytes"
|
123
|
+
|
124
|
+
server.close
|
125
|
+
rescue => e
|
126
|
+
puts "[服务器] 错误: #{e.message}"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# 等待服务器启动
|
131
|
+
sleep 0.5
|
132
|
+
|
133
|
+
# 客户端
|
134
|
+
begin
|
135
|
+
client = NNG::Socket.new(:pair1)
|
136
|
+
client.dial(url)
|
137
|
+
puts "[客户端] 连接: #{url}"
|
138
|
+
|
139
|
+
# 创建请求
|
140
|
+
request = Request.new(
|
141
|
+
id: 99999,
|
142
|
+
rpc_method: "getContacts",
|
143
|
+
params: '{"limit": 100}'
|
144
|
+
)
|
145
|
+
|
146
|
+
# 序列化并发送
|
147
|
+
request_data = Request.encode(request)
|
148
|
+
puts "[客户端] 发送请求 #{request_data.bytesize} bytes"
|
149
|
+
client.send(request_data)
|
150
|
+
|
151
|
+
# 接收响应
|
152
|
+
response_data = client.recv
|
153
|
+
puts "[客户端] 收到响应 #{response_data.bytesize} bytes"
|
154
|
+
|
155
|
+
# 反序列化
|
156
|
+
response = Response.decode(response_data)
|
157
|
+
puts "[客户端] 解析响应:"
|
158
|
+
puts "[客户端] ID: #{response.id}"
|
159
|
+
puts "[客户端] Status: #{response.status}"
|
160
|
+
puts "[客户端] Message: #{response.message}"
|
161
|
+
|
162
|
+
client.close
|
163
|
+
rescue => e
|
164
|
+
puts "[客户端] 错误: #{e.message}"
|
165
|
+
puts e.backtrace.first(3)
|
166
|
+
end
|
167
|
+
|
168
|
+
# 等待服务器进程结束
|
169
|
+
Process.wait(server_pid)
|
170
|
+
|
171
|
+
puts
|
172
|
+
puts "=" * 70
|
173
|
+
puts "✅ 示例完成"
|
174
|
+
puts "=" * 70
|
175
|
+
puts
|
176
|
+
puts "关键代码:"
|
177
|
+
puts
|
178
|
+
puts " # 序列化"
|
179
|
+
puts " binary_data = Request.encode(request)"
|
180
|
+
puts " socket.send(binary_data)"
|
181
|
+
puts
|
182
|
+
puts " # 反序列化"
|
183
|
+
puts " binary_data = socket.recv"
|
184
|
+
puts " request = Request.decode(binary_data)"
|
185
|
+
puts
|
186
|
+
puts "优势:"
|
187
|
+
puts " ✅ 类型安全的消息定义"
|
188
|
+
puts " ✅ 高效的二进制序列化 (~50% 比 JSON 小)"
|
189
|
+
puts " ✅ 跨语言兼容 (Python, Java, Go, C++ 等)"
|
190
|
+
puts " ✅ 向后兼容的版本演进"
|
191
|
+
puts
|