1、简介
1.1 node
Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。
Node.js 是一个开源和跨平台的 JavaScript 运行时环境。 它是几乎任何类型项目的流行工具!
1.2 Protobuf
Protobuf 是一种用于 序列化 和 反序列化 对象的格式规范(rpc 通信协议)。
Protobuf 与 非结构化格式(如 JSON、XML)最大的区别在于,你必须为 protobufs 定义数据类型,最常用的方式是定义 .proto 文件。
2 代码示例
2.1 例子:hello.proto + udp
- hello.proto
package yxy;
message helloworld
{
message helloReq { required string name = 1; }
message helloRsp
{
required int32 retcode = 1;
optional string reply = 2;
}
}
2.1.1 服务端:yxy_server.js
- yxy_server.js
var ProtoBuf = require("protobufjs");
var dgram = require('dgram');
var PORT = 8080;
var HOST = '127.0.0.1';
var server = dgram.createSocket('udp4');
var root = ProtoBuf.loadSync("./hello.proto");
var HelloReq = root.lookupType("yxy.helloworld.helloReq");
var HelloRsp = root.lookupType("yxy.helloworld.helloRsp");
server.on('listening', function () {
var address = server.address();
console.log('UDP Server listening on ' + address.address + ":" + address.port);
});
server.on('message', function (message, remote) {
console.log(remote.address + ':' + remote.port + ' - ' + message);
console.log(HelloReq.decode(message) + ' from client!');
var hCReq = HelloRsp.fromObject({retcode:200, reply:'Yeah!I\'m 杨小羊!'});
var message = HelloRsp.encode(hCReq).finish();
server.send(message, 0, message.length, remote.port, remote.address, function (err, bytes) {
if (err) {
throw err;
}
console.log('UDP message reply to ' + remote.address + ':' + remote.port);
})
});
server.bind(PORT, HOST);
2.1.2 客户端:yxy_client.js
var dgram = require('dgram');
var ProtoBuf = require("protobufjs");
var PORT = 8080;
var HOST = '127.0.0.1';
var root = ProtoBuf.loadSync("./hello.proto");
var HelloReq = root.lookupType("yxy.helloworld.helloReq");
var HelloRsp = root.lookupType("yxy.helloworld.helloRsp");
var hCReq = HelloReq.fromObject({name:"杨小羊"});
var buffer = HelloReq.encode(hCReq).finish();
message = buffer;
var socket = dgram.createSocket({
type: 'udp4',
fd: PORT
}, function (err, message) {
if (err) {
console.log(err);
}
console.log(message);
});
socket.send(message, 0, message.length, PORT, HOST, function (err, bytes) {
if (err) {
throw err;
}
console.log('UDP message sent to ' + HOST + ':' + PORT);
});
socket.on("message", function (msg, rinfo) {
console.log("[Client] Received message: " + HelloRsp.decode(msg).reply + " from " + rinfo.address + ":" + rinfo.port);
console.log(HelloRsp.decode(msg));
socket.close();
});
socket.on('close', function () {
console.log('socket closed.');
});
socket.on('error', function (err) {
socket.close();
console.log('socket err');
console.log(err);
});
2.2 例子:user.proto + tcp
- user.proto
syntax = "proto3";
package yxy;
message Login {
required string name = 1;
required string pwd = 2;
}
message Address{
string province = 1;
string city = 2;
string country = 3;
}
2.2.1 服务端:yxy_tcpserver.js
- yxy_tcpserver.js
const net = require("net");
const protobuf = require("protobufjs");
const PORT = 9090;
const HOST = '127.0.0.1';
protobuf.load("./user.proto", (err, root) => {
if (err) throw err;
const LoginMessage = root.lookupType("yxy.Login");
const server = net.createServer((socket) => {
console.log("New client connected");
socket.on("data", (data) => {
// 解码数据
const message = LoginMessage.decode(data);
// 在这里处理消息
console.log(message);
// 编码响应
const responseData = LoginMessage.encode({
name: "杨小羊",
pwd: "123456"
}).finish();
// 将响应写回到连接
socket.write(responseData);
});
socket.on("close", () => {
console.log("Client disconnected");
});
});
server.listen(PORT, () => {
console.log(`Server listening on localhost:${PORT}`);
});
});
2.2.2 客户端:yxy_tcpclient.js
- yxy_tcpclient.js
const net = require("net");
const protobuf = require("protobufjs");
const PORT = 9090;
const HOST = '127.0.0.1';
protobuf.load("./user.proto", (err, root) => {
if (err) throw err;
const LoginMessage = root.lookupType("yxy.Login");
const client = net.createConnection({
port: PORT
}, () => {
console.log("Connected to server");
// 编码数据
const data = LoginMessage.encode({
name: "爱看书的小沐",
pwd: "666666"
}).finish();
// 将数据写到连接
client.write(data);
});
client.on("data", (data) => {
// 解码服务器的响应
const message = LoginMessage.decode(data);
// 在这里处理响应
console.log(message);
});
client.on("close", () => {
console.log("Connection closed");
});
});
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!