这里有新鲜出炉的 Node.JS 入门教程,程序狗速度看过来!
Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的 易于扩展的网络应用 · Node.js 借助事件驱动, 非阻塞 I/O 模型变得轻量和高效, 非常适合 运行在分布式设备 的 数据密集型 的实时应用
Node.js Net 模块提供了一些用于底层的网络通信的小工具,包含了创建服务器 / 客户端的方法,下面这篇文章主要给大家介绍了 Node.js 利用 Net 模块实现命令行多人聊天室的方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
这篇文章介绍的是 Node.js 利用 Net 模块实现命令行式的多人聊天室,下面话不多说,来看看详细的介绍吧。
1、net 模块基本 API
要使用 Node.js 的 net 模块实现一个命令行聊天室,就必须先了解 NET 模块的 API 使用。NET 模块 API 分为两大类:
Server 和 Socket 类、工厂方法。
Server 类如下图所示:
net.Server 类可以用来创建一个 TCP 或本地服务器,继承了 EventEmitter。
Socket 类如下:
net.Socket 类一般用创建一个 socket 客户端或者是 net.Server connection 事件的参数。
工厂方法如下:
以上三个图展示了 API 的使用,其实 NET 模块的内部原理和 C++ 网络编程差不多的,都是以下步骤。
服务端:
客户端:
如下图所示:
2、聊天室的设计和实现
上面学习了 NET 模块 API 的使用,接下来便开始实现命令行聊天室,我们不需要做的很复杂,只需实现如下功能即可:
确定功能之后,便开始代码的编写。这里我就不一步步分析,直接上代码了,首先是服务端:
Server:
- const net = require('net');
- const server = net.createServer();
- const clients = {}; //保存客户端的连接
- var client = null; //当前客户连接
- var uid = 0;
- server.on('connection', (socket) = >{
- //启动心跳机制
- var isOnline = !0;
- var keepAliveTimer = socket.timer = setInterval(() = >{
- if (!isOnline) {
- isOnline = !1;
- client = socket;
- quit(socket.nick);
- return;
- }
- if (socket.writable) {
- socket.write('::');
- } else {
- client = socket;
- quit(socket.nick);
- }
- },
- 3000);
- socket.on('end', () = >{
- console.log(`client disconnected.\n\r`);
- socket.destroy();
- });
- socket.on('error', (error) = >{
- console.log(error.message);
- });
- socket.on('data', (chunk) = >{
- client = socket;
- var msg = JSON.parse(chunk.toString());
- if (msg.cmd == 'keep') {
- isOnline = !0;
- return;
- }
- dealMsg(msg);
- });
- });
- server.on('error', (err) = >{
- console.log(err);
- });
- server.on('listening', () = >{
- console.log(`listening on $ {
- server.address().address
- }: $ {
- server.address().port
- }\n\r`);
- });
- server.listen(8060); //启动监听
- /**
- * 处理用户信息
- */
- function dealMsg(msg) {
- const cmd = msg.cmd;
- const funs = {
- 'login': login,
- 'chat': chat,
- 'quit': quit,
- 'exit': quit
- };
- if (typeof funs[cmd] !== 'function') return ! 1;
- funs[cmd](msg);
- }
- /**
- * 释放连接资源
- */
- function freeConn(conn) {
- conn.end();
- delete clients[conn.uuid];
- conn.timer && clearInterval(conn.timer);
- }
- /**
- * 用户首次进入聊天室
- */
- function login(msg) {
- var uuid = '';
- uuid = getRndStr(15) + (++uid); //产生用户ID
- client.write(`欢迎你,$ {
- msg.nick
- }:这里总共有$ {
- Object.keys(clients).length
- }个小伙伴在聊天.\r\n`) client.nick = msg.nick;
- client.uuid = uuid;
- clients[uuid] = client;
- broadcast(`系统:$ {
- msg.nick
- }进入了聊天室.`);
- }
- /**
- * 广播消息
- */
- function broadcast(msg) {
- Object.keys(clients).forEach((uuid) = >{
- if ((clients[uuid] != client) & clients[uuid].writable) {
- clients[uuid].write(msg);
- }
- });
- }
- /**
- * 退出聊天室
- */
- function quit(nick) {
- var message = `小伙伴$ {
- nick
- }退出了聊天室.`;
- broadcast(message);
- freeConn(client);
- }
- function chat(msg) {
- if (msg.msg.toLowerCase() == 'quit' || msg.msg.toLowerCase() == 'exit') {
- quit(msg.nick);
- return;
- }
- var message = `$ {
- msg.nick
- }说:$ {
- msg.msg
- }`;
- broadcast(message);
- }
- /**
- * 随机指定长度(len)的字符串
- */
- function getRndStr(len = 1) {
- var rndStr = '';
- for (; rndStr.length < len; rndStr += Math.random().toString(36).substr(2));
- return rndStr.substr(0, len);
- }
客户端代码如下:
client:
- const net = require('net');
- const cout = process.stdout;
- const cin = process.stdin;
- var client = null;
- var nick = '';
- cout.write(`请输入昵称:`);
- //监听命令行输入
- cin.on('data', (chunk) = >{
- if (chunk.toString() != '\r\n') {
- if (client === null) {
- nick = (chunk + '').replace(/[\r\n]/ig, "");
- createClient();
- } else {
- msg = (chunk + '').replace(/[\r\n]/ig, "");
- client.write(JSON.stringify({
- cmd: 'chat',
- msg: msg,
- nick: nick
- }));
- //如果输入是exit或quit则断开连接并退出
- if (msg.toLowerCase() == 'exit' || msg.toLowerCase() == 'quit') {
- client.end();
- cin.end();
- return;
- }
- cout.write(`你说:$ {
- msg
- }\n\r`);
- }
- } else {
- cout.write(`请输入昵称:`);
- }
- });
- function addListener(client) {
- client.on('connect', () = >{
- cout.write(`已连接到服务器\n\r`);
- client.write(JSON.stringify({
- cmd: 'login',
- msg: 'hello server',
- nick: nick
- }));
- });
- client.on('end', (chunk) = >{
- cout.write(`与服务器断开连接.\n\r`);
- });
- client.on('data', (chunk) = >{
- //如果是心跳信息则回应keep命令
- if (chunk.toString() == '::') {
- client.write(JSON.stringify({
- cmd: 'keep',
- msg: '',
- nick: nick
- }));
- return;
- }
- cout.write(`$ {
- chunk
- }\n\r`);
- });
- client.on('error', (err) = >{
- cout.write(`an error has occured.\n\r$ {
- err
- }`);
- });
- }
- /**
- * 创建socket并连接服务器
- */
- function createClient() {
- console.log('\033[2J'); //清屏操作
- cout.write(`输入'EXIT OR QUIT'退出聊天室.\r\n`);
- client = new net.Socket() client.connect({
- port: 8060
- /*,host:'1.1.1.69'*/
- });
- addListener(client);
- }
执行结果如下如下:
到此,一个命令行聊天室便做完了。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0618/329233.html