В этой статье используется node+express+jquery для создания персонализированного чата, давайте вместе~ (адрес источника см. в конце статьи)
визуализация
Структура проекта
реализовать функцию
- Обнаружение входа
- Система автоматически подсказывает статус пользователя (вход/выход)
- показать онлайн пользователей
- Поддержка отправки и получения сообщений
- пользовательский цвет шрифта
- Поддержка отправки смайликов, картинок, дрожания окон
Далее будет объяснено, как достичь
Предварительная подготовка
узел и среда npm,express,socket.io
Выполнение
1. Разверните чат на сервере
Сначала создайте сервер с узлом, разверните его на порту localhost:3000, сначала попробуйте отправить «hello world» в браузер и создайте новый файл server.js.
var app = require('express')(); // 引入express模块
var http = require('http').Server(app);
app.get('/', function(req, res){ // 路由为localhost:3000时向客户端响应“hello world”
res.send('<h1>Hello world</h1>'); // 发送数据
});
http.listen(3000, function(){ // 监听3000端口
console.log('listening on *:3000');
});
Откройте браузер и введите URL-адрес: localhost:3000 выглядит следующим образом.
Узловой сервер успешно построен.Затем используйте экспресс, чтобы вернуть html-страницу в браузер.
#安装express模块
npm install --save express
Измените код server.js на:
var express = require('express');
var app = express();
var http = require('http').Server(app);
// 路由为/默认www静态文件夹
app.use('/', express.static(__dirname + '/www'));
express.static(__dirname + '/www'); предназначен для размещения папки www в качестве статического ресурса, что означает, что файлы (html, css, js) в этой папке могут использовать относительные пути друг к другу. Добавьте файл index.html и соответствующий css в папку www (соответствующий код css не будет опубликован, подробности см. в исходном коде), как показано ниже, на странице используется маленький значок с потрясающим шрифтом.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>chat</title>
<link rel="stylesheet" href="style/index.css">
<link rel="stylesheet" href="style/font-awesome-4.7.0/css/font-awesome.min.css">
</head>
<body>
<div class="all">
<div class="name">
<!-- <h2>请输入你的昵称</h2> -->
<input type="text" id="name" placeholder="请输入昵称..." autocomplete="off">
<button id="nameBtn">确 定</button>
</div>
<div class="main">
<div class="header">
<img src="image/logo.jpg">
happy聊天室
</div>
<div id="container">
<div class="conversation">
<ul id="messages"></ul>
<form action="">
<div class="edit">
<input type="color" id="color" value="#000000">
<i title="双击取消选择" class="fa fa-smile-o" id="smile">
</i><i title="双击取消选择" class="fa fa-picture-o" id="img"></i>
<div class="selectBox">
<div class="smile">
</div>
<div class="img">
</div>
</div>
</div>
<!-- autocomplete禁用自动完成功能 -->
<textarea id="m"></textarea>
<button class="btn rBtn" id="sub">发送</button>
<button class="btn" id="clear">关闭</button>
</form>
</div>
<div class="contacts">
<h1>在线人员(<span id="num">0</span>)</h1>
<ul id="users"></ul>
<p>当前无人在线哟~</p>
</div>
</div>
</div>
</div>
</body>
</html>
Откройте localhost:3000 и вы увидите следующее:
Чат успешно развернут на сервере.2. Обнаружить логин
Socket.io требуется для передачи сообщений между клиентом и сервером.
#安装socket.io模块
npm install --save socket.io
Измените server.js следующим образом:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use('/', express.static(__dirname + '/www'));
io.on('connection', function(socket){ // 用户连接时触发
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
При открытии localhost:3000 будет инициировано событие подключения серверного ввода-вывода, и на сервере будет напечатано «пользователь подключен», но мы хотим подсчитать количество пользователей, подключенных к серверу. пользовательское соединение, напечатайте "n пользователей подключено", n - количество пользователей, что мне делать?
Установите глобальный массив как пользователь в server.js. Всякий раз, когда пользователь успешно подключается, вставьте псевдоним пользователя в user в событии подключения и напечатайте user.length, чтобы узнать количество пользователей, которые успешно подключились.
Подождите минуту.
Когда пользователь подключается, чтобы ввести псевдоним для входа в систему, мы должны проверить, существует ли уже псевдоним пользователя, чтобы избежать того же псевдонима.Сервер прослушивает событие входа в систему, чтобы оценить ситуацию.Поскольку все происходит после подключения пользователя, событие срабатывает.Должно быть записано в функции обратного вызова события соединения.
io.on('connection', (socket)=> {
// 渲染在线人员
io.emit('disUser', usersInfo);
// 登录,检测用户名
socket.on('login', (user)=> {
if(users.indexOf(user.name) > -1) { // 昵称是否存在
socket.emit('loginError'); // 触发客户端的登录失败事件
} else {
users.push(user.name); //储存用户的昵称
usersInfo.push(user); // 储存用户的昵称和头像
socket.emit('loginSuc'); // 触发客户端的登录成功事件
socket.nickname = user.name;
io.emit('system', { // 向所有用户广播该用户进入房间
name: user.name,
status: '进入'
});
io.emit('disUser', usersInfo); // 渲染右侧在线人员信息
console.log(users.length + ' user connect.'); // 打印连接人数
}
});
Сначала будут проигнорированы события system и disUser, которые будут обсуждаться позже. Различают io.emit(foo), socket.emit(foo), socket.broadcast.emit(foo)
io.emit(foo); //会触发所有客户端用户的foo事件
socket.emit(foo); //只触发当前客户端用户的foo事件
socket.broadcast.emit(foo); //触发除了当前客户端用户的其他用户的foo事件
Далее код клиента chat-client.js
$(function() {
// io-client
// 连接成功会触发服务器端的connection事件
var socket = io();
// 点击输入昵称
$('#nameBtn').click(()=> {
var imgN = Math.floor(Math.random()*4)+1; // 随机分配头像
if($('#name').val().trim()!=='')
socket.emit('login', { // 触发服务器端登录事件
name: $('#name').val(),
img: 'image/user' + imgN + '.jpg'
});
return false;
});
// 登录成功,隐藏登录层
socket.on('loginSuc', ()=> {
$('.name').hide();
})
socket.on('loginError', ()=> {
alert('用户名已存在,请重新输入!');
$('#name').val('');
});
});
Если авторизация прошла успешно, вы увидите следующую страницу:
Определение входа завершено.3. Система автоматически подсказывает статус пользователя (вход/выход)
Эта функция предназначена для реализации системного приглашения «XXX входит в комнату чата», как показано на рисунке выше, инициирования системного события при успешном входе в систему и передачи информации всем пользователям.Обратите внимание, что вместо сокета используется io.emit. испускать в это время, и код клиента показывает, как показано ниже
// 系统提示消息
socket.on('system', (user)=> {
var data = new Date().toTimeString().substr(0, 8);
$('#messages').append(`<p class='system'><span>${data}</span><br /><span>${user.name} ${user.status}了聊天室<span></p>`);
// 滚动条总是在最底部
$('#messages').scrollTop($('#messages')[0].scrollHeight);
});
4. Показать онлайн-пользователей
Клиент прослушивает событие disUser, которое отображает онлайн-пользователей, а сервер запускает событие для повторного рендеринга один раз в следующие три периода времени.
- Когда программа запускается
- всякий раз, когда пользователь входит в комнату
- всякий раз, когда пользователь выходит из комнаты
// chat-client.js
// 显示在线人员
socket.on('disUser', (usersInfo)=> {
displayUser(usersInfo);
});
// 显示在线人员
function displayUser(users) {
$('#users').text(''); // 每次都要重新渲染
if(!users.length) {
$('.contacts p').show();
} else {
$('.contacts p').hide();
}
$('#num').text(users.length);
for(var i = 0; i < users.length; i++) {
var $html = `<li>
<img src="${users[i].img}">
<span>${users[i].name}</span>
</li>`;
$('#users').append($html);
}
}
5. Поддержка отправки и получения сообщений
Когда пользователь отправляет сообщение, на стороне сервера запускается событие sendMsg, а содержимое сообщения используется в качестве параметра. .излучать(фу)
// server.js
// 发送消息事件
socket.on('sendMsg', (data)=> {
var img = '';
for(var i = 0; i < usersInfo.length; i++) {
if(usersInfo[i].name == socket.nickname) {
img = usersInfo[i].img;
}
}
socket.broadcast.emit('receiveMsg', { // 向除了发送者之外的其他用户广播
name: socket.nickname,
img: img,
msg: data.msg,
color: data.color,
side: 'left'
});
socket.emit('receiveMsg', { // 向发送者发送消息,为什么分开发送?因为css样式不同
name: socket.nickname,
img: img,
msg: data.msg,
color: data.color,
side: 'right'
});
});
После того, как сервер получит сообщение от пользователя, он вызовет событие ReceiveMsg клиента и передаст сообщение, отправленное пользователем, в качестве параметра. Это событие добавит содержимое чата на панель чата. Ниже приведен чат-клиент. .js-код
// 点击按钮或回车键发送消息
$('#sub').click(sendMsg);
$('#m').keyup((ev)=> {
if(ev.which == 13) {
sendMsg();
}
});
// 接收消息
socket.on('receiveMsg', (obj)=> { // 将接收到的消息渲染到面板上
$('#messages').append(`
<li class='${obj.side}'>
<img src="${obj.img}">
<div>
<span>${obj.name}</span>
<p>${obj.msg}</p>
</div>
</li>
`);
// 滚动条总是在最底部
$('#messages').scrollTop($('#messages')[0].scrollHeight);
});
// 发送消息
function sendMsg() {
if($('#m').val() == '') { // 输入消息为空
alert('请输入内容!');
return false;
}
socket.emit('sendMsg', {
msg: $('#m').val()
});
$('#m').val('');
return false;
}
6. Настройте цвет шрифта
Благодаря новой функции ввода html5 системную палитру можно вызывать через ввод, тип которого — цвет.
<!-- $('#color').val();为选中颜色,格式为#FFCCBB -->
<input type='color' id='color'>
Клиент отображает стиль содержимого в соответствии с цветом, выбранным пользователем, а код прост для понимания, поэтому я не буду здесь вдаваться в подробности.
7. Поддержка отправки выражений
Отправить смайлик на самом деле очень просто: поместите изображение смайлика в li, и когда пользователь щелкнет li, серийный номер в src смайлика будет проанализирован и сохранен в окне чата в формате [смайлик + серийный номер смайлика ]. После нажатия кнопки «Отправить» он будет проанализирован как src. Это процесс парсинга и восстановления, во время которого наш серверный код остается неизменным, нужно изменить событие receiveMsg, отслеживаемое клиентом.
// chat-client.js
// 显示表情选择面板
$('#smile').click(()=> {
$('.selectBox').css('display', "block");
});
$('#smile').dblclick((ev)=> {
$('.selectBox').css('display', "none");
});
$('#m').click(()=> {
$('.selectBox').css('display', "none");
});
// 用户点击发送表情
$('.emoji li img').click((ev)=> {
ev = ev || window.event;
var src = ev.target.src;
var emoji = src.replace(/\D*/g, '').substr(6, 8); // 提取序号
var old = $('#m').val(); // 用户输入的其他内容
$('#m').val(old+'[emoji'+emoji+']');
$('.selectBox').css('display', "none");
});
После того, как клиент его получает, он восстанавливает порядковый номер выражения в src, и изменения следующие:
// chat-client.js
// 接收消息
socket.on('receiveMsg', (obj)=> {
// 提取文字中的表情加以渲染
var msg = obj.msg;
var content = '';
while(msg.indexOf('[') > -1) { // 其实更建议用正则将[]中的内容提取出来
var start = msg.indexOf('[');
var end = msg.indexOf(']');
content += '<span>'+msg.substr(0, start)+'</span>';
content += '<img src="image/emoji/emoji%20('+msg.substr(start+6, end-start-6)+').png">';
msg = msg.substr(end+1, msg.length);
}
content += '<span>'+msg+'</span>';
$('#messages').append(`
<li class='${obj.side}'>
<img src="${obj.img}">
<div>
<span>${obj.name}</span>
<p style="color: ${obj.color};">${content}</p>
</div>
</li>
`);
// 滚动条总是在最底部
$('#messages').scrollTop($('#messages')[0].scrollHeight);
});
Смайлик может быть успешно отправлен.
8. Поддержка отправки изображений
Во-первых, это стиль кнопки изображения, кнопка, которая отправляет изображение, является вводом типа файла. Вот небольшой трюк, чтобы изменить стиль, то есть установить непрозрачность ввода на 0, z-index на 5, поместить нужный стиль в div и установить z-index на 1, чтобы наложить ввод.
<input type="file" id="file">
<i class="fa fa-picture-o" id="img"></i>
css:
.edit #file {
width: 32.36px;
height: 29px;
opacity: 0;
z-index: 5;
}
.edit #img {
z-index: 0;
margin-left: -43px;
}
Идеально
Следующим шагом является нажатие кнопки для отправки изображения. Мы использовали объект fileReader. Вот хорошая статья, объясняющая fileReader. FileReader — это объект, который может выводить выбранный файл в 64-битном формате и сохранять результат в reader.result , После выбора изображения, reader.result сохраняет src изображения.// chat-client.js
// 用户发送图片
$('#file').change(function() {
var file = this.files[0]; // 上传单张图片
var reader = new FileReader();
//文件读取出错的时候触发
reader.onerror = function(){
console.log('读取文件失败,请重试!');
};
// 读取成功后
reader.onload = function() {
var src = reader.result; // 读取结果
var img = '<img class="sendImg" src="'+src+'">';
socket.emit('sendMsg', { // 发送
msg: img,
color: color,
type: 'img' // 发送类型为img
});
};
reader.readAsDataURL(file); // 读取为64位
});
Поскольку отправляются изображения, это неизбежно повлияет на макет страницы.Ради красоты страницы клиент сначала определит, отправляется ли текст или изображения при получении сообщений от других пользователей, и отобразит разные макеты в соответствии с разными результатами. Метод оценки заключается в передаче типа, когда клиент отправляет сообщение, и в соответствии со значением типа тип отправляемого контента действительно отправляется. Поэтому в коде отправки картинки выше срабатывает событие sendMsg, а входящий параметр имеет дополнительный атрибут типа.
В ответ мы должны изменить функцию прослушивания событий receiveMsg в chat-client.js, чтобы выполнять различные операции в зависимости от входящего типа.
chat-client.js
// 接收消息
socket.on('receiveMsg', (obj)=> {
// 发送为图片
if(obj.type == 'img') {
$('#messages').append(`
<li class='${obj.side}'>
<img src="${obj.img}">
<div>
<span>${obj.name}</span>
<p style="padding: 0;">${obj.msg}</p>
</div>
</li>
`);
$('#messages').scrollTop($('#messages')[0].scrollHeight);
return;
}
// 提取文字中的表情加以渲染
// 下面不变
});
Теперь мы можем отправлять фотографии
7. Отправить дрожание окна
Когда пользователь нажимает кнопку встряхивания, событие встряхивания сервера будет отправлено, и сервер будет транслировать событие, так что каждый клиент будет встряхивать окно.
// chat-client.js
// 用户发送抖动
$('.edit #shake').click(function() {
socket.emit('shake');
});
// server.js
// 发送窗口抖动
socket.on('shake', ()=> {
socket.emit('shake', {
name: '您'
});
socket.broadcast.emit('shake', {
name: socket.nickname
});
});
Реализовать анимацию css3 для дрожания окна
.edit .selectBox {
position: absolute;
bottom: 34px;
left: 0px;
}
.shaking {
animation: run 0.2s infinite;
}
@keyframes run {
0% {
left: 0;
}
25% {
left: -7px;
}
50% {
left: 7px;
}
100% {
left: 0;
}
}
Полностью завершите полнофункциональный чат!
Адрес источника:windlany/happy-chat,Эта статья писалась от случая к случаю два дня.На самом деле писать статьи более утомительно,чем набирать код...На самом деле написать чат не сложно.Это стартовая работа ноды. Если вы заинтересованы, вы можете раскошелиться и изменить его в соответствии с вашими потребностями.Если вы чувствуете себя хорошо, пожалуйста, дайте мне звезду.
Ссылка на ссылку