Node UDP 开发 和 进程管理
到此为止,Node 的大部分的主要内容我们都涉及到,但是还有一些核心模块需要你自己去探索,以下文章内容仅仅以案例补充的形式帮大家了解一下 Node 的用法。
UDP 开发
以下是 UDP 的服务器端的例子:
// 引入数据报模块
const dgram = require('dgram');
// 创建服务器端的 Socket 对象,继承了 EventEmitter
const server = dgram.createSocket('udp4');
// 监听服务器端关闭监听的事件
server.on('close', () => {
console.log('socket 已关闭');
});
// 异常处理
server.on('error', err => {
console.log(err);
});
server.on('listening', () => {
console.log('socket 正在监听中...');
});
// 收到客户端消息后触发此事件。
server.on('message', (msg, rinfo) => {
console.log(`receive :${msg} from ${rinfo.address}:${rinfo.port}`);
});
// 绑定端口,并开始进行广播。
// 第一个参数:端口,第二个参数:服务器本机 IP 地址
server.bind('58060', '192.168.0.104', () => {
server.setBroadcast(true); //开启广播
// server.setTTL(128);
setInterval(() => {
console.log('发送消息');
var msg = Buffer.from('大家好啊,我是服务端.');
// 广播消息,注意最后一个 IP 是广播网段的 IP,可以设置分组广播。
server.send(msg, 0, msg.length, 48061, '192.168.0.255');
}, 1500);
});
以下是 UDP 客户端的例子:
const dgram = require('dgram');
// 创建客户端的 socket,其实不分服务端和客户端,仅仅是我们人为定义的。
const client = dgram.createSocket('udp4');
client.on('close', () => {
console.log('socket 已关闭');
});
client.on('error', err => {
console.log('===>', err);
});
client.on('listening', () => {
console.log('socket 正在监听中...');
});
// 收到服务器消息。
client.on('message', (msg, rinfo) => {
console.log(`client => receive :${msg} from ${rinfo.address}:${rinfo.port}`);
});
// 绑定接受消息的端口,不绑定 IP,它会帮助我们尽可能的接收各个网段的对应的端口的消息。
client.bind(48061);
setInterval(() => {
var msg = Buffer.from('你好');
console.log('发送消息');
// 对单个服务器发送消息。
var msg = Buffer.from('大家好啊,我是 client.');
client.send(msg, 0, msg.length, 58060, '192.168.0.104');
}, 1500);
进程管理
process
对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。 因为是全局变量,所以无需使用 require()。
应用程序未捕获异常补救
process 对象
的'uncaughtException' 事件会在 Node 进程出现代码中有未处理的异常时触发,不至于让程序出现未处理异常直接崩溃。所以一般一个健壮的 Node 应用都要用此事件做最后的日志记录,用它在进程结束前执行一些已分配资源(比如文件描述符,句柄等等)的同步清理操作或者应用重启等操作,最好不要让程序继续执行,最好是重启应用。比如极端情况:持续性出异常,可能导致内存暴增或者其他问题就可能让服务器瘫痪。
process.on('uncaughtException', (err) => {
fs.writeSync(1, `捕获到异常:${err}\n`);
});
环境变量
process.env
属性返回一个包含用户环境信息的对象。
// a.js
console.log(process.env);
// 运行: node a.js
// 输出如下内容:
{
SSH_AUTH_SOCK: '/privatexxbin',
LSCOLORS: 'Gxfxcxdxbxegedabagacad',
SHLVL: '1',
ZSH: '/Users/x/.oh-my-zsh',
_: '/usr/local/bin/node',
TERM_PROGRAM: 'vscode',
TERM_PROGRAM_VERSION: '1.22.2',
LANG: 'en_US.UTF-8',
TERM: 'xterm-256color'
}
当然我们执行 node 程序的时候,还可以临时设置环境变量, process.env
大量运用于我们的自动化部署和编译的工具中环境判断:比如 webpack、gulp 等。
例如:
process.env.NODE_ENV = 'production'
// a.js
console.log(process.env);
# 运行 a.js 文件,并给设置环境变量 Age
$ Age=18 node a.js
# 输出如下内容, 多了一个 Age=18 的环境变量参数:
{
SSH_AUTH_SOCK: '/private/',
PATH: '/Users/x/Desktop/xxxxxx',
LSCOLORS: 'Gxfxcxdxbxegedabagacad',
SHLVL: '1',
ZSH: '/Users/x/.oh-my-zsh',
_: '/usr/local/bin/node',
TERM_PROGRAM: 'vscode',
TERM_PROGRAM_VERSION: '1.22.2',
LANG: 'en_US.UTF-8',
TERM: 'xterm-256color',
NODE_ENV: 'production',
Age: 18
}
进程退出
process.exit([code])
方法以结束状态码 code 指示 Node.js 同步终止进程。
// 异常退出。
process.exit(1);
状态码列表:
状态码 | 说明 |
---|---|
1 | 未捕获异常 - 有一个未被捕获的异常, 并且没被一个 domain 或 an 'uncaughtException' 事件处理器处理。 |
2 | - 未被使用 (Bash 为防内部滥用而保留) |
3 | 内部 JavaScript 分析错误 - Node.js 的内部的 JavaScript 源代码 在引导进程中导致了一个语法分析错误。 这是非常少见的, 一般只会在开发 Node.js 本身的时候出现。 |
4 | 内部 JavaScript 执行失败 - 引导进程执行 Node.js 的内部的 JavaScript 源代码时,返回函数值失败。 这是非常少见的, 一般只会在开发 Node.js 本身的时候出现。 |
5 | 致命错误 - 在 V8 中有一个致命的错误. 比较典型的是以 FATALERROR 为前缀从 stderr 打印出来的消息。 |
6 | 非函数的内部异常处理 - 发生了一个内部异常,但是内部异常处理函数 被设置成了一个非函数,或者不能被调用。 |
7 | 内部异常处理运行时失败 - 有一个不能被捕获的异常。 在试图处理这个异常时,处理函数本身抛出了一个错误。 这是可能发生的, 比如, 如果一个 'uncaughtException' 或者 domain.on('error') 处理函数抛出了一个错误。 |
8 | - 未被使用. 在之前版本的 Node.js, 退出码 8 有时候表示一个未被捕获的异常。 |
9 | - 不可用参数 - 也许是某个未知选项没有确定,或者没给必需要的选项填值。 |
10 | 内部 JavaScript 运行时失败 - 调用引导函数时, 引导进程执行 Node.js 的内部的 JavaScript 源代码抛出错误。 这是非常少见的, 一般只会在开发 Node.js 本身的时候出现。 |
12 | 不可用的调试参数 - --inspect 和/或 --inspect-brk 选项已设置,但选择的端口号无效或不可用。 |
大于 128 | 退出信号 - 如果 Node.js 的接收信号致命诸如 SIGKILL 或 SIGHUP,那么它的退出代码将是 128 加上信号的码值。 这是 POSIX 的标准做法,因为退出码被定义为 7 位整数,并且信号退出设置高位,然后包含信号码值。 |
其他用法
process.memoryUsage()
获取当前内存的使用量
{ rss: 20783104,
heapTotal: 7159808,
heapUsed: 4905696,
external: 8608 }
- 当前事件循环的延后处理
process.nextTick(callback[, ...args])
方法将 callback 添加到"next tick 队列"。 一旦当前事件轮询队列的任务全部完成,在 next tick 队列中的所有 callbacks 会被依次调用。
这种方式不是 setTimeout(fn, 0) 的别名。它更加有效率。事件轮询随后的 ticks 调用,会在任何 I/O 事件(包括定时器)之前运行。
console.log('start');
process.nextTick(() => {
console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback
- 获取当前进程工作目录
process.cwd()
- 关闭进程
process.kill(pid[, signal])
总结
其实还有很多其他的东西可以慢慢展开:比如 node 的 vm 模块、v8 模块、加密模块等,都是非常有意思的东西。但是老马不展开了,毕竟文档还是最详细的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: NodeJS http 模块
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论