Socketio搭建一个聊天室
前言
本次实验所用编程语言为HTML
以及javascript
和JQurey
语言和Socketio
框架,所用编辑文本工具为VS code
。
注意事项
(1)前端编程注意HTML
语言的灵活运用以及javascript
语言的使用。
(2)所要使用图片自己上网寻找替换即可。
(3)由于涉及隐私问题,所以代码实现效果图没有全部放出来。
(4)本文章主要用于大家学习参考,博客中代码按照步骤来即可执行使用,但请不要商用。。
(5)本聊天室功能参照B站视频完成,视频网址如下:https://www.bilibili.com/video/BV14K411T7cd?from=search&seid=16452167357705157739
。
聊天室具体功能
1、完成点对点即时的文本消息聊天功能。
2、实现Web的表情的发送、接收和显示功能。
3、实现Web的图片的发送、接收和显示功能。
4、实现本地消息的存储,在离线的时候也能加载和查看历史消息。
5、实现本地截图工具的调用。
6、实现视频的传输。
聊天室具体实现步骤
1、将VS code
安装好。
(步骤一:进入VS code
官网下载VS code
安装包。)
(步骤二:选好安装路径,安装步骤直接默认即可。)
2、安装node.js
。
(步骤一:进入node.js
官网下载node.js
安装包。注意点击图中红线所画,下载稳定版本。)
(步骤二:选好安装路径,安装步骤直接默认即可。)
3、打开VS code
,创建一个文件夹,再在文件夹下创建一个文件命名为app.js
。
4、右击app.js,点击图中红线所划打开终端。
5、在终端中执行指令yarn add nodejs-websocket
添加node_modules
。
(本步骤可能遇到的报错一:)
(问题原因:Windows
没有安装yarn
)
(解决办法:在Windows
上安装yarn
)
【步骤一:运用管理员身份打开Windws PowerShell
】
【步骤二:在Windws PowerShell
按照如下图所示执行指令】
6、在文件app.js
中写如下代码。 (注:app.js
是服务器文件)
/*
启动聊天的服务端程序
*/
var app = require('express')()
var server = require('http').Server(app)
var io = require('socket.io')(server)
// 记录所有已经登录过的用户
const users = []
server.listen(3000, () => {
console.log('服务器启动成功了')
})
// express处理静态资源
// 把public目录设置为静态资源目录
app.use(require('express').static('public'))
app.get('/', function(req, res) {
res.redirect('/index.html')
})
io.on('connection', function(socket) {
socket.on('login', data => {
// 判断,如果data在users中存在,说明该用户已经登录了,不允许登录
// 如果data在users中不存在,说明该用户没有登录,允许用户登录
let user = users.find(item => item.username === data.username)
if (user) {
// 表示用户存在, 登录失败. 服务器需要给当前用户响应,告诉登录失败
socket.emit('loginError', { msg: '登录失败' })
// console.log('登录失败')
} else {
// 表示用户不存在, 登录成功
users.push(data)
// 告诉用户,登录成功
socket.emit('loginSuccess', data)
// console.log('登录成功')
// 告诉所有的用户,有用户加入到了聊天室,广播消息
// socket.emit: 告诉当前用户
// io.emit : 广播事件
io.emit('addUser', data)
// 告诉所有的用户,目前聊天室中有多少人
io.emit('userList', users)
// 把登录成功的用户名和头像存储起来
socket.username = data.username
socket.avatar = data.avatar
}
})
// 用户断开连接的功能
// 监听用户断开连接
socket.on('disconnect', () => {
// 把当前用户的信息从users中删除掉
let idx = users.findIndex(item => item.username === socket.username)
// 删除掉断开连接的这个人
users.splice(idx, 1)
// 1. 告诉所有人,有人离开了聊天室
io.emit('delUser', {
username: socket.username,
avatar: socket.avatar
})
// 2. 告诉所有人,userList发生更新
io.emit('userList', users)
})
// 监听聊天的消息
socket.on('sendMessage', data => {
console.log(data)
// 广播给所有用户
io.emit('receiveMessage', data)
})
// 接收图片信息
socket.on('sendImage', data => {
// 广播给所有用户
console.log(data);
io.emit('receiveImage', data)
})
// 接收视频信息
socket.on('sendVideo',data=>{
//广播给所有用户
console.log(data)
io.emit('receiveVideo', data)
})
})
7、在wechart
文件夹下创建一个public
文件夹,用来存放css
文件和js
文件和images
文件以及配置文件和index.html
文件。
(注:index.html
文件中代码如下:)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>聊天室</title>
<link rel="stylesheet" href="lib/jquery-mCustomScrollbar/css/jquery.mCustomScrollbar.min.css"/>
<link rel="stylesheet" href="lib/jquery-emoji/css/jquery.emoji.css"/>
<link rel="stylesheet" href="css/index.css" />
</head>
<body>
<div class="login_box" style="display: block;">
<h3>用户登录</h3>
<p>用户名</p>
<input type="text" placeholder="请输入用户名" id="username" />
<p>选择头像</p>
<ul class="avatar" id="login_avatar">
<li class="now"><img src="images/avatar01.jpg" alt="" /></li>
<li><img src="images/avatar02.jpg" alt="" /></li>
<li><img src="images/avatar03.jpg" alt="" /></li>
<li><img src="images/avatar04.jpg" alt="" /></li>
<li><img src="images/avatar05.jpg" alt="" /></li>
<li><img src="images/avatar06.jpg" alt="" /></li>
<li><img src="images/avatar07.jpg" alt="" /></li>
<li><img src="images/avatar08.jpg" alt="" /></li>
<li><img src="images/avatar09.jpg" alt="" /></li>
<li><img src="images/avatar10.jpg" alt="" /></li>
</ul>
<button class="weui-btn" id="loginBtn">登录</button>
</div>
<div class="container" style="display: none;">
<!-- 用户列表 -->
<div class="user-list">
<div class="header">
<div class="avatar">
<img class="img avatar_url" src="images/avatar2.jpg" alt="" />
</div>
<div class="info">
<!-- -->
<h3 class="username">清流</h3>
</div>
</div>
<div class="title"><h3>用户列表</h3></div>
<ul>
</ul>
</div>
<!-- 聊天主窗口 -->
<div class="box">
<!-- 聊天窗口头部 -->
<div class="box-hd"><h3>聊天室(<span id="userCount">99</span>)</h3></div>
<!-- 聊天窗口主体区域 -->
<div class="box-bd">
<!--
<div class="system">
<p class="message_system">
<span class="content">"往事随风"邀请你和"Boy"加入了群聊</span>
</p>
</div>
<div class="message-box">
<div class="my message">
<img class="avatar" src="images/avatar2.jpg" alt="" />
<div class="content">
<div class="bubble">
<div class="bubble_cont">在干嘛</div>
</div>
</div>
</div>
</div>
<div class="message-box">
<div class="other message">
<img class="avatar" src="images/avatar02.jpg" alt="" />
<div class="content">
<div class="nickname">小美</div>
<div class="bubble">
<div class="bubble_cont">吃饭</div>
</div>
</div>
</div>
</div>
-->
</div>
<!-- 聊天窗口底部区域 -->
<div class="box-ft">
<!-- 工具栏 -->
<div class="toolbar">
<a href="javascript:;" title="表情" class="face"></a>
<a href="Go://调用截图" title="截屏" class="screen-cut">
<!--<label for="screen-cut"></label>
<input type="file" style="display: none;" id="screen-cut"/>-->
</a>
<a href="javascript:;" title="图片" class="file">
<label for="file"></label>
<input type="file" id="file" style="display: none;">
</a>
<a href="javascript:;" title="视频" class="videos">
<label for="videos"></label>
<input type="file" style="display: none;" id="videos"/>
<!--<input type="file" id="videos" style="display: none;"></input>-->
</a>
</div>
<!-- 内容输入区域 -->
<div class="content">
<!-- div添加一个属性:contenteditable -->
<div class="text" id="content" contenteditable></div>
</div>
<!-- 发送按钮 -->
<div class="action">
<span class="desc">按下Ctrl+Enter发送</span>
<a class="btn-send" id="btn-send" href="javascript:;">发送</a>
</div>
</div>
</div>
</div>
</div>
<!-- 引入socketio -->
<script src="/socket.io/socket.io.js"></script>
<script src="js/jquery-1.12.4.js"></script>
<script src="lib/jquery-mCustomScrollbar/script/jquery.mCustomScrollbar.min.js"></script>
<script src="lib/jquery-emoji/js/jquery.emoji.min.js"></script>
<script src="js/index.js"></script>
<!--<script src="js/jquery-1.4.1.min.js"></script>-->
</body>
</html>
(注:index.css
文件中代码如下:)
* {
margin: 0;
padding: 0;
list-style: none;
}
html,
body {
height: 100%;
}
body {
background: url('../images/bg.jpg') no-repeat center center;
background-size: cover;
}
.container {
max-width: 1000px;
min-width: 800px;
height: 100%;
margin: 0 auto;
background-color: pink;
}
/*用户列表*/
.user-list {
width: 280px;
height: 100%;
float: left;
position: relative;
/*background-color:#2e3238;*/
background-color: #a5aebd;
}
/*聊天主窗口*/
.box {
overflow: hidden;
height: 100%;
background-color: #eee;
position: relative;
}
/*聊天窗口头部*/
.box-hd {
text-align: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
line-height: 30px;
}
/*聊天窗口头部文字*/
.box-hd h3 {
font-size: 18px;
font-weight: 400;
padding: 10px 0;
margin: 0 20px;
border-bottom: 1px solid #ccc;
z-index: 999;
box-sizing: border-box;
}
.message-box {
overflow: hidden;
}
/*聊天窗口主体部分*/
.box-bd {
position: absolute;
width: 100%;
bottom: 180px;
top: 51px;
overflow-y: auto;
overflow-x: hidden;
}
.system {
overflow: hidden;
}
.message_system {
text-align: center;
margin: 10px auto;
max-width: 50%;
}
.message_system .content {
display: inline-block;
font-size: 12px;
padding: 1px 18px;
color: #b2b2b2;
border-radius: 2px;
}
.other {
margin-bottom: 16px;
float: left;
width: 100%;
padding-left: 20px;
box-sizing: border-box;
}
.my {
margin-bottom: 16px;
float: right;
width: 100%;
text-align: right;
padding-right: 20px;
box-sizing: border-box;
}
.my.message .avatar {
float: right;
}
.message .content {
overflow: hidden;
}
.message .content .nickname {
font-weight: 400;
padding-left: 10px;
font-size: 12px;
height: 22px;
line-height: 24px;
color: #4f4f4f;
width: 350px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
}
.message .avatar {
width: 40px;
height: 40px;
border-radius: 2px;
float: left;
cursor: pointer;
}
.my.message .bubble {
background-color: #b2e281;
}
.message .bubble {
max-width: 500px;
min-height: 1em;
display: inline-block;
vertical-align: top;
position: relative;
text-align: left;
font-size: 14px;
border-radius: 3px;
margin: 0 10px;
background-color: #fff;
}
/*图片信息*/
.message .bubble img {
display: inline-block;
cursor: pointer;
max-width: 350px;
max-height: 240px;
}
/*自己消息信息*/
.message .bubble video {
display: inline-block;
cursor: pointer;
max-width: 350px;
max-height: 240px;
}
.other .bubble:before {
position: absolute;
top: 14px;
left: -10px;
border: 6px solid transparent;
content: ' ';
border-right-color: #fff;
border-right-width: 4px;
}
.my .bubble:before {
position: absolute;
top: 14px;
right: -10px;
border: 6px solid transparent;
content: ' ';
border-left-color: #b2e281;
border-left-width: 4px;
}
.bubble_cont {
word-wrap: break-word;
word-break: break-all;
min-height: 25px;
padding: 9px 13px;
}
/*他人视频消息*/
.bubble_cont video {
word-wrap: break-word;
word-break: break-all;
min-height: 25px;
padding: 9px 13px;
}
/*聊天窗口底部区域*/
.box-ft {
border-top: 1px solid #ccc;
position: absolute;
height: 180px;
bottom: 0;
right: 0;
left: 0;
}
.box-ft .toolbar {
height: 30px;
padding: 5px 20px;
}
.box-ft .toolbar .face {
display: inline-block;
vertical-align: middle;
width: 30px;
height: 30px;
background: url('../images/wechat-sprit.png') no-repeat -404px -398px;
}
.box-ft .toolbar .screen-cut {
display: inline-block;
vertical-align: middle;
width: 30px;
height: 30px;
background: url('../images/wechat-sprit.png') no-repeat -30px -432px;
}
/*聊天窗口底部截屏*/
.box-ft .toolbar .screen-cut label {
opacity: 0;
width: 100%;
height: 100%;
display: block;
cursor: pointer;
background: rgb(255, 255, 255);
}
.box-ft .toolbar .file label {
opacity: 0;
width: 100%;
height: 100%;
display: block;
cursor: pointer;
background: rgb(255, 255, 255);
}
.box-ft .toolbar .file {
display: inline-block;
vertical-align: middle;
width: 30px;
height: 30px;
background: url('../images/wechat-sprit.png') no-repeat -120px -432px;
}
.box-ft .toolbar .videos label {
opacity: 0;
width: 100%;
height: 100%;
display: block;
cursor: pointer;
background: rgb(255, 255, 255);
}
/*视频按钮*/
.box-ft .toolbar .videos {
display: inline-block;
vertical-align: middle;
width: 30px;
height: 30px;
background: url('../images/wechat-sprit.png') no-repeat -430px -398px;
}
.box-ft .content {
height: 90px;
overflow-x: hidden;
padding: 0px 20px;
}
.box-ft .content .text {
resize: none;
border: none;
outline: none;
width: 100%;
height: 84px;
font-size: 16px;
background-color: #eee;
}
.box-ft .action {
text-align: right;
margin-top: 5px;
padding-right: 20px;
}
.box-ft .action .desc {
color: #888;
font-size: 12px;
margin-left: 10px;
margin-right: 7px;
}
.btn-send {
display: inline-block;
border: 1px solid #c1c1c1;
text-decoration: none;
background-color: #fff;
color: #222;
border-radius: 4px;
padding: 3px 30px;
font-size: 14px;
}
.btn-send:hover {
background-color: #d8d8d8;
}
.header {
padding: 18px;
position: relative;
}
.header .avatar {
display: table-cell;
vertical-align: middle;
word-wrap: break-word;
word-break: break-all;
white-space: nowrap;
padding-right: 10.625px;
}
.header .avatar .img {
width: 40px;
height: 40px;
border-radius: 2px;
display: block;
cursor: pointer;
}
.header .info {
display: table-cell;
vertical-align: middle;
word-wrap: break-word;
word-break: break-all;
width: 2000px;
}
.header .info h3 {
display: inline-block;
font-weight: 400;
width: 156px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
color: #fff;
font-size: 18px;
vertical-align: top;
line-height: 31px;
text-decoration: none;
}
.title {
padding: 13px 18px 11px;
border-bottom: 1px solid #24272c;
border-top: 1px solid #24272c;
color: #fff;
}
.title h3 {
font-weight: 400;
font-size: 18px;
}
.user {
overflow: hidden;
padding: 12px 18px 11px;
border-bottom: 1px solid #292c33;
cursor: pointer;
position: relative;
}
.user .avatar {
float: left;
margin-right: 10px;
position: relative;
}
.user .avatar img {
display: block;
width: 40px;
height: 40px;
border-radius: 2px;
}
.user .name {
color: #fff;
overflow: hidden;
line-height: 36px;
}
.login_box {
position: absolute;
top: 50%;
left: 50%;
width: 380px;
height: 380px;
transform: translate(-50%, -50%);
border-radius: 4px;
/*background-color: #fff;*/
background-color: rgba(128, 128, 128, 0.801);
box-shadow: #999 0 2px 10px;
}
.login_box h3 {
text-align: center;
color: #ffffff;
/*color: #333;*/
font-size: 24px;
font-weight: 400;
line-height: 100px;
}
.login_box input {
width: 300px;
height: 30px;
line-height: 30px;
margin: 0 auto;
padding: 0;
display: block;
outline: none;
margin-bottom: 5px;
}
.weui-btn {
position: relative;
display: block;
width: 300px;
margin: 0 auto;
box-sizing: border-box;
font-size: 14px;
text-align: center;
text-decoration: none;
color: #ffffff;
line-height: 2.55555556;
border-radius: 5px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
overflow: hidden;
background-color:lightgray;
/*background-color: #1aad19;*/
border: none;
cursor: pointer;
margin-top: 5px;
}
.login_box ul {
overflow: hidden;
width: 280px;
margin: 0 auto;
border: 1px solid rgba(128, 128, 128, 0.801);
/*border: 1px solid #ccc;*/
padding: 0 10px;
}
.login_box li {
float: left;
width: 44px;
height: 44px;
border: 2px solid transparent;
margin: 0 4px;
cursor: pointer;
}
.login_box li.now {
/*border-color: #1aad19;*/
border-color:honeydew;
}
.login_box img {
width: 40px;
height: 40px;
display: block;
}
.login_box p {
height: 30px;
line-height: 30px;
padding-left: 38px;
color: #ffffff;
}
::-webkit-scrollbar-track-piece {
background-color: #f8f8f8;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
border-radius: 3px;
}
::-webkit-scrollbar-thumb {
background-color: #ccc;
background-clip: padding-box;
min-height: 28px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #666;
}
(注:index.js
文件中代码如下:)
/*
聊天室的主要功能
*/
/*
1. 连接socketio服务
*/
var socket = io('http://localhost:3000')
var username, avatar
/*
2. 登录功能
*/
$('#login_avatar li').on('click', function() {
$(this)
.addClass('now')
.siblings()
.removeClass('now')
})
// 点击按钮,登录
$('#loginBtn').on('click', function() {
// 获取用户名
var username = $('#username')
.val()
.trim()
if (!username) {
alert('请输入用户名')
return
}
// 获取选择的头像
var avatar = $('#login_avatar li.now img').attr('src')
// 需要告诉socket io服务,登录
socket.emit('login', {
username: username,
avatar: avatar
})
})
// 监听登录失败的请求
socket.on('loginError', data => {
alert('用户名已经存在')
})
// 监听登录成功的请求
socket.on('loginSuccess', data => {
// 需要显示聊天窗口
// 隐藏登录窗口
$('.login_box').fadeOut()
$('.container').fadeIn()
// 设置个人信息
console.log(data)
$('.avatar_url').attr('src', data.avatar)
$('.user-list .username').text(data.username)
username = data.username
avatar = data.avatar
})
// 监听添加用户的消息
socket.on('addUser', data => {
// 添加一条系统消息
$('.box-bd').append(`
<div class="system">
<p class="message_system">
<span class="content">${data.username}加入了群聊</span>
</p>
</div>
`)
scrollIntoView()
})
// 监听用户列表的消息
socket.on('userList', data => {
// 把userList中的数据动态渲染到左侧菜单
$('.user-list ul').html('')
data.forEach(item => {
$('.user-list ul').append(`
<li class="user">
<div class="avatar"><img src="${item.avatar}" alt="" /></div>
<div class="name">${item.username}</div>
</li>
`)
})
$('#userCount').text(data.length)
})
// 监听用户离开的消息
socket.on('delUser', data => {
// 添加一条系统消息
$('.box-bd').append(`
<div class="system">
<p class="message_system">
<span class="content">${data.username}离开了群聊</span>
</p>
</div>
`)
scrollIntoView()
})
// 聊天功能
$('.btn-send').on('click', () => {
// 获取到聊天的内容
var content = $('#content').html()
$('#content').html('')
if (!content) return alert('请输入内容')
// 发送给服务器
socket.emit('sendMessage', {
msg: content,
username: username,
avatar: avatar
})
})
// 监听聊天的消息
socket.on('receiveMessage', data => {
console.log(data);
// 把接收到的消息显示到聊天窗口中
if (data.username === username) {
// 自己的消息
$('.box-bd').append(`
<div class="message-box">
<div class="my message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="bubble">
<div class="bubble_cont">${data.msg}</div>
</div>
</div>
</div>
</div>
`)
} else {
// 别人的消息
$('.box-bd').append(`
<div class="message-box">
<div class="other message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="nickname">${data.username}</div>
<div class="bubble">
<div class="bubble_cont">${data.msg}</div>
</div>
</div>
</div>
</div>
`)
}
scrollIntoView()
})
function scrollIntoView() {
// 当前元素的底部滚动到可视区
$('.box-bd')
.children(':last')
.get(0)
.scrollIntoView(false)
}
//发送图片功能
$('#file').on('change', function() {
var file = this.files[0]
console.log(this.files[0]);
// 需要把这个文件发送到服务器, 借助于H5新增的fileReader
var fr = new FileReader()
fr.readAsDataURL(file)
console.log("fr = " + fr.result);
fr.onload = function() {
socket.emit('sendImage', {
username: username,
avatar: avatar,
img: fr.result
})
}
})
// 监听图片聊天信息
socket.on('receiveImage', data => {
// 把接收到的消息显示到聊天窗口中
if (data.username === username) {
// 自己的消息
$('.box-bd').append(`
<div class="message-box">
<div class="my message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="bubble">
<div class="bubble_cont">
<img src="${data.img}">
</div>
</div>
</div>
</div>
</div>
`)
} else {
// 别人的消息
$('.box-bd').append(`
<div class="message-box">
<div class="other message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="nickname">${data.username}</div>
<div class="bubble">
<div class="bubble_cont">
<img src="${data.img}">
</div>
</div>
</div>
</div>
</div>
`)
}
// 等待图片加载完成,在滚动到底部
$('.box-bd img:last').on('load', function() {
scrollIntoView()
})
})
//建立一个可存取到该file的url
function getObjectURL(file) {
var url = null;
if (window.createObjectURL != undefined) { // basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file);
}
return url;
}
//传输视频消息
$("#videos").change(function () {
var objUrl = getObjectURL(this.files[0]);
console.log("1111111111");
console.log("objUrl = " + objUrl);
socket.emit('sendVideo', {
username: username,
avatar: avatar,
src: objUrl
})
});
/*
$("#screen-cut").change(function () {
console.log("22222");
location.href = '%windir%\system32\SnippingTool.exe';
});
*/
// 监听视频聊天信息
socket.on('receiveVideo', data => {
// 把接收到的消息显示到聊天窗口中
console.log(data.src);
if (data.username === username) {
// 自己的消息
$('.box-bd').append(`
<div class="message-box">
<div class="my message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="bubble">
<div class="bubble_cont">
<video style="height:auto;" src="${data.src}" id="video0" controls="controls"></video>
</div>
</div>
</div>
</div>
</div>
`)
} else {
// 别人的消息
$('.box-bd').append(`
<div class="message-box">
<div class="other message">
<img class="avatar" src="${data.avatar}" alt="" />
<div class="content">
<div class="nickname">${data.username}</div>
<div class="bubble">
<div class="bubble_cont">
<video style="height:auto;" src="${data.src}" id="video0" controls="controls"></video>
</div>
</div>
</div>
</div>
</div>
`)
}
// 等待图片加载完成,在滚动到底部
$('.box-bd src:last').on('load', function() {
scrollIntoView()
})
})
// 初始化jquery-emoji插件
$('.face').on('click', function() {
$('#content').emoji({
// 设置触发表情的按钮
button: '.face',
showTab: false,
animation: 'slide',
position: 'topRight',
icons: [
{
name: 'QQ表情',
path: 'lib/jquery-emoji/img/qq/',
maxNum: 91,
excludeNums: [41, 45, 54],
file: '.gif'
}
]
})
})
8、在js文件夹中参照网址http://eshengsky.github.io/jQuery-emoji/
添加文件,完成文件布置。
(注:最后创建文件夹结构如下)
聊天室功能实现效果如下
1、启动服务器
(步骤一:打开cmd
,按照如图所示执行指令。注:cd指令
的目的是要进入代码文件所在目录)
2、打开浏览器输入localhost:3000
,打开聊天室,进入登陆界面,输入用户名,选择头像。
3、进入登录界面以后,进行文本消息发送。
4、表情包发送。
5、截图工具调用。
6、实现图片和视频传输。