目錄
#關於 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() 配合得不太好,它會將文字輸出到與提示字元相同的行,從而在各處留下雜散的“>”字符和其他字符怪異。為了解決這個問題,我們不會在此應用程式中的任何位置使用 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

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1324
25
PHP教程
1272
29
C# 教程
1251
24
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中的全域變數有哪些 nodejs中的全域變數有哪些 Apr 21, 2024 am 04:54 AM

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

nodejs怎麼連接mysql資料庫 nodejs怎麼連接mysql資料庫 Apr 21, 2024 am 06:13 AM

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

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是後端開發語言嗎 nodejs是後端開發語言嗎 Apr 21, 2024 am 05:09 AM

是的,Node.js 是一種後端開發語言。它用於後端開發,包括處理伺服器端業務邏輯、管理資料庫連接和提供 API。

nodejs可以寫前端嗎 nodejs可以寫前端嗎 Apr 21, 2024 am 05:00 AM

是的,Node.js可用於前端開發,主要優勢包括高效能、豐富的生態系統和跨平台相容性。需要考慮的注意事項有學習曲線、工具支援和社群規模較小。

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 適用於大型企業應用程式。

See all articles