Node.js용 Readline 및 Socket.io를 사용한 실시간 채팅

WBOY
풀어 주다: 2023-08-31 18:09:07
원래의
1410명이 탐색했습니다.

Node.js용 Readline 및 Socket.io를 사용한 실시간 채팅

Node.js에는 과소평가되었지만 표준 라이브러리에는 매우 유용한 모듈이 있습니다. Readline 모듈은 상자에 적힌 대로 터미널에서 입력 라인을 읽습니다. 이는 사용자에게 한두 가지 질문을 하거나 화면 하단에 프롬프트를 만드는 데 사용할 수 있습니다. 이 튜토리얼에서는 Readline의 기능을 시연하고 Socket.io로 구동되는 라이브 CLI 채팅방을 만들겠습니다. 클라이언트는 간단한 메시지를 보낼 수 있을 뿐만 아니라 /me 发送表情命令,使用 /msg 发送私人消息,并允许使用 /nick를 사용할 수도 있습니다.

Readline에 대해 조금

이것은 아마도 Readline의 가장 간단한 사용법일 것입니다:

으아아아

표준 입력 및 출력 스트림을 사용하여 Readline 인터페이스를 생성한 다음 사용자에게 일회성 질문을 하기 위해 이 모듈을 포함합니다. 이것은 Readline의 첫 번째 사용입니다: 질문하기. 사용자에게 무언가를 확인해야 하는 경우, 아마도 CLI 도구에서 흔히 볼 수 있는 "Would you like to do this? (y/n)"라는 인기 있는 형식으로 readline.question ()를 사용하는 방법입니다.

Readline이 제공하는 또 다른 기능은 프롬프트입니다. 프롬프트는 기본 ">" 문자로 사용자 정의할 수 있고 입력을 방지하기 위해 일시적으로 일시 중지할 수 있습니다. Readline 채팅 클라이언트의 경우 이것이 기본 인터페이스가 됩니다. 한 번만 나타납니다 readline.question() 来询问用户昵称,但其他所有内容都将是 readline.prompt().

종속성 관리

지루한 부분인 종속성부터 시작해 보겠습니다. 프로젝트는 socket.iosocket.io-client 包和 ansi-color。您的 packages.json를 사용할 것입니다. 파일은 다음과 같아야 합니다:

으아아아

달려npm install 그게 전부입니다.

서버

이 튜토리얼에서는 매우 간단한 Socket.io 서버를 사용합니다. 이보다 더 기본적인 것은 없습니다:

으아아아

한 클라이언트로부터 들어오는 메시지를 받아 다른 모든 사람에게 전달하는 것이 전부입니다. 대규모 애플리케이션의 경우 서버가 더 강력할 수 있지만 이 간단한 예에서는 충분합니다.

이것은 프로젝트 디렉토리에 server.js라는 이름으로 저장되어야 합니다.

클라이언트: 포함 및 설정

재미있는 부분에 도달하기 전에 종속성을 포함하고, 일부 변수를 정의하고, Readline 인터페이스와 소켓 연결을 시작해야 합니다.

으아아아

이 시점에서 코드는 거의 설명이 필요합니다. 우리는 이미 별명 변수, 소켓 연결(socket.io-client 패키지를 통해) 및 Readline 인터페이스를 가지고 있습니다.

이 예에서 Socket.io는 포트3636를 통해 localhost에 연결합니다. 물론 프로덕션 채팅 애플리케이션을 만드는 경우 자체 서버의 도메인과 포트로 변경됩니다. (혼자 대화하는 것은 별로 의미가 없습니다!)

클라이언트: 사용자 이름을 물어보세요

이제 우리는 처음으로 Readline을 사용하고 있습니다! 우리는 사용자에게 채팅방에서 사용자를 식별할 닉네임을 선택하도록 요청하고 싶습니다. 이를 위해 Readline의 question() 메소드를 사용하겠습니다.

으아아아

이전 nick 변수를 사용자로부터 수집한 값으로 설정하고, 사용자가 채팅에 참여했다는 메시지를 서버에 보내고(다른 클라이언트로 전달됨) Readline 인터페이스를 다시 프롬프트 모드로 전환합니다. prompt()true 값을 전달하면 프롬프트가 올바르게 표시됩니다. (그렇지 않으면 커서가 해당 줄의 0번 위치로 이동하여 ">"이 표시되지 않을 수 있습니다.)

불행히도 Readline에는 prompt() 메서드와 관련된 실망스러운 문제가 있습니다. 텍스트를 프롬프트 문자와 동일한 줄에 출력하고 "prompt() 方法方面存在令人沮丧的问题。它与 console.log() 配合得不太好,它会将文本输出到与提示字符相同的行,从而在各处留下杂散的“>”字符和其他字符怪异。为了解决这个问题,我们不会在此应用程序中的任何位置使用 console.log>s 모든 곳에

" 문자와 기타 문자를 남겨두는 console.log()에서는 제대로 작동하지 않습니다. 이상한 캐릭터. 이 문제를 해결하기 위해 우리는 이 애플리케이션의 어느 곳에서도 console.log를 사용하지 않을 것입니다. 대신 출력이 다음 함수로 전달되어야 합니다.

으아아아 약간

해키 솔루션은 출력을 인쇄하기 전에 콘솔의 현재 줄이 비어 있고 커서가 0 위치에 있는지 확인합니다. 그런 다음 명시적으로 프롬프트를 다시 출력하도록 요청합니다.

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿