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_thread.rb
CHANGED
@@ -1,236 +1,236 @@
|
|
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
|
-
# 定义 Protobuf 消息
|
17
|
-
# ============================================================================
|
18
|
-
|
19
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
20
|
-
add_file("rpc.proto", syntax: :proto3) do
|
21
|
-
# RPC 请求
|
22
|
-
add_message "RpcRequest" do
|
23
|
-
optional :func_code, :int32, 1
|
24
|
-
optional :data, :bytes, 2
|
25
|
-
optional :request_id, :string, 3
|
26
|
-
end
|
27
|
-
|
28
|
-
# RPC 响应
|
29
|
-
add_message "RpcResponse" do
|
30
|
-
optional :status, :int32, 1
|
31
|
-
optional :data, :bytes, 2
|
32
|
-
optional :error_msg, :string, 3
|
33
|
-
end
|
34
|
-
|
35
|
-
# 联系人
|
36
|
-
add_message "Contact" do
|
37
|
-
optional :wxid, :string, 1
|
38
|
-
optional :name, :string, 2
|
39
|
-
end
|
40
|
-
|
41
|
-
# 联系人列表
|
42
|
-
add_message "ContactList" do
|
43
|
-
repeated :contacts, :message, 1, "Contact"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
RpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcRequest").msgclass
|
49
|
-
RpcResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcResponse").msgclass
|
50
|
-
Contact = Google::Protobuf::DescriptorPool.generated_pool.lookup("Contact").msgclass
|
51
|
-
ContactList = Google::Protobuf::DescriptorPool.generated_pool.lookup("ContactList").msgclass
|
52
|
-
|
53
|
-
puts "✅ Protobuf 消息定义完成"
|
54
|
-
puts
|
55
|
-
|
56
|
-
# ============================================================================
|
57
|
-
# 示例: 获取联系人列表 (使用嵌套的 Protobuf 消息)
|
58
|
-
# ============================================================================
|
59
|
-
|
60
|
-
puts "示例: RPC 调用 - 获取联系人列表"
|
61
|
-
puts "=" * 70
|
62
|
-
puts
|
63
|
-
|
64
|
-
url = "inproc://contacts_demo" # 使用 inproc 避免端口冲突
|
65
|
-
|
66
|
-
# 创建 server socket (必须在 client 之前)
|
67
|
-
server_socket = NNG::Socket.new(:pair1)
|
68
|
-
server_socket.listen(url)
|
69
|
-
server_ready = true
|
70
|
-
puts "✅ 服务器监听: #{url}"
|
71
|
-
puts
|
72
|
-
|
73
|
-
# 服务器线程
|
74
|
-
server_thread = Thread.new do
|
75
|
-
begin
|
76
|
-
# 接收 RPC 请求
|
77
|
-
request_data = server_socket.recv
|
78
|
-
puts "📥 [服务器] 收到请求 (#{request_data.bytesize} bytes)"
|
79
|
-
|
80
|
-
# 反序列化 RPC 请求
|
81
|
-
rpc_request = RpcRequest.decode(request_data)
|
82
|
-
puts "📋 [服务器] 解析 RPC 请求:"
|
83
|
-
puts " Function Code: 0x#{rpc_request.func_code.to_s(16)}"
|
84
|
-
puts " Request ID: #{rpc_request.request_id}"
|
85
|
-
puts
|
86
|
-
|
87
|
-
# 构建联系人列表 (嵌套消息)
|
88
|
-
contacts = ContactList.new(
|
89
|
-
contacts: [
|
90
|
-
Contact.new(wxid: "wxid_001", name: "张三"),
|
91
|
-
Contact.new(wxid: "wxid_002", name: "李四"),
|
92
|
-
Contact.new(wxid: "wxid_003", name: "王五"),
|
93
|
-
Contact.new(wxid: "chatroom_001", name: "技术交流群")
|
94
|
-
]
|
95
|
-
)
|
96
|
-
|
97
|
-
puts "🏗️ [服务器] 构建联系人列表:"
|
98
|
-
puts " 联系人数量: #{contacts.contacts.size}"
|
99
|
-
contacts.contacts.each_with_index do |contact, i|
|
100
|
-
puts " #{i + 1}. #{contact.name} (#{contact.wxid})"
|
101
|
-
end
|
102
|
-
puts
|
103
|
-
|
104
|
-
# 序列化联系人列表 (内层)
|
105
|
-
contacts_data = ContactList.encode(contacts)
|
106
|
-
puts "📦 [服务器] 序列化联系人列表: #{contacts_data.bytesize} bytes"
|
107
|
-
|
108
|
-
# 构建 RPC 响应 (外层)
|
109
|
-
rpc_response = RpcResponse.new(
|
110
|
-
status: 0,
|
111
|
-
data: contacts_data,
|
112
|
-
error_msg: ""
|
113
|
-
)
|
114
|
-
|
115
|
-
# 序列化 RPC 响应
|
116
|
-
response_data = RpcResponse.encode(rpc_response)
|
117
|
-
puts "📦 [服务器] 序列化 RPC 响应: #{response_data.bytesize} bytes"
|
118
|
-
|
119
|
-
# 发送响应
|
120
|
-
server_socket.send(response_data)
|
121
|
-
puts "📤 [服务器] 响应已发送"
|
122
|
-
puts
|
123
|
-
|
124
|
-
rescue => e
|
125
|
-
puts "❌ [服务器] 错误: #{e.message}"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# 等待服务器准备好
|
130
|
-
sleep 0.1
|
131
|
-
|
132
|
-
# ============================================================================
|
133
|
-
# 客户端
|
134
|
-
# ============================================================================
|
135
|
-
|
136
|
-
puts "📞 [客户端] 发起 RPC 调用..."
|
137
|
-
puts
|
138
|
-
|
139
|
-
begin
|
140
|
-
# 创建 client socket
|
141
|
-
client_socket = NNG::Socket.new(:pair1)
|
142
|
-
client_socket.dial(url)
|
143
|
-
puts "✅ [客户端] 连接: #{url}"
|
144
|
-
puts
|
145
|
-
|
146
|
-
# 构建 RPC 请求
|
147
|
-
rpc_request = RpcRequest.new(
|
148
|
-
func_code: 0x12, # 假设 0x12 = FUNC_GET_CONTACTS
|
149
|
-
data: "", # 本例无需参数
|
150
|
-
request_id: "req_#{Time.now.to_i}"
|
151
|
-
)
|
152
|
-
|
153
|
-
puts "🏗️ [客户端] 构建 RPC 请求:"
|
154
|
-
puts " Function Code: 0x#{rpc_request.func_code.to_s(16)}"
|
155
|
-
puts " Request ID: #{rpc_request.request_id}"
|
156
|
-
puts
|
157
|
-
|
158
|
-
# 序列化并发送
|
159
|
-
request_data = RpcRequest.encode(rpc_request)
|
160
|
-
puts "📦 [客户端] 序列化请求: #{request_data.bytesize} bytes"
|
161
|
-
client_socket.send(request_data)
|
162
|
-
puts "📤 [客户端] 请求已发送"
|
163
|
-
puts
|
164
|
-
|
165
|
-
# 接收响应
|
166
|
-
response_data = client_socket.recv
|
167
|
-
puts "📥 [客户端] 收到响应 (#{response_data.bytesize} bytes)"
|
168
|
-
|
169
|
-
# 反序列化 RPC 响应 (外层)
|
170
|
-
rpc_response = RpcResponse.decode(response_data)
|
171
|
-
puts "📋 [客户端] 解析 RPC 响应:"
|
172
|
-
puts " Status: #{rpc_response.status}"
|
173
|
-
puts " Error: #{rpc_response.error_msg}" unless rpc_response.error_msg.empty?
|
174
|
-
puts
|
175
|
-
|
176
|
-
if rpc_response.status == 0
|
177
|
-
# 反序列化联系人列表 (内层)
|
178
|
-
contacts = ContactList.decode(rpc_response.data)
|
179
|
-
puts "📋 [客户端] 解析联系人列表:"
|
180
|
-
puts " 总数: #{contacts.contacts.size}"
|
181
|
-
puts
|
182
|
-
|
183
|
-
contacts.contacts.each_with_index do |contact, i|
|
184
|
-
puts " #{i + 1}. #{contact.name}"
|
185
|
-
puts " WXID: #{contact.wxid}"
|
186
|
-
end
|
187
|
-
else
|
188
|
-
puts "❌ [客户端] RPC 调用失败: #{rpc_response.error_msg}"
|
189
|
-
end
|
190
|
-
|
191
|
-
# 关闭
|
192
|
-
client_socket.close
|
193
|
-
|
194
|
-
rescue => e
|
195
|
-
puts "❌ [客户端] 错误: #{e.message}"
|
196
|
-
puts e.backtrace.first(3)
|
197
|
-
end
|
198
|
-
|
199
|
-
# 等待服务器线程完成
|
200
|
-
server_thread.join
|
201
|
-
server_socket.close
|
202
|
-
|
203
|
-
puts
|
204
|
-
puts "=" * 70
|
205
|
-
puts "✅ 示例完成"
|
206
|
-
puts "=" * 70
|
207
|
-
puts
|
208
|
-
puts "技术要点:"
|
209
|
-
puts
|
210
|
-
puts "1. 消息嵌套:"
|
211
|
-
puts " RpcRequest/Response 包含 bytes 类型的 data 字段"
|
212
|
-
puts " data 字段可以存储任意 Protobuf 消息的序列化结果"
|
213
|
-
puts
|
214
|
-
puts "2. 序列化过程:"
|
215
|
-
puts " 内层: contacts → ContactList.encode → bytes"
|
216
|
-
puts " 外层: RpcRequest { data: bytes } → RpcRequest.encode → bytes"
|
217
|
-
puts " 发送: bytes → NNG socket.send"
|
218
|
-
puts
|
219
|
-
puts "3. 反序列化过程:"
|
220
|
-
puts " 接收: NNG socket.recv → bytes"
|
221
|
-
puts " 外层: bytes → RpcResponse.decode → RpcResponse"
|
222
|
-
puts " 内层: RpcResponse.data → ContactList.decode → contacts"
|
223
|
-
puts
|
224
|
-
puts "4. 优势:"
|
225
|
-
puts " • 类型安全 - 编译时检查消息结构"
|
226
|
-
puts " • 高效序列化 - 比 JSON 小 50%+"
|
227
|
-
puts " • 跨语言 - Python/Java/Go/C++ 互通"
|
228
|
-
puts " • 向后兼容 - 可安全添加字段"
|
229
|
-
puts " • 自动文档 - .proto 文件即文档"
|
230
|
-
puts
|
231
|
-
puts "5. 实际应用:"
|
232
|
-
puts " • 微服务 RPC 通信"
|
233
|
-
puts " • 分布式系统消息传递"
|
234
|
-
puts " • 客户端-服务器协议"
|
235
|
-
puts " • 消息队列数据格式"
|
236
|
-
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
|
+
# 定义 Protobuf 消息
|
17
|
+
# ============================================================================
|
18
|
+
|
19
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
20
|
+
add_file("rpc.proto", syntax: :proto3) do
|
21
|
+
# RPC 请求
|
22
|
+
add_message "RpcRequest" do
|
23
|
+
optional :func_code, :int32, 1
|
24
|
+
optional :data, :bytes, 2
|
25
|
+
optional :request_id, :string, 3
|
26
|
+
end
|
27
|
+
|
28
|
+
# RPC 响应
|
29
|
+
add_message "RpcResponse" do
|
30
|
+
optional :status, :int32, 1
|
31
|
+
optional :data, :bytes, 2
|
32
|
+
optional :error_msg, :string, 3
|
33
|
+
end
|
34
|
+
|
35
|
+
# 联系人
|
36
|
+
add_message "Contact" do
|
37
|
+
optional :wxid, :string, 1
|
38
|
+
optional :name, :string, 2
|
39
|
+
end
|
40
|
+
|
41
|
+
# 联系人列表
|
42
|
+
add_message "ContactList" do
|
43
|
+
repeated :contacts, :message, 1, "Contact"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
RpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcRequest").msgclass
|
49
|
+
RpcResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcResponse").msgclass
|
50
|
+
Contact = Google::Protobuf::DescriptorPool.generated_pool.lookup("Contact").msgclass
|
51
|
+
ContactList = Google::Protobuf::DescriptorPool.generated_pool.lookup("ContactList").msgclass
|
52
|
+
|
53
|
+
puts "✅ Protobuf 消息定义完成"
|
54
|
+
puts
|
55
|
+
|
56
|
+
# ============================================================================
|
57
|
+
# 示例: 获取联系人列表 (使用嵌套的 Protobuf 消息)
|
58
|
+
# ============================================================================
|
59
|
+
|
60
|
+
puts "示例: RPC 调用 - 获取联系人列表"
|
61
|
+
puts "=" * 70
|
62
|
+
puts
|
63
|
+
|
64
|
+
url = "inproc://contacts_demo" # 使用 inproc 避免端口冲突
|
65
|
+
|
66
|
+
# 创建 server socket (必须在 client 之前)
|
67
|
+
server_socket = NNG::Socket.new(:pair1)
|
68
|
+
server_socket.listen(url)
|
69
|
+
server_ready = true
|
70
|
+
puts "✅ 服务器监听: #{url}"
|
71
|
+
puts
|
72
|
+
|
73
|
+
# 服务器线程
|
74
|
+
server_thread = Thread.new do
|
75
|
+
begin
|
76
|
+
# 接收 RPC 请求
|
77
|
+
request_data = server_socket.recv
|
78
|
+
puts "📥 [服务器] 收到请求 (#{request_data.bytesize} bytes)"
|
79
|
+
|
80
|
+
# 反序列化 RPC 请求
|
81
|
+
rpc_request = RpcRequest.decode(request_data)
|
82
|
+
puts "📋 [服务器] 解析 RPC 请求:"
|
83
|
+
puts " Function Code: 0x#{rpc_request.func_code.to_s(16)}"
|
84
|
+
puts " Request ID: #{rpc_request.request_id}"
|
85
|
+
puts
|
86
|
+
|
87
|
+
# 构建联系人列表 (嵌套消息)
|
88
|
+
contacts = ContactList.new(
|
89
|
+
contacts: [
|
90
|
+
Contact.new(wxid: "wxid_001", name: "张三"),
|
91
|
+
Contact.new(wxid: "wxid_002", name: "李四"),
|
92
|
+
Contact.new(wxid: "wxid_003", name: "王五"),
|
93
|
+
Contact.new(wxid: "chatroom_001", name: "技术交流群")
|
94
|
+
]
|
95
|
+
)
|
96
|
+
|
97
|
+
puts "🏗️ [服务器] 构建联系人列表:"
|
98
|
+
puts " 联系人数量: #{contacts.contacts.size}"
|
99
|
+
contacts.contacts.each_with_index do |contact, i|
|
100
|
+
puts " #{i + 1}. #{contact.name} (#{contact.wxid})"
|
101
|
+
end
|
102
|
+
puts
|
103
|
+
|
104
|
+
# 序列化联系人列表 (内层)
|
105
|
+
contacts_data = ContactList.encode(contacts)
|
106
|
+
puts "📦 [服务器] 序列化联系人列表: #{contacts_data.bytesize} bytes"
|
107
|
+
|
108
|
+
# 构建 RPC 响应 (外层)
|
109
|
+
rpc_response = RpcResponse.new(
|
110
|
+
status: 0,
|
111
|
+
data: contacts_data,
|
112
|
+
error_msg: ""
|
113
|
+
)
|
114
|
+
|
115
|
+
# 序列化 RPC 响应
|
116
|
+
response_data = RpcResponse.encode(rpc_response)
|
117
|
+
puts "📦 [服务器] 序列化 RPC 响应: #{response_data.bytesize} bytes"
|
118
|
+
|
119
|
+
# 发送响应
|
120
|
+
server_socket.send(response_data)
|
121
|
+
puts "📤 [服务器] 响应已发送"
|
122
|
+
puts
|
123
|
+
|
124
|
+
rescue => e
|
125
|
+
puts "❌ [服务器] 错误: #{e.message}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# 等待服务器准备好
|
130
|
+
sleep 0.1
|
131
|
+
|
132
|
+
# ============================================================================
|
133
|
+
# 客户端
|
134
|
+
# ============================================================================
|
135
|
+
|
136
|
+
puts "📞 [客户端] 发起 RPC 调用..."
|
137
|
+
puts
|
138
|
+
|
139
|
+
begin
|
140
|
+
# 创建 client socket
|
141
|
+
client_socket = NNG::Socket.new(:pair1)
|
142
|
+
client_socket.dial(url)
|
143
|
+
puts "✅ [客户端] 连接: #{url}"
|
144
|
+
puts
|
145
|
+
|
146
|
+
# 构建 RPC 请求
|
147
|
+
rpc_request = RpcRequest.new(
|
148
|
+
func_code: 0x12, # 假设 0x12 = FUNC_GET_CONTACTS
|
149
|
+
data: "", # 本例无需参数
|
150
|
+
request_id: "req_#{Time.now.to_i}"
|
151
|
+
)
|
152
|
+
|
153
|
+
puts "🏗️ [客户端] 构建 RPC 请求:"
|
154
|
+
puts " Function Code: 0x#{rpc_request.func_code.to_s(16)}"
|
155
|
+
puts " Request ID: #{rpc_request.request_id}"
|
156
|
+
puts
|
157
|
+
|
158
|
+
# 序列化并发送
|
159
|
+
request_data = RpcRequest.encode(rpc_request)
|
160
|
+
puts "📦 [客户端] 序列化请求: #{request_data.bytesize} bytes"
|
161
|
+
client_socket.send(request_data)
|
162
|
+
puts "📤 [客户端] 请求已发送"
|
163
|
+
puts
|
164
|
+
|
165
|
+
# 接收响应
|
166
|
+
response_data = client_socket.recv
|
167
|
+
puts "📥 [客户端] 收到响应 (#{response_data.bytesize} bytes)"
|
168
|
+
|
169
|
+
# 反序列化 RPC 响应 (外层)
|
170
|
+
rpc_response = RpcResponse.decode(response_data)
|
171
|
+
puts "📋 [客户端] 解析 RPC 响应:"
|
172
|
+
puts " Status: #{rpc_response.status}"
|
173
|
+
puts " Error: #{rpc_response.error_msg}" unless rpc_response.error_msg.empty?
|
174
|
+
puts
|
175
|
+
|
176
|
+
if rpc_response.status == 0
|
177
|
+
# 反序列化联系人列表 (内层)
|
178
|
+
contacts = ContactList.decode(rpc_response.data)
|
179
|
+
puts "📋 [客户端] 解析联系人列表:"
|
180
|
+
puts " 总数: #{contacts.contacts.size}"
|
181
|
+
puts
|
182
|
+
|
183
|
+
contacts.contacts.each_with_index do |contact, i|
|
184
|
+
puts " #{i + 1}. #{contact.name}"
|
185
|
+
puts " WXID: #{contact.wxid}"
|
186
|
+
end
|
187
|
+
else
|
188
|
+
puts "❌ [客户端] RPC 调用失败: #{rpc_response.error_msg}"
|
189
|
+
end
|
190
|
+
|
191
|
+
# 关闭
|
192
|
+
client_socket.close
|
193
|
+
|
194
|
+
rescue => e
|
195
|
+
puts "❌ [客户端] 错误: #{e.message}"
|
196
|
+
puts e.backtrace.first(3)
|
197
|
+
end
|
198
|
+
|
199
|
+
# 等待服务器线程完成
|
200
|
+
server_thread.join
|
201
|
+
server_socket.close
|
202
|
+
|
203
|
+
puts
|
204
|
+
puts "=" * 70
|
205
|
+
puts "✅ 示例完成"
|
206
|
+
puts "=" * 70
|
207
|
+
puts
|
208
|
+
puts "技术要点:"
|
209
|
+
puts
|
210
|
+
puts "1. 消息嵌套:"
|
211
|
+
puts " RpcRequest/Response 包含 bytes 类型的 data 字段"
|
212
|
+
puts " data 字段可以存储任意 Protobuf 消息的序列化结果"
|
213
|
+
puts
|
214
|
+
puts "2. 序列化过程:"
|
215
|
+
puts " 内层: contacts → ContactList.encode → bytes"
|
216
|
+
puts " 外层: RpcRequest { data: bytes } → RpcRequest.encode → bytes"
|
217
|
+
puts " 发送: bytes → NNG socket.send"
|
218
|
+
puts
|
219
|
+
puts "3. 反序列化过程:"
|
220
|
+
puts " 接收: NNG socket.recv → bytes"
|
221
|
+
puts " 外层: bytes → RpcResponse.decode → RpcResponse"
|
222
|
+
puts " 内层: RpcResponse.data → ContactList.decode → contacts"
|
223
|
+
puts
|
224
|
+
puts "4. 优势:"
|
225
|
+
puts " • 类型安全 - 编译时检查消息结构"
|
226
|
+
puts " • 高效序列化 - 比 JSON 小 50%+"
|
227
|
+
puts " • 跨语言 - Python/Java/Go/C++ 互通"
|
228
|
+
puts " • 向后兼容 - 可安全添加字段"
|
229
|
+
puts " • 自动文档 - .proto 文件即文档"
|
230
|
+
puts
|
231
|
+
puts "5. 实际应用:"
|
232
|
+
puts " • 微服务 RPC 通信"
|
233
|
+
puts " • 分布式系统消息传递"
|
234
|
+
puts " • 客户端-服务器协议"
|
235
|
+
puts " • 消息队列数据格式"
|
236
|
+
puts
|
data/examples/pubsub.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative '../lib/nng'
|
5
|
-
|
6
|
-
# Example: Publish/Subscribe protocol
|
7
|
-
|
8
|
-
puts "NNG Publish/Subscribe Protocol Example"
|
9
|
-
puts "=" * 50
|
10
|
-
|
11
|
-
# Create publisher socket
|
12
|
-
pub = NNG::Socket.new(:pub)
|
13
|
-
pub.listen("tcp://127.0.0.1:5557")
|
14
|
-
puts "Publisher listening on tcp://127.0.0.1:5557"
|
15
|
-
|
16
|
-
# Create subscribers in threads
|
17
|
-
sub_threads = 3.times.map do |i|
|
18
|
-
Thread.new do
|
19
|
-
sleep 0.5 # Give publisher time to start
|
20
|
-
sub = NNG::Socket.new(:sub)
|
21
|
-
sub.dial("tcp://127.0.0.1:5557")
|
22
|
-
sub.set_option("sub:subscribe", "") # Subscribe to all topics
|
23
|
-
puts "Subscriber #{i + 1} connected"
|
24
|
-
|
25
|
-
# Receive 5 messages
|
26
|
-
5.times do
|
27
|
-
msg = sub.recv
|
28
|
-
puts "Subscriber #{i + 1} received: #{msg}"
|
29
|
-
end
|
30
|
-
|
31
|
-
sub.close
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Publisher sends 5 messages
|
36
|
-
sleep 1 # Give subscribers time to connect
|
37
|
-
5.times do |i|
|
38
|
-
message = "Broadcast message #{i + 1}"
|
39
|
-
pub.send(message)
|
40
|
-
puts "Publisher sent: #{message}"
|
41
|
-
sleep 0.2
|
42
|
-
end
|
43
|
-
|
44
|
-
# Wait for all subscribers
|
45
|
-
sub_threads.each(&:join)
|
46
|
-
|
47
|
-
# Cleanup
|
48
|
-
pub.close
|
49
|
-
|
50
|
-
puts "=" * 50
|
51
|
-
puts "Example completed!"
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/nng'
|
5
|
+
|
6
|
+
# Example: Publish/Subscribe protocol
|
7
|
+
|
8
|
+
puts "NNG Publish/Subscribe Protocol Example"
|
9
|
+
puts "=" * 50
|
10
|
+
|
11
|
+
# Create publisher socket
|
12
|
+
pub = NNG::Socket.new(:pub)
|
13
|
+
pub.listen("tcp://127.0.0.1:5557")
|
14
|
+
puts "Publisher listening on tcp://127.0.0.1:5557"
|
15
|
+
|
16
|
+
# Create subscribers in threads
|
17
|
+
sub_threads = 3.times.map do |i|
|
18
|
+
Thread.new do
|
19
|
+
sleep 0.5 # Give publisher time to start
|
20
|
+
sub = NNG::Socket.new(:sub)
|
21
|
+
sub.dial("tcp://127.0.0.1:5557")
|
22
|
+
sub.set_option("sub:subscribe", "") # Subscribe to all topics
|
23
|
+
puts "Subscriber #{i + 1} connected"
|
24
|
+
|
25
|
+
# Receive 5 messages
|
26
|
+
5.times do
|
27
|
+
msg = sub.recv
|
28
|
+
puts "Subscriber #{i + 1} received: #{msg}"
|
29
|
+
end
|
30
|
+
|
31
|
+
sub.close
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Publisher sends 5 messages
|
36
|
+
sleep 1 # Give subscribers time to connect
|
37
|
+
5.times do |i|
|
38
|
+
message = "Broadcast message #{i + 1}"
|
39
|
+
pub.send(message)
|
40
|
+
puts "Publisher sent: #{message}"
|
41
|
+
sleep 0.2
|
42
|
+
end
|
43
|
+
|
44
|
+
# Wait for all subscribers
|
45
|
+
sub_threads.each(&:join)
|
46
|
+
|
47
|
+
# Cleanup
|
48
|
+
pub.close
|
49
|
+
|
50
|
+
puts "=" * 50
|
51
|
+
puts "Example completed!"
|