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.
@@ -1,340 +1,340 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # NNG + Protocol Buffers 集成演示
5
- # 展示如何将 Protobuf 消息通过 NNG 发送和接收
6
-
7
- require 'google/protobuf'
8
-
9
- puts "=" * 70
10
- puts "NNG + Protocol Buffers 集成演示"
11
- puts "=" * 70
12
- puts
13
-
14
- # ============================================================================
15
- # 1. 定义 Protobuf 消息结构
16
- # ============================================================================
17
-
18
- puts "步骤 1: 定义 Protobuf 消息结构"
19
- puts "-" * 70
20
- puts
21
-
22
- Google::Protobuf::DescriptorPool.generated_pool.build do
23
- add_file("wcf_rpc.proto", syntax: :proto3) do
24
- # RPC 请求消息
25
- add_message "RpcRequest" do
26
- optional :func_code, :int32, 1 # 功能码
27
- optional :data, :bytes, 2 # 业务数据
28
- optional :request_id, :string, 3 # 请求 ID
29
- end
30
-
31
- # RPC 响应消息
32
- add_message "RpcResponse" do
33
- optional :status, :int32, 1 # 状态码
34
- optional :data, :bytes, 2 # 响应数据
35
- optional :error_msg, :string, 3 # 错误消息
36
- end
37
-
38
- # 联系人信息
39
- add_message "Contact" do
40
- optional :wxid, :string, 1
41
- optional :name, :string, 2
42
- optional :remark, :string, 3
43
- end
44
-
45
- # 联系人列表
46
- add_message "ContactList" do
47
- repeated :contacts, :message, 1, "Contact"
48
- end
49
-
50
- # 文本消息
51
- add_message "TextMessage" do
52
- optional :receiver, :string, 1
53
- optional :content, :string, 2
54
- optional :aters, :string, 3
55
- end
56
- end
57
- end
58
-
59
- # 获取消息类
60
- RpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcRequest").msgclass
61
- RpcResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcResponse").msgclass
62
- Contact = Google::Protobuf::DescriptorPool.generated_pool.lookup("Contact").msgclass
63
- ContactList = Google::Protobuf::DescriptorPool.generated_pool.lookup("ContactList").msgclass
64
- TextMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("TextMessage").msgclass
65
-
66
- puts "✅ 消息定义完成:"
67
- puts " - RpcRequest (func_code, data, request_id)"
68
- puts " - RpcResponse (status, data, error_msg)"
69
- puts " - Contact (wxid, name, remark)"
70
- puts " - ContactList (contacts[])"
71
- puts " - TextMessage (receiver, content, aters)"
72
- puts
73
-
74
- # ============================================================================
75
- # 2. 示例 1: 简单的请求-响应
76
- # ============================================================================
77
-
78
- puts "示例 1: 简单的 RPC 请求-响应"
79
- puts "=" * 70
80
- puts
81
-
82
- # 客户端: 构建请求
83
- request = RpcRequest.new(
84
- func_code: 0x01, # FUNC_IS_LOGIN
85
- data: "",
86
- request_id: "req_001"
87
- )
88
-
89
- puts "📤 客户端构建请求:"
90
- puts " Function Code: 0x#{request.func_code.to_s(16)}"
91
- puts " Request ID: #{request.request_id}"
92
- puts
93
-
94
- # 序列化为二进制
95
- request_binary = RpcRequest.encode(request)
96
- puts "📦 序列化结果:"
97
- puts " 大小: #{request_binary.bytesize} bytes"
98
- puts " 十六进制: #{request_binary.unpack('H*').first[0, 40]}..."
99
- puts
100
-
101
- # 模拟通过 NNG 发送 (实际代码: socket.send(request_binary))
102
- puts "🌐 通过 NNG 发送: socket.send(request_binary)"
103
- puts
104
-
105
- # 服务器: 接收并反序列化
106
- # 模拟从 NNG 接收 (实际代码: response_binary = socket.recv)
107
- puts "📥 服务器接收并解析:"
108
- received_request = RpcRequest.decode(request_binary)
109
- puts " Function Code: 0x#{received_request.func_code.to_s(16)}"
110
- puts " Request ID: #{received_request.request_id}"
111
- puts
112
-
113
- # 服务器: 构建响应
114
- response = RpcResponse.new(
115
- status: 0,
116
- data: [1].pack('C'), # 返回 1 表示已登录
117
- error_msg: ""
118
- )
119
-
120
- puts "📤 服务器构建响应:"
121
- puts " Status: #{response.status} (成功)"
122
- puts
123
-
124
- # 序列化响应
125
- response_binary = RpcResponse.encode(response)
126
- puts "📦 序列化响应: #{response_binary.bytesize} bytes"
127
- puts
128
-
129
- # 模拟通过 NNG 发送响应
130
- puts "🌐 通过 NNG 发送响应: socket.send(response_binary)"
131
- puts
132
-
133
- # 客户端: 接收并解析响应
134
- received_response = RpcResponse.decode(response_binary)
135
- puts "📥 客户端接收响应:"
136
- puts " Status: #{received_response.status}"
137
- puts " Is Login: #{received_response.data.unpack('C').first == 1}"
138
- puts
139
- puts
140
-
141
- # ============================================================================
142
- # 3. 示例 2: 嵌套消息 - 获取联系人列表
143
- # ============================================================================
144
-
145
- puts "示例 2: 嵌套消息 - 获取联系人列表"
146
- puts "=" * 70
147
- puts
148
-
149
- # 客户端: 发送获取联系人请求
150
- get_contacts_request = RpcRequest.new(
151
- func_code: 0x12, # FUNC_GET_CONTACTS
152
- data: "",
153
- request_id: "req_002"
154
- )
155
-
156
- request_binary = RpcRequest.encode(get_contacts_request)
157
- puts "📤 客户端发送请求: FUNC_GET_CONTACTS (#{request_binary.bytesize} bytes)"
158
- puts
159
-
160
- # 服务器: 构建联系人列表
161
- contacts = ContactList.new(
162
- contacts: [
163
- Contact.new(wxid: "wxid_001", name: "张三", remark: "老同学"),
164
- Contact.new(wxid: "wxid_002", name: "李四", remark: "同事"),
165
- Contact.new(wxid: "wxid_003", name: "王五", remark: ""),
166
- Contact.new(wxid: "chatroom_001", name: "技术交流群", remark: "")
167
- ]
168
- )
169
-
170
- puts "🏗️ 服务器构建联系人列表:"
171
- contacts.contacts.each_with_index do |contact, i|
172
- puts " #{i + 1}. #{contact.name} (#{contact.wxid})"
173
- puts " 备注: #{contact.remark}" unless contact.remark.empty?
174
- end
175
- puts
176
-
177
- # 序列化联系人列表 (内层消息)
178
- contacts_binary = ContactList.encode(contacts)
179
- puts "📦 序列化联系人列表: #{contacts_binary.bytesize} bytes"
180
- puts
181
-
182
- # 构建 RPC 响应 (外层消息,包含内层数据)
183
- contacts_response = RpcResponse.new(
184
- status: 0,
185
- data: contacts_binary, # 嵌套的联系人列表
186
- error_msg: ""
187
- )
188
-
189
- response_binary = RpcResponse.encode(contacts_response)
190
- puts "📦 序列化 RPC 响应: #{response_binary.bytesize} bytes"
191
- puts " (包含嵌套的联系人列表)"
192
- puts
193
-
194
- # 客户端: 接收并解析
195
- puts "📥 客户端接收并解析:"
196
-
197
- # 第一层: 解析 RPC 响应
198
- rpc_resp = RpcResponse.decode(response_binary)
199
- puts " RPC Status: #{rpc_resp.status}"
200
-
201
- # 第二层: 解析嵌套的联系人列表
202
- contact_list = ContactList.decode(rpc_resp.data)
203
- puts " 联系人数量: #{contact_list.contacts.size}"
204
- puts
205
-
206
- puts "📋 解析结果:"
207
- contact_list.contacts.each_with_index do |contact, i|
208
- puts " #{i + 1}. #{contact.name}"
209
- puts " WXID: #{contact.wxid}"
210
- puts " 备注: #{contact.remark}" unless contact.remark.empty?
211
- end
212
- puts
213
- puts
214
-
215
- # ============================================================================
216
- # 4. 示例 3: 发送文本消息
217
- # ============================================================================
218
-
219
- puts "示例 3: 发送文本消息"
220
- puts "=" * 70
221
- puts
222
-
223
- # 客户端: 构建文本消息
224
- text_msg = TextMessage.new(
225
- receiver: "wxid_001",
226
- content: "Hello from NNG + Protobuf!",
227
- aters: ""
228
- )
229
-
230
- puts "📝 客户端构建文本消息:"
231
- puts " 接收者: #{text_msg.receiver}"
232
- puts " 内容: #{text_msg.content}"
233
- puts
234
-
235
- # 序列化文本消息
236
- text_msg_binary = TextMessage.encode(text_msg)
237
- puts "📦 序列化文本消息: #{text_msg_binary.bytesize} bytes"
238
- puts
239
-
240
- # 构建 RPC 请求 (包含文本消息)
241
- send_text_request = RpcRequest.new(
242
- func_code: 0x20, # FUNC_SEND_TXT
243
- data: text_msg_binary,
244
- request_id: "req_003"
245
- )
246
-
247
- request_binary = RpcRequest.encode(send_text_request)
248
- puts "📦 序列化 RPC 请求: #{request_binary.bytesize} bytes"
249
- puts "🌐 通过 NNG 发送: socket.send(request_binary)"
250
- puts
251
-
252
- # 服务器: 接收并解析
253
- puts "📥 服务器接收并解析:"
254
- recv_request = RpcRequest.decode(request_binary)
255
- puts " Function Code: 0x#{recv_request.func_code.to_s(16)}"
256
-
257
- # 解析嵌套的文本消息
258
- recv_text_msg = TextMessage.decode(recv_request.data)
259
- puts " 接收者: #{recv_text_msg.receiver}"
260
- puts " 内容: #{recv_text_msg.content}"
261
- puts
262
-
263
- # 服务器: 发送消息并响应
264
- puts "📨 服务器发送消息..."
265
- send_response = RpcResponse.new(
266
- status: 0,
267
- data: [1].pack('C'), # 1 = 发送成功
268
- error_msg: ""
269
- )
270
-
271
- response_binary = RpcResponse.encode(send_response)
272
- puts "📤 服务器响应: 发送成功"
273
- puts
274
-
275
- # 客户端: 接收响应
276
- final_response = RpcResponse.decode(response_binary)
277
- puts "📥 客户端收到响应:"
278
- if final_response.status == 0
279
- puts " ✅ 消息发送成功"
280
- else
281
- puts " ❌ 发送失败: #{final_response.error_msg}"
282
- end
283
- puts
284
- puts
285
-
286
- # ============================================================================
287
- # 5. 总结
288
- # ============================================================================
289
-
290
- puts "=" * 70
291
- puts "✅ 演示完成"
292
- puts "=" * 70
293
- puts
294
- puts "实际使用 NNG 的代码示例:"
295
- puts
296
- puts " require 'nng'"
297
- puts " require 'google/protobuf'"
298
- puts
299
- puts " # 客户端"
300
- puts " client = NNG::Socket.new(:pair1)"
301
- puts " client.dial('tcp://127.0.0.1:10086')"
302
- puts
303
- puts " # 构建并发送 Protobuf 请求"
304
- puts " request = RpcRequest.new(func_code: 0x12, data: '', request_id: 'req_001')"
305
- puts " request_binary = RpcRequest.encode(request)"
306
- puts " client.send(request_binary)"
307
- puts
308
- puts " # 接收并解析 Protobuf 响应"
309
- puts " response_binary = client.recv"
310
- puts " response = RpcResponse.decode(response_binary)"
311
- puts
312
- puts " # 解析嵌套的业务数据"
313
- puts " contacts = ContactList.decode(response.data)"
314
- puts
315
- puts " client.close"
316
- puts
317
- puts "关键技术点:"
318
- puts
319
- puts "1. 消息嵌套:"
320
- puts " RpcRequest/Response.data 字段 (bytes 类型) 可存储任意 Protobuf 消息"
321
- puts
322
- puts "2. 序列化链:"
323
- puts " 业务消息 → encode → bytes → RPC 消息 → encode → bytes → NNG 发送"
324
- puts
325
- puts "3. 反序列化链:"
326
- puts " NNG 接收 → bytes → decode → RPC 消息 → bytes → decode → 业务消息"
327
- puts
328
- puts "4. 优势:"
329
- puts " ✅ 类型安全 - 编译时检查"
330
- puts " ✅ 高效编码 - 比 JSON 小 50%+"
331
- puts " ✅ 跨语言 - 与 Python/Java/Go/C++ 互通"
332
- puts " ✅ 版本兼容 - 可安全添加/删除字段"
333
- puts " ✅ 自动验证 - 自动检查必填字段"
334
- puts
335
- puts "5. 实际应用场景:"
336
- puts " • WeChatFerry RPC 通信"
337
- puts " • 微服务间调用"
338
- puts " • 分布式系统消息传递"
339
- puts " • 客户端-服务器协议"
340
- puts
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # NNG + Protocol Buffers 集成演示
5
+ # 展示如何将 Protobuf 消息通过 NNG 发送和接收
6
+
7
+ require 'google/protobuf'
8
+
9
+ puts "=" * 70
10
+ puts "NNG + Protocol Buffers 集成演示"
11
+ puts "=" * 70
12
+ puts
13
+
14
+ # ============================================================================
15
+ # 1. 定义 Protobuf 消息结构
16
+ # ============================================================================
17
+
18
+ puts "步骤 1: 定义 Protobuf 消息结构"
19
+ puts "-" * 70
20
+ puts
21
+
22
+ Google::Protobuf::DescriptorPool.generated_pool.build do
23
+ add_file("wcf_rpc.proto", syntax: :proto3) do
24
+ # RPC 请求消息
25
+ add_message "RpcRequest" do
26
+ optional :func_code, :int32, 1 # 功能码
27
+ optional :data, :bytes, 2 # 业务数据
28
+ optional :request_id, :string, 3 # 请求 ID
29
+ end
30
+
31
+ # RPC 响应消息
32
+ add_message "RpcResponse" do
33
+ optional :status, :int32, 1 # 状态码
34
+ optional :data, :bytes, 2 # 响应数据
35
+ optional :error_msg, :string, 3 # 错误消息
36
+ end
37
+
38
+ # 联系人信息
39
+ add_message "Contact" do
40
+ optional :wxid, :string, 1
41
+ optional :name, :string, 2
42
+ optional :remark, :string, 3
43
+ end
44
+
45
+ # 联系人列表
46
+ add_message "ContactList" do
47
+ repeated :contacts, :message, 1, "Contact"
48
+ end
49
+
50
+ # 文本消息
51
+ add_message "TextMessage" do
52
+ optional :receiver, :string, 1
53
+ optional :content, :string, 2
54
+ optional :aters, :string, 3
55
+ end
56
+ end
57
+ end
58
+
59
+ # 获取消息类
60
+ RpcRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcRequest").msgclass
61
+ RpcResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("RpcResponse").msgclass
62
+ Contact = Google::Protobuf::DescriptorPool.generated_pool.lookup("Contact").msgclass
63
+ ContactList = Google::Protobuf::DescriptorPool.generated_pool.lookup("ContactList").msgclass
64
+ TextMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("TextMessage").msgclass
65
+
66
+ puts "✅ 消息定义完成:"
67
+ puts " - RpcRequest (func_code, data, request_id)"
68
+ puts " - RpcResponse (status, data, error_msg)"
69
+ puts " - Contact (wxid, name, remark)"
70
+ puts " - ContactList (contacts[])"
71
+ puts " - TextMessage (receiver, content, aters)"
72
+ puts
73
+
74
+ # ============================================================================
75
+ # 2. 示例 1: 简单的请求-响应
76
+ # ============================================================================
77
+
78
+ puts "示例 1: 简单的 RPC 请求-响应"
79
+ puts "=" * 70
80
+ puts
81
+
82
+ # 客户端: 构建请求
83
+ request = RpcRequest.new(
84
+ func_code: 0x01, # FUNC_IS_LOGIN
85
+ data: "",
86
+ request_id: "req_001"
87
+ )
88
+
89
+ puts "📤 客户端构建请求:"
90
+ puts " Function Code: 0x#{request.func_code.to_s(16)}"
91
+ puts " Request ID: #{request.request_id}"
92
+ puts
93
+
94
+ # 序列化为二进制
95
+ request_binary = RpcRequest.encode(request)
96
+ puts "📦 序列化结果:"
97
+ puts " 大小: #{request_binary.bytesize} bytes"
98
+ puts " 十六进制: #{request_binary.unpack('H*').first[0, 40]}..."
99
+ puts
100
+
101
+ # 模拟通过 NNG 发送 (实际代码: socket.send(request_binary))
102
+ puts "🌐 通过 NNG 发送: socket.send(request_binary)"
103
+ puts
104
+
105
+ # 服务器: 接收并反序列化
106
+ # 模拟从 NNG 接收 (实际代码: response_binary = socket.recv)
107
+ puts "📥 服务器接收并解析:"
108
+ received_request = RpcRequest.decode(request_binary)
109
+ puts " Function Code: 0x#{received_request.func_code.to_s(16)}"
110
+ puts " Request ID: #{received_request.request_id}"
111
+ puts
112
+
113
+ # 服务器: 构建响应
114
+ response = RpcResponse.new(
115
+ status: 0,
116
+ data: [1].pack('C'), # 返回 1 表示已登录
117
+ error_msg: ""
118
+ )
119
+
120
+ puts "📤 服务器构建响应:"
121
+ puts " Status: #{response.status} (成功)"
122
+ puts
123
+
124
+ # 序列化响应
125
+ response_binary = RpcResponse.encode(response)
126
+ puts "📦 序列化响应: #{response_binary.bytesize} bytes"
127
+ puts
128
+
129
+ # 模拟通过 NNG 发送响应
130
+ puts "🌐 通过 NNG 发送响应: socket.send(response_binary)"
131
+ puts
132
+
133
+ # 客户端: 接收并解析响应
134
+ received_response = RpcResponse.decode(response_binary)
135
+ puts "📥 客户端接收响应:"
136
+ puts " Status: #{received_response.status}"
137
+ puts " Is Login: #{received_response.data.unpack('C').first == 1}"
138
+ puts
139
+ puts
140
+
141
+ # ============================================================================
142
+ # 3. 示例 2: 嵌套消息 - 获取联系人列表
143
+ # ============================================================================
144
+
145
+ puts "示例 2: 嵌套消息 - 获取联系人列表"
146
+ puts "=" * 70
147
+ puts
148
+
149
+ # 客户端: 发送获取联系人请求
150
+ get_contacts_request = RpcRequest.new(
151
+ func_code: 0x12, # FUNC_GET_CONTACTS
152
+ data: "",
153
+ request_id: "req_002"
154
+ )
155
+
156
+ request_binary = RpcRequest.encode(get_contacts_request)
157
+ puts "📤 客户端发送请求: FUNC_GET_CONTACTS (#{request_binary.bytesize} bytes)"
158
+ puts
159
+
160
+ # 服务器: 构建联系人列表
161
+ contacts = ContactList.new(
162
+ contacts: [
163
+ Contact.new(wxid: "wxid_001", name: "张三", remark: "老同学"),
164
+ Contact.new(wxid: "wxid_002", name: "李四", remark: "同事"),
165
+ Contact.new(wxid: "wxid_003", name: "王五", remark: ""),
166
+ Contact.new(wxid: "chatroom_001", name: "技术交流群", remark: "")
167
+ ]
168
+ )
169
+
170
+ puts "🏗️ 服务器构建联系人列表:"
171
+ contacts.contacts.each_with_index do |contact, i|
172
+ puts " #{i + 1}. #{contact.name} (#{contact.wxid})"
173
+ puts " 备注: #{contact.remark}" unless contact.remark.empty?
174
+ end
175
+ puts
176
+
177
+ # 序列化联系人列表 (内层消息)
178
+ contacts_binary = ContactList.encode(contacts)
179
+ puts "📦 序列化联系人列表: #{contacts_binary.bytesize} bytes"
180
+ puts
181
+
182
+ # 构建 RPC 响应 (外层消息,包含内层数据)
183
+ contacts_response = RpcResponse.new(
184
+ status: 0,
185
+ data: contacts_binary, # 嵌套的联系人列表
186
+ error_msg: ""
187
+ )
188
+
189
+ response_binary = RpcResponse.encode(contacts_response)
190
+ puts "📦 序列化 RPC 响应: #{response_binary.bytesize} bytes"
191
+ puts " (包含嵌套的联系人列表)"
192
+ puts
193
+
194
+ # 客户端: 接收并解析
195
+ puts "📥 客户端接收并解析:"
196
+
197
+ # 第一层: 解析 RPC 响应
198
+ rpc_resp = RpcResponse.decode(response_binary)
199
+ puts " RPC Status: #{rpc_resp.status}"
200
+
201
+ # 第二层: 解析嵌套的联系人列表
202
+ contact_list = ContactList.decode(rpc_resp.data)
203
+ puts " 联系人数量: #{contact_list.contacts.size}"
204
+ puts
205
+
206
+ puts "📋 解析结果:"
207
+ contact_list.contacts.each_with_index do |contact, i|
208
+ puts " #{i + 1}. #{contact.name}"
209
+ puts " WXID: #{contact.wxid}"
210
+ puts " 备注: #{contact.remark}" unless contact.remark.empty?
211
+ end
212
+ puts
213
+ puts
214
+
215
+ # ============================================================================
216
+ # 4. 示例 3: 发送文本消息
217
+ # ============================================================================
218
+
219
+ puts "示例 3: 发送文本消息"
220
+ puts "=" * 70
221
+ puts
222
+
223
+ # 客户端: 构建文本消息
224
+ text_msg = TextMessage.new(
225
+ receiver: "wxid_001",
226
+ content: "Hello from NNG + Protobuf!",
227
+ aters: ""
228
+ )
229
+
230
+ puts "📝 客户端构建文本消息:"
231
+ puts " 接收者: #{text_msg.receiver}"
232
+ puts " 内容: #{text_msg.content}"
233
+ puts
234
+
235
+ # 序列化文本消息
236
+ text_msg_binary = TextMessage.encode(text_msg)
237
+ puts "📦 序列化文本消息: #{text_msg_binary.bytesize} bytes"
238
+ puts
239
+
240
+ # 构建 RPC 请求 (包含文本消息)
241
+ send_text_request = RpcRequest.new(
242
+ func_code: 0x20, # FUNC_SEND_TXT
243
+ data: text_msg_binary,
244
+ request_id: "req_003"
245
+ )
246
+
247
+ request_binary = RpcRequest.encode(send_text_request)
248
+ puts "📦 序列化 RPC 请求: #{request_binary.bytesize} bytes"
249
+ puts "🌐 通过 NNG 发送: socket.send(request_binary)"
250
+ puts
251
+
252
+ # 服务器: 接收并解析
253
+ puts "📥 服务器接收并解析:"
254
+ recv_request = RpcRequest.decode(request_binary)
255
+ puts " Function Code: 0x#{recv_request.func_code.to_s(16)}"
256
+
257
+ # 解析嵌套的文本消息
258
+ recv_text_msg = TextMessage.decode(recv_request.data)
259
+ puts " 接收者: #{recv_text_msg.receiver}"
260
+ puts " 内容: #{recv_text_msg.content}"
261
+ puts
262
+
263
+ # 服务器: 发送消息并响应
264
+ puts "📨 服务器发送消息..."
265
+ send_response = RpcResponse.new(
266
+ status: 0,
267
+ data: [1].pack('C'), # 1 = 发送成功
268
+ error_msg: ""
269
+ )
270
+
271
+ response_binary = RpcResponse.encode(send_response)
272
+ puts "📤 服务器响应: 发送成功"
273
+ puts
274
+
275
+ # 客户端: 接收响应
276
+ final_response = RpcResponse.decode(response_binary)
277
+ puts "📥 客户端收到响应:"
278
+ if final_response.status == 0
279
+ puts " ✅ 消息发送成功"
280
+ else
281
+ puts " ❌ 发送失败: #{final_response.error_msg}"
282
+ end
283
+ puts
284
+ puts
285
+
286
+ # ============================================================================
287
+ # 5. 总结
288
+ # ============================================================================
289
+
290
+ puts "=" * 70
291
+ puts "✅ 演示完成"
292
+ puts "=" * 70
293
+ puts
294
+ puts "实际使用 NNG 的代码示例:"
295
+ puts
296
+ puts " require 'nng'"
297
+ puts " require 'google/protobuf'"
298
+ puts
299
+ puts " # 客户端"
300
+ puts " client = NNG::Socket.new(:pair1)"
301
+ puts " client.dial('tcp://127.0.0.1:10086')"
302
+ puts
303
+ puts " # 构建并发送 Protobuf 请求"
304
+ puts " request = RpcRequest.new(func_code: 0x12, data: '', request_id: 'req_001')"
305
+ puts " request_binary = RpcRequest.encode(request)"
306
+ puts " client.send(request_binary)"
307
+ puts
308
+ puts " # 接收并解析 Protobuf 响应"
309
+ puts " response_binary = client.recv"
310
+ puts " response = RpcResponse.decode(response_binary)"
311
+ puts
312
+ puts " # 解析嵌套的业务数据"
313
+ puts " contacts = ContactList.decode(response.data)"
314
+ puts
315
+ puts " client.close"
316
+ puts
317
+ puts "关键技术点:"
318
+ puts
319
+ puts "1. 消息嵌套:"
320
+ puts " RpcRequest/Response.data 字段 (bytes 类型) 可存储任意 Protobuf 消息"
321
+ puts
322
+ puts "2. 序列化链:"
323
+ puts " 业务消息 → encode → bytes → RPC 消息 → encode → bytes → NNG 发送"
324
+ puts
325
+ puts "3. 反序列化链:"
326
+ puts " NNG 接收 → bytes → decode → RPC 消息 → bytes → decode → 业务消息"
327
+ puts
328
+ puts "4. 优势:"
329
+ puts " ✅ 类型安全 - 编译时检查"
330
+ puts " ✅ 高效编码 - 比 JSON 小 50%+"
331
+ puts " ✅ 跨语言 - 与 Python/Java/Go/C++ 互通"
332
+ puts " ✅ 版本兼容 - 可安全添加/删除字段"
333
+ puts " ✅ 自动验证 - 自动检查必填字段"
334
+ puts
335
+ puts "5. 实际应用场景:"
336
+ puts " • WeChatFerry RPC 通信"
337
+ puts " • 微服务间调用"
338
+ puts " • 分布式系统消息传递"
339
+ puts " • 客户端-服务器协议"
340
+ puts