目录
关于 Readline 的一点
管理您的依赖项
服务器
点燃它!
首页 CMS教程 &#&按 使用Node.js的Readline和Socket.io实现实时聊天

使用Node.js的Readline和Socket.io实现实时聊天

Aug 31, 2023 pm 06:09 PM
nodejs socketio readline

使用Node.js的Readline和Socket.io实现实时聊天

Node.js 在其标准库中有一个未被充分重视的模块,但却非常有用。 Readline 模块按照包装盒上的说明执行操作:从终端读取一行输入。这可用于询问用户一两个问题,或在屏幕底部创建提示。在本教程中,我打算展示 Readline 的功能并制作一个由 Socket.io 支持的实时 CLI 聊天室。客户端不仅可以发送简单的消息,还可以使用 /me 发送表情命令,使用 /msg 发送私人消息,并允许使用 /nick

关于 Readline 的一点

这可能是 Readline 最简单的用法:

var readline = require('readline');

var rl = readline.createInterface(process.stdin, process.stdout);

rl.question("What is your name? ", function(answer) {
	console.log("Hello, " + answer );
	rl.close();
});
登录后复制

我们包含该模块,使用标准输入和输出流创建 Readline 接口,然后向用户询问一个一次性问题。这是Readline的第一个用法:提问。如果您需要与用户确认某些内容,可能采用流行的形式,“您想这样做吗?(y/n)”,这种形式普遍存在于 CLI 工具中,readline.question () 就是这样做的方法。

Readline 提供的另一个功能是提示,可以根据其默认的“>”字符进行自定义,并暂时暂停以防止输入。对于我们的 Readline 聊天客户端,这将是我们的主要界面。将会出现一次 readline.question() 来询问用户昵称,但其他所有内容都将是 readline.prompt()

管理您的依赖项

让我们从无聊的部分开始:依赖关系。该项目将使用 socket.iosocket.io-client 包和 ansi-color。您的 packages.json 文件应如下所示:

{
    "name": "ReadlineChatExample",
	"version": "1.0.0",
	"description": "CLI chat with readline and socket.io",
	"author": "Matt Harzewski",
	"dependencies": {
		"socket.io": "latest",
		"socket.io-client": "latest",
		"ansi-color": "latest"
	},
	"private": true
}
登录后复制

运行 npm install 就可以了。

服务器

在本教程中,我们将使用一个非常简单的 Socket.io 服务器。没有比这更基本的了:

var socketio = require('socket.io');

// Listen on port 3636
var io = socketio.listen(3636);

io.sockets.on('connection', function (socket) {

    // Broadcast a user's message to everyone else in the room
	socket.on('send', function (data) {
		io.sockets.emit('message', data);
    });

});
登录后复制

它所做的只是从一个客户端接收传入消息并将其传递给其他所有人。对于更大规模的应用程序来说,服务器可能会更加健壮,但对于这个简单的示例来说,它应该足够了。

这应该保存在项目目录中,名称为 server.js

客户端:包括和设置

在我们开始有趣的部分之前,我们需要包含我们的依赖项,定义一些变量,并启动 Readline 接口和套接字连接。

var readline = require('readline'),
socketio = require('socket.io-client'),
util = require('util'),
color = require("ansi-color").set;


var nick;
var socket = socketio.connect('localhost', { port: 3636 });
var rl = readline.createInterface(process.stdin, process.stdout);
登录后复制

此时,代码几乎是不言自明的。我们已经有了昵称变量、套接字连接(通过 socket.io-client 包)和 Readline 接口。

在此示例中,Socket.io 将通过端口 3636 连接到本地主机,当然,如果您正在制作生产聊天应用程序,这将更改为您自己的服务器的域和端口。 (与自己聊天没有多大意义!)

客户端:询问用户名

现在我们第一次使用 Readline!我们想询问用户选择的昵称,这将在聊天室中识别他们。为此,我们将使用 Readline 的 question() 方法。

// Set the username
rl.question("Please enter a nickname: ", function(name) {
    nick = name;
	var msg = nick + " has joined the chat";
	socket.emit('send', { type: 'notice', message: msg });
	rl.prompt(true);
});
登录后复制

我们将之前的 nick 变量设置为从用户收集的值,向服务器发送一条消息(该消息将转发到其他客户端)我们的用户已加入聊天,然后将 Readline 界面切换回提示模式。传递给 prompt()true 值可确保正确显示提示符。 (否则光标可能会移动到该行的零位置,并且不会显示“>”。)

不幸的是,Readline 在 prompt() 方法方面存在令人沮丧的问题。它与 console.log() 配合得不太好,它会将文本输出到与提示字符相同的行,从而在各处留下杂散的“prompt() 方法方面存在令人沮丧的问题。它与 console.log() 配合得不太好,它会将文本输出到与提示字符相同的行,从而在各处留下杂散的“>”字符和其他字符怪异。为了解决这个问题,我们不会在此应用程序中的任何位置使用 console.log>

”字符和其他字符怪异。为了解决这个问题,我们不会在此应用程序中的任何位置使用 console.log,仅保留一个位置。相反,输出应该传递给此函数:

function console_out(msg) {
    process.stdout.clearLine();
	process.stdout.cursorTo(0);
	console.log(msg);
	rl.prompt(true);
}
登录后复制
这个稍微

的hacky解决方案可确保控制台中的当前行为空,并且在打印输出之前光标位于零位置。然后它明确要求再次输出提示。

console_out() 而不是 console.log()因此,在本教程的其余部分中,您将看到

客户端:处理输入

用户可以输入两种类型的输入:聊天和命令。我们知道命令前面有斜杠,因此很容易区分两者。

🎜

Readline 有几个事件处理程序,但最重要的无疑是 line。每当在输入流中检测到换行符(通过 return 或 Enter 键)时,就会触发此事件。因此,我们需要为我们的输入处理程序挂钩 line

rl.on('line', function (line) {
    if (line[0] == "/" && line.length > 1) {
		var cmd = line.match(/[a-z]+\b/)[0];
		var arg = line.substr(cmd.length+2, line.length);
		chat_command(cmd, arg);

	} else {
		// send chat message
		socket.emit('send', { type: 'chat', message: line, nick: nick });
		rl.prompt(true);
	}
});
登录后复制

如果输入行的第一个字符是斜杠,我们就知道这是一个命令,这将需要更多的处理。否则,我们只是发送常规聊天消息并重置提示。请注意此处通过套接字发送的数据与上一步中的加入消息之间的差异。它使用不同的 type,因此接收客户端知道如何格式化消息,并且我们还传递 nick 变量。

命令名称(cmd)和后面的文本(arg)用一些正则表达式和子字符串魔术隔离,然后我们将它们传递给处理函数命令。

function chat_command(cmd, arg) {
    switch (cmd) {

		case 'nick':
			var notice = nick + " changed their name to " + arg;
			nick = arg;
			socket.emit('send', { type: 'notice', message: notice });
			break;

		case 'msg':
			var to = arg.match(/[a-z]+\b/)[0];
			var message = arg.substr(to.length, arg.length);
			socket.emit('send', { type: 'tell', message: message, to: to, from: nick });
			break;

		case 'me':
			var emote = nick + " " + arg;
			socket.emit('send', { type: 'emote', message: emote });
			break;

		default:
			console_out("That is not a valid command.");

	}
}
登录后复制

如果用户输入 /nick gollum,则 nick 变量将重置为 gollum,它可能是 smeagol 之前,并将通知推送到服务器。

如果用户输入 /msg bilbo 珍贵在哪里?,使用相同的正则表达式来分隔接收者和消息,然后是一个类型为 tell 被推送到服务器。这将与普通消息的显示方式略有不同,并且其他用户不应该看到。诚然,我们过于简单的服务器会盲目地将消息推送给每个人,但客户端会忽略未发送到正确昵称的通知。更强大的服务器可以更加离散。

表情命令的使用形式为/我正在吃第二顿早餐。昵称以任何使用过 IRC 或玩过多人角色扮演游戏的人都应该熟悉的方式添加到表情符号中,然后将其推送到服务器。

客户端:处理传入消息

现在客户端需要一种接收消息的方法。我们需要做的就是挂钩 Socket.io 客户端的 message 事件并适当地格式化数据以进行输出。

socket.on('message', function (data) {
    var leader;
	if (data.type == 'chat' && data.nick != nick) {
		leader = color("<"+data.nick+"> ", "green");
		console_out(leader + data.message);
	}
	else if (data.type == "notice") {
		console_out(color(data.message, 'cyan'));
	}
	else if (data.type == "tell" && data.to == nick) {
		leader = color("["+data.from+"->"+data.to+"]", "red");
		console_out(leader + data.message);
	}
	else if (data.type == "emote") {
		console_out(color(data.message, "cyan"));
	}
});
登录后复制

客户端使用我们的昵称发送的类型为 chat 的消息将与昵称和聊天文本一起显示。用户已经可以看到他们在 Readline 中输入的内容,因此没有必要再次输出它。在这里,我使用 ansi-color 包对输出进行一点着色。这并不是绝对必要的,但它使聊天更容易理解。

类型为 noticeemote 的消息按原样打印,但颜色为青色。

如果消息是 tell,且昵称等于此客户端的当前名​​称,则输出采用 [Somebody->You] Hi! 的形式。当然,这并不是非常私密的事情。如果您想查看每个人的消息,您只需取出 && data.to == nick 部分即可。理想情况下,服务器应该知道将消息推送到哪个客户端,而不是将其发送给不需要它的客户端。但这增加了不必要的复杂性,超出了本教程的范围。

点燃它!

现在让我们看看是否一切正常。要对其进行测试,请通过运行 node server.js 启动服务器,然后打开几个新的终端窗口。在新窗口中,运行 node client.js 并输入昵称。假设一切顺利,那么您应该能够在他们之间聊天。

希望本教程向您展示了 Readline 模块的入门是多么容易。您可能想尝试向聊天应用程序添加更多功能,以进行更多练习。最后,查看 Readline 文档以获取完整的 API。

以上是使用Node.js的Readline和Socket.io实现实时聊天的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

nodejs和vuejs区别 nodejs和vuejs区别 Apr 21, 2024 am 04:17 AM

Node.js 是一种服务器端 JavaScript 运行时,而 Vue.js 是一个客户端 JavaScript 框架,用于创建交互式用户界面。Node.js 用于服务器端开发,如后端服务 API 开发和数据处理,而 Vue.js 用于客户端开发,如单页面应用程序和响应式用户界面。

nodejs是后端框架吗 nodejs是后端框架吗 Apr 21, 2024 am 05:09 AM

Node.js 可作为后端框架使用,因为它提供高性能、可扩展性、跨平台支持、丰富的生态系统和易于开发等功能。

nodejs怎么连接mysql数据库 nodejs怎么连接mysql数据库 Apr 21, 2024 am 06:13 AM

要连接 MySQL 数据库,需要遵循以下步骤:安装 mysql2 驱动程序。使用 mysql2.createConnection() 创建连接对象,其中包含主机地址、端口、用户名、密码和数据库名称。使用 connection.query() 执行查询。最后使用 connection.end() 结束连接。

nodejs中的全局变量有哪些 nodejs中的全局变量有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全局变量:全局对象:global核心模块:process、console、require运行时环境变量:__dirname、__filename、__line、__column常量:undefined、null、NaN、Infinity、-Infinity

nodejs安装目录里的npm与npm.cmd文件有什么区别 nodejs安装目录里的npm与npm.cmd文件有什么区别 Apr 21, 2024 am 05:18 AM

Node.js 安装目录中有两个与 npm 相关的文件:npm 和 npm.cmd,区别如下:扩展名不同:npm 是可执行文件,npm.cmd 是命令窗口快捷方式。Windows 用户:npm.cmd 可以在命令提示符下使用,npm 只能从命令行运行。兼容性:npm.cmd 特定于 Windows 系统,npm 跨平台可用。使用建议:Windows 用户使用 npm.cmd,其他操作系统使用 npm。

nodejs和java的差别大吗 nodejs和java的差别大吗 Apr 21, 2024 am 06:12 AM

Node.js 和 Java 的主要差异在于设计和特性:事件驱动与线程驱动:Node.js 基于事件驱动,Java 基于线程驱动。单线程与多线程:Node.js 使用单线程事件循环,Java 使用多线程架构。运行时环境:Node.js 在 V8 JavaScript 引擎上运行,而 Java 在 JVM 上运行。语法:Node.js 使用 JavaScript 语法,而 Java 使用 Java 语法。用途:Node.js 适用于 I/O 密集型任务,而 Java 适用于大型企业应用程序。

nodejs是后端开发语言吗 nodejs是后端开发语言吗 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一种后端开发语言。它用于后端开发,包括处理服务器端业务逻辑、管理数据库连接和提供 API。

nodejs和java选哪个 nodejs和java选哪个 Apr 21, 2024 am 04:40 AM

Node.js 和 Java 在 Web 开发中各有优劣,具体选择取决于项目要求。Node.js 擅长实时应用程序、快速开发和微服务架构,而 Java 则在企业级支持、性能和安全性方面占优。

See all articles