[Xiao Muxue フロントエンド] Node.js は UDP と Protobuf 通信を実装します (protobuf.js)

1 はじめに

1.1ノード

Node.js は、オープンソースのクロスプラットフォーム JavaScript ランタイム環境です。

Node.js は、オープンソースのクロスプラットフォームの JavaScript ランタイム環境です。これは、ほぼあらゆる種類のプロジェクトで人気のあるツールです。

Node.js は、ブラウザの外部で V8 JavaScript エンジン (Google Chrome のコア) を実行します。これにより、Node.js が非常に効率的になります。

Node.js アプリケーションは単一プロセスで実行されるため、リクエストごとに新しいスレッドを作成する必要がなくなります。Node.js は、JavaScript コードがブロックされるのを防ぐために、標準ライブラリに一連の非同期 I/O プリミティブを提供します。また、一般に、Node.js のライブラリは非ブロッキング パラダイムを使用して記述されているため、ブロック動作は通常ではなく例外となります。
ここに画像の説明を挿入します

1.2 プロトバッファ

Protobuf は、オブジェクトをシリアル化および逆シリアル化するための形式仕様 (rpc 通信プロトコル) です。

Protobuf と非構造化形式 (JSON、XML など) の最大の違いは、protobuf のデータ型を定義する必要があることです。最も一般的な方法は .proto ファイルを定義することです。

ここに画像の説明を挿入します
Google Protocol Buffer (略して Protobuf) は、Google の内部混合言語データ標準であり、現在 48,162 を超えるメッセージ形式定義と 12,183 を超える .proto ファイルが使用されています。これらは、RPC システムおよび永続データ ストレージ システムで使用されます。
ここに画像の説明を挿入します

Google プロトコル バッファーは、構造化データのシリアル化またはシリアル化に使用できる、軽量で効率的な構造化データ ストレージ形式です。データストレージまたは RPC データ交換フォーマットに非常に適しています。言語、プラットフォームに依存しない、拡張可能なシリアル化された構造化データ形式であり、通信プロトコル、データ ストレージ、その他の分野で使用できます。現在、C++、Java、Python の 3 つの言語で API が提供されています (IM Network 注: Protobuf の公式プロジェクト ホームページには、C++、Java、Python、Objective-C、C#、 JavaNano、JavaScript、Ruby、Go、PHP、基本的にすべての主流言語がサポートされています。
ここに画像の説明を挿入します

2. ダウンロードしてインストールします

2.1ノード

https://nodejs.org/zh-cn
ここに画像の説明を挿入します
https://nodejs.org/zh-cn/download
ここに画像の説明を挿入します

2.2 プロトバッファ

https://github.com/protocolbuffers/protobuf
https://github.com/protobufjs/protobuf.js

npm install protobufjs [--save --save-prefix=~]
npm i -g protobufjs

# The command line utility lives in the protobufjs-cli package and must be installed separately:
npm install protobufjs-cli [--save --save-prefix=~]
#老版本
##使用pbjs命令将.proto文件转换为.js文件
./node_modules/protobufjs/bin/pbjs -t json msg.proto > msg.json

## 使用pbjs命令将.proto文件转换为.json文件
./node_modules/protobufjs/bin/pbjs -t static_module -w commonjs -o msg.js msg.proto

#新版本
npx pbjs  -t json message.proto --es6 "msg.js"
npx pbjs  -t json message.proto --ts "msg.ts" 

ノード側では、処理のために js ファイルにパッケージ化することもできます。ただし、ノードはサーバー環境であり、.proto の存在は完全に許可されているため、実際にそれをエレガントな方法、つまり直接解析で使用できます。

pbjs コマンドを使用して .proto ファイルを .json ファイルに変換します。

./node_modules/protobufjs/bin/pbjs -t json msg.proto > msg.json
./protobuf.js-protobufjs-v7.2.5/cli/bin/pbjs  -t json msg.proto > msg.json

3. ノードコード例

3.1 HTTP

Node をインストールしたら、最初の Web サーバーを構築してみましょう。次に、node server.js を使用してプログラムを実行し、http://localhost:3000 にアクセスすると、「Hello World」というメッセージが表示されます。

  • サーバー.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
    
    
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain;charset=utf-8');
  res.end('Hello World, 爱看书的小沐!2023!\n');
});

server.listen(port, hostname, () => {
    
    
  console.log(`服务器运行在 http://${
      
      hostname}:${
      
      port}/`);
});

スクリプトを実行します。

node server.js

ここに画像の説明を挿入します
ブラウザは http サーバーにアクセスします。

http://127.0.0.1:3000/

ここに画像の説明を挿入します

var http = require('http');
var hostname = '127.0.0.1';
var port = 3000;

http.createServer(function(req, res) {
    
    
  res.writeHead(200, {
    
    'Content-Type': 'text/html'});
  res.write('<head><meta charset="utf-8"/></head>');
  res.write('<h1>Node.js</h1>');
  res.write('<b>爱看书的小沐!2023!</b>');
  res.end('<p>Hello World</p>');
  
}).listen(port);
 
console.log("HTTP server is listening at port ${port}.");
console.log(`服务器运行在 http://${
      
      hostname}:${
      
      port}/`);

ここに画像の説明を挿入します

3.2 UDP ユニキャスト

UDP ユニキャストの例 1

  • ポート 8080 でメッセージをリッスンするファイル (「demo_dgram.js」) を作成します。
var dgram = require('dgram');
var s = dgram.createSocket('udp4');
s.on('message', function(msg, rinfo) {
    
    
  console.log('I got this message: ' + msg.toString());
});
s.bind(8080);
  • ポート 8080 にメッセージを送信するファイル (「demo_dgram_send.js」) を作成します。
var dgram = require('dgram');
var s = dgram.createSocket('udp4');
s.send(Buffer.from('abc'), 8080, 'localhost');

UDPユニキャストの例2

  • サーバー: udp_server.js
// 例子:UDP服务端
var PORT = 9090;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var server = dgram.createSocket('udp4');

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);
});

server.bind(PORT, HOST);

ここに画像の説明を挿入します

  • クライアント: udp_client.js
// 例子:UDP客户端
var PORT = 9090;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var message = Buffer.from('This is 爱看书的小沐!');

var client = dgram.createSocket('udp4');

client.send(message, PORT, HOST, function(err, bytes) {
    
    
    if (err) throw err;
    console.log('UDP message sent to ' + HOST +':'+ PORT);
    client.close();
});

ここに画像の説明を挿入します

3.4 UDPブロードキャスト

  • サーバー:boardcast_server.js
var dgram = require('dgram');
var server = dgram.createSocket('udp4');
var port = 8080;

server.on('message', function(message, rinfo){
    
    
    console.log('server got message from: ' + rinfo.address + ':' + rinfo.port);
});

server.on('listening', function () {
    
    
    var address = server.address();
    console.log('Boardcast Server listening on ' + address.address + ":" + address.port);
});

server.bind(port);

ここに画像の説明を挿入します

  • クライアント:boardcast_client.js
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
var msg = Buffer.from('hello world, 爱看书的小沐!');
var port = 8080;
var host = '255.255.255.255';

client.bind(function(){
    
    
    client.setBroadcast(true);

    // client.send(msg, port, host, function(err){
    
    
    //     if(err) throw err;
    //     console.log('msg has been sent');
    //     client.close();
    // });

    // 循环发送消息
    setInterval(function(){
    
    
        client.send(msg, port, host, function(err){
    
    
            if(err) throw err;
            console.log('msg has been sent');
        });
    }, 1000);
    
});

ここに画像の説明を挿入します

4. Protobuf コード例

4.1 例: awesome.proto

  • awesome.proto の内容は次のように定義されます。
// awesome.proto
package awesomepackage;
syntax = "proto3";

message AwesomeMessage {
    
    
    string awesome_field = 1; // becomes awesomeField
}
  • テストスクリプトファイル:test_proto.js
var protobuf = require("protobufjs");
protobuf.load("awesome.proto", function(err, root) {
    
    
    if (err)
        throw err;

    // Obtain a message type
    var AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage");

    // Exemplary payload
    var payload = {
    
     awesomeField: "AwesomeString" };
    console.log("payload: " + JSON.stringify(payload));

    // Verify the payload if necessary (i.e. when possibly incomplete or invalid)
    var errMsg = AwesomeMessage.verify(payload);
    if (errMsg)
        throw Error(errMsg);

    // Create a new message
    var message = AwesomeMessage.create(payload); // or use .fromObject if conversion is necessary
    console.log("create: " + JSON.stringify(message));

    // Encode a message to an Uint8Array (browser) or Buffer (node)
    var buffer = AwesomeMessage.encode(message).finish();
    // ... do something with buffer
    console.log("encode: " + JSON.stringify(buffer));

    // Decode an Uint8Array (browser) or Buffer (node) to a message
    var message = AwesomeMessage.decode(buffer);
    // ... do something with message
    console.log("decode: " + JSON.stringify(message));

    // If the application uses length-delimited buffers, there is also encodeDelimited and decodeDelimited.

    // Maybe convert the message back to a plain object
    var object = AwesomeMessage.toObject(message, {
    
    
        longs: String,
        enums: String,
        bytes: String,
        // see ConversionOptions
    });
    console.log("toObject: " + JSON.stringify(object));
});

次のように実行コマンドを実行します。

node test_proto.js

ここに画像の説明を挿入します

結論

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

おすすめ

転載: blog.csdn.net/hhy321/article/details/133435420