net 搭建多路复用的RPC通道
2021年11月24日单通信搭建
服务端
1 2 3 4 5 6 7 8 9 10 11 12 |
const net = require('net'); const server = net.createServer((socket) => { /** * 接听事件data */ socket.on('data', function (buffer) { console.log(buffer, buffer.toString()) //打印buffer 并转换为字符串 }) }); server.listen(4000); |
客户端
1 2 3 4 5 |
const net = require('net'); const socket = new net.Socket(); socket.connect({host: '127.0.0.1', port: 4000}) //设置连接地址 socket.write('good morning geekbang') //设置字符串 |
半双工通信
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const net = require('net'); const data = { 136797: "01 | 课程介绍", 136798: "02 | 内容综述", 136799: "03 | Node.js是什么?", 136800: "04 | Node.js可以用来做什么?", 136801: "05 | 课程实战项目介绍", 136803: "06 | 什么是技术预研?", 136804: "07 | Node.js开发环境安装", 136806: "08 | 第一个Node.js程序:石头剪刀布游戏", 136807: "09 | 模块:CommonJS规范", 136808: "10 | 模块:使用模块规范改造石头剪刀布游戏", 136809: "11 | 模块:npm", 141994: "12 | 模块:Node.js内置模块", 143517: "13 | 异步:非阻塞I/O", 143557: "14 | 异步:异步编程之callback", 143564: "15 | 异步:事件循环", 143644: "16 | 异步:异步编程之Promise", 146470: "17 | 异步:异步编程之async/await", 146569: "18 | HTTP:什么是HTTP服务器?", 146582: "19 | HTTP:简单实现一个HTTP服务器" } /** * 创建tcp服务器 */ const server = net.createServer((socket) => { //监听data事件 socket.on('data', function (buffer) { const id = buffer.readInt32BE(); //从传来的buffer里读出一个int32 console.log(buffer,id) setTimeout(() => {socket.write(Buffer.from(data[id]))}, 50) //50毫秒后回写数据 }) }); // 监听端口启动服务 server.listen(4000); |
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
const net = require('net'); const socket = new net.Socket(); //创建socket const lessonids = ["136797", "136798", "136799", "136800", "136801", "136803", "136804", "136806", "136807", "136808", "136809", "141994", "143517", "143557", "143564", "143644", "146470", "146569", "146582"] socket.connect({host: '127.0.0.1', port: 4000}); //连接服务器 socket.write(bufferEncode(Math.floor(Math.random() * lessonids.length))); //往服务器传数据 /** * 监听服务器返回的数据 */ socket.on('data', (buffer) => { console.log(buffer, buffer.toString()) socket.write(bufferEncode(Math.floor(Math.random() * lessonids.length))); }) // 把编码请求包的逻辑封装为一个函数 function bufferEncode(index) { buffer = Buffer.alloc(4); buffer.writeInt32BE(lessonids[index]); return buffer; } |
全双通通信(不需要等待返回数据)
1加包序号实现全双通通信
客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
const net = require('net'); const socket = new net.Socket(); socket.connect({host: '127.0.0.1', port: 4000}); const lessonData = ["136797", "136798", "136799", "136800", "136801", "136803", "136804", "136806", "136807", "136808", "136809", "141994", "143517", "143557", "143564", "143644", "146470", "146569", "146582"] let id = Math.floor(Math.random() * lessonData.length); let oldBuffer = null; socket.on('data', (buffer) => { if (oldBuffer) { buffer = Buffer.concat([oldBuffer, buffer]); } let completeLength = 0; while (completeLength = checkComplete(buffer)) { const package = buffer.slice(0, completeLength); buffer = buffer.slice(completeLength); const result = decode(package); console.log(`包${result.seq},返回值是${result.data}`); } oldBuffer = buffer; }) let seq = 0; function encode(data) { const body = Buffer.alloc(4); body.writeInt32BE(lessonData[data.id]); const header = Buffer.alloc(6); header.writeInt16BE(seq) header.writeInt32BE(body.length, 2); const buffer = Buffer.concat([header, body]) console.log(`包${seq}传输的课程id为${lessonData[data.id]}`); seq++; return buffer; } function decode(buffer) { const header = buffer.slice(0, 6); const seq = header.readInt16BE(); const body = buffer.slice(6) return { seq, data: body.toString() } } function checkComplete(buffer) { if (buffer.length < 6) { return 0; } const bodyLength = buffer.readInt32BE(2); return 6 + bodyLength } for (let k = 0; k < 100; k++) { id = Math.floor(Math.random() * lessonData.length); socket.write(encode({id})); } |
服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
const net = require('net'); const lessonData = { 136797: "01 | 课程介绍", 136798: "02 | 内容综述", 136799: "03 | Node.js是什么?", 136800: "04 | Node.js可以用来做什么?", 136801: "05 | 课程实战项目介绍", 136803: "06 | 什么是技术预研?", 136804: "07 | Node.js开发环境安装", 136806: "08 | 第一个Node.js程序:石头剪刀布游戏", 136807: "09 | 模块:CommonJS规范", 136808: "10 | 模块:使用模块规范改造石头剪刀布游戏", 136809: "11 | 模块:npm", 141994: "12 | 模块:Node.js内置模块", 143517: "13 | 异步:非阻塞I/O", 143557: "14 | 异步:异步编程之callback", 143564: "15 | 异步:事件循环", 143644: "16 | 异步:异步编程之Promise", 146470: "17 | 异步:异步编程之async/await", 146569: "18 | HTTP:什么是HTTP服务器?", 146582: "19 | HTTP:简单实现一个HTTP服务器" } //假数据 const server = net.createServer((socket) => { let oldBuffer = null; socket.on('data', function (buffer) { //判断是否有老数据如果有老数据将,老数据和新数据结合 if (oldBuffer) { buffer = Buffer.concat([oldBuffer, buffer]); } let packageLength = 0; //检查包的长度 while (packageLength = checkComplete(buffer)) { const package = buffer.slice(0, packageLength); buffer = buffer.slice(packageLength); const result = decode(package); //解包获取数据 socket.write(encode(lessonData[result.data], result.seq)); //编译包返回数据 } oldBuffer = buffer; }) }); server.listen(4000); function encode(data, seq) { const body = Buffer.from(data) const header = Buffer.alloc(6); header.writeInt16BE(seq) header.writeInt32BE(body.length, 2); const buffer = Buffer.concat([header, body]) return buffer; } function decode(buffer) { const header = buffer.slice(0, 6); const seq = header.readInt16BE(); const body = buffer.slice(6).readInt32BE() return {seq, data: body} } function checkComplete(buffer) { if (buffer.length < 6) {return 0;} const bodyLength = buffer.readInt32BE(2); return 6 + bodyLength } |