1项目展示


登陆界面

不同的端口 登陆 属于不同的用户

登陆两个端口号后的 界面

2项目基本配置

2.1参考文档 socket.io

先引入 socket.io插件

npm install --save socket.io

因为是基于express的,所以还需要install express;

npm install express --save

服务端代码(app.js)

//创建了http服务器
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);server.listen(3000);app.get('/', function (req, res) {res.sendFile(__dirname + '/online-chat.html');
});io.on('connection', function (socket) {socket.emit('send', { name: 'haha' });});

客户端代码(inline-chat)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>在线聊天室</title>
</head>
<body></body>
<script src="/socket.io/socket.io.js"></script>  //必须引入
<script>var socket = io('http://localhost:3000');  //请求3000端口socket.on('send', function (data) {  console.log(data);  });
</script>
</html>


接收到了服务端 发过来的 消息,说明配置成功了。

3.静态页面搭建

创建一个public文件夹,把所有静态资源都放进public文件夹中,如图所示

由于要使用public的静态资源,必须使用express 中的语句

// express使用静态资源
app.use(require('express').static('public'));

此时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="data:images/avatar01.jpg" alt="" /></li><li><img src="data:images/avatar02.jpg" alt="" /></li><li><img src="data:images/avatar03.jpg" alt="" /></li><li><img src="data:images/avatar04.jpg" alt="" /></li><li><img src="data:images/avatar05.jpg" alt="" /></li><li><img src="data:images/avatar06.jpg" alt="" /></li><li><img src="data:images/avatar07.jpg" alt="" /></li><li><img src="data:images/avatar08.jpg" alt="" /></li><li><img src="data:images/avatar09.jpg" alt="" /></li><li><img src="data: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="data: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="data: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="data: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="javascript:;" title="截屏" class="screen-cut"></a><a href="javascript:;" title="图片" class="file"><label for="file"></label><input type="file" id="file" style="display: none;"></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></body>
</html>

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;
}.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;
}.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;
}.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 .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 .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;box-shadow: #999 0 2px 10px;
}.login_box h3 {text-align: center;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: #1aad19;border: none;cursor: pointer;margin-top: 5px;
}.login_box ul {overflow: hidden;width: 280px;margin: 0 auto;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;
}.login_box img {width: 40px;height: 40px;display: block;
}.login_box p {height: 30px;line-height: 30px;padding-left: 38px;
}::-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;
}

4.实现简单登陆

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.usernameavatar = data.avatar
})

app.js中

let users=[];//记录所有已经登陆的用户
io.on('connection', function (socket) {socket.on("login",data=>{// 判断该账号是否已经被登陆let user = users.find(item =>item.username===data.username);if(user){//该账户已经存在,登陆失败socket.emit('login',{msg:"登录失败"})console.log("登陆失败");}else{//该用户不存在,登陆成功users.push(data);socket.emit('loginSuccess',data)  //这两个data不可以携程user,因为user是空的console.log("登陆成功");}})
});
在这里插入代码片

5在聊天室里广播告诉所有人该有的消息

5.1.告诉有人进来了

5.1.1服务端(app.js)

//广播告诉所有人 有人进来了io.emit("addUser",data);

5.1.2客户端(index.js)

// 监听添加用户的消息
socket.on('addUser', data => {// 添加一条系统消息$('.box-bd').append(`<div class="system"><p class="message_system"><span class="content">${data.username}加入了群聊</span></p></div>`)scrollIntoView();//该方法用于使聊天记录可以上下移动(这样就不会只能看到一页的聊天记录)
})

5.2.把新进来的用户的信息添加到用户列表中

5.2.1服务端(app.js)

 //把所有用户列表重新渲染出来io.emit("userList",users);

5.2.2客户端(index.js)

// 监听用户列表的消息
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)
})

5.3当有用户离开时广播告诉所有人 有某某某离开

服务端(app.js)

//把用户信息存到socket中,方便退出时,告诉大家(这一步时在登录时做的)socket.username=data.username;socket.avatar=data.avatar;

**

到这里需要解释下说明socket 和 io 的区别,io 是广播给所有用户的,而socket 是属于该登录的用户自己拥有的
当socket.emit()的时候也是把信息只发送给该用户
所以你会发现在客户端,接受的方式都是socket.on();

//当用户退出聊天室时socket.on('disconnect',function () {console.log("关闭");let index = users.findIndex(item=>item.username===socket.username);users.splice(index,1);//告诉大家有人退出了聊天室io.emit("delUser",{username:socket.username,avatar:socket.avatar})//重新渲染用户列表io.emit("userList",users);})

客户端(index.js)

// 监听用户离开的消息socket.on('delUser', data => {// 添加一条系统消息$('.box-bd').append(`<div class="system"><p class="message_system"><span class="content">${data.username}离开了群聊</span></p></div>`)scrollIntoView()})

6实现聊天功能

服务端(app.js)

//接受用户发送的信息socket.on("sendMessage",data=>{//把消息广播给所有人io.emit("receiveMessage",data)})

客户端


// 聊天功能
$('.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 => {// 把接收到的消息显示到聊天窗口中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()
})

实现图片的发送

服务端

//接受用户发送的图片socket.on("sendImage",data=>{//把图片广播给所有人io.emit("receiveImage",data)})

客户端


在这里插入代码片

// 发送图片功能
$('#file').on('change', function() {var file = this.files[0]// 需要把这个文件发送到服务器, 借助于H5新增的fileReadervar fr = new FileReader()fr.readAsDataURL(file)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()})
})

使用表情

使用插件 jqury-emoji、

jquery-emoji文档

首先在页面上引用css文件和js文件,css文件一般在中添加,js文件一般在之前添加。注意要先引用jquery和jquery.mCustomScrollbar,再引用该js。

 <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" /><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>

客户端


/ 初始化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'}]})
})

**

完结!!!!,体会:::div 可以有属性contenteditable,使div可编辑

**
点击获取源码

用 websocket、JQuery开发仿微信聊天相关推荐

  1. 用APICloud开发仿微信聊天App制作经验分享

    作者:川哥哥 之前我一直用融云的接口做即时通信,自己也摸索了一段时间觉得融云做的挺好的.可是接口是收费的还有点小贵,就放弃融云了决心自己搭建一个后台. 在网上查资料,去学校图书馆借书发现居然还有< ...

  2. 2023仿微信聊天软件系统开发独立部署聊天系统

    系统模式:独立系统版本,独立服务器部署,服务器配置:建议 4 核 8G:10M 带宽既可 以下是聊天系统客户端的功能介绍,服务端的功能我会再写一篇文章接着 仿微信聊天开发的聊天软件以及聊天客户端功能介 ...

  3. js模拟群聊天php,jquery仿微信聊天界面实例分享

    本文主要为大家详细介绍了jquery仿微信聊天界面的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能帮助到大家. 首先看一下我们的效果图. 这个颜色可能搭配的有些不合适,但基本功能大 ...

  4. react仿微信聊天室|react即时聊天IM系统|react群聊

    react+redux仿微信聊天IM实战|react仿微信界面|react多人群聊天室 最近一直捣鼓react开发,就运用react开发了个仿微信聊天室reactChatRoom项目,基于react+ ...

  5. 基于Flutter的仿微信聊天应用

    前言   作为当下风头正劲的跨端框架,flutter成为原生开发者和前端开发者争相试水的领域,笔者将通过一个仿微信聊天的应用,展现flutter的开发流程和相关工具链,旨在熟悉flutter的开发生态 ...

  6. java 简单仿微信聊天(springboot)

    采用springboot netty 简单模仿微信聊天界面和功能. 系统模块:包括手机app端,后台服务端 技术架构: 手机app:Html5+,开发工具HBuilderX 后台服务:springbo ...

  7. HTML5仿微信聊天界面、微信朋友圈实例

    这几天使用H5开发了一个仿微信聊天前端界面,尤其微信底部编辑器那块处理的很好,使用HTML5来开发,虽说功能效果并没有微信那么全,但是也相当不错了,可以发送消息.表情,发送的消息自动回滚定位到底部,另 ...

  8. h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器

    之前做过一版h5微信聊天移动端,这段时间闲来无事就整理了下之前项目,又重新在原先的那版基础上升级了下,如是就有了现在的h5仿微信聊天高仿版,新增了微聊.通讯录.探索.我四个模块 左右触摸滑屏切换,聊天 ...

  9. native聊天界面 react_ReactNative 仿微信聊天 App 实例分享|RN 仿朋友圈

    今天给大家分享的是 RN 聊天室项目,基于 react-native+react-navigation+react-redux+react-native-image-picker+rnPop 等技术实 ...

最新文章

  1. 保护您的IE浏览器安全
  2. 一个 3D 多功能和灵巧的神经界面
  3. 2009年9月等考试题及答案51CTO站第一时间发布
  4. jwt https://mp.weixin.qq.com/s/8FdzMq4msyhqE9Rrhgwqjw
  5. Windows Phone 7 XNA触控操作之Gestures
  6. python编程例子-Python面向对象编程 - 类和实例
  7. Python画一个国旗
  8. 噫吁嚱!文言文亦能编程!此诚年度最骚语言也
  9. C#联合halcon应用——大华相机采集类
  10. 五笔:25 个一级简码(口诀)
  11. 大番薯本地模式怎么使用?大番薯u盘启动盘制作工具本地模式重装系统教程
  12. 2021运营App推广必备的几款工具
  13. c语言编程实现简单三子棋游戏
  14. 深入理解Java虚拟机(周志明第三版)- 第十一章:后端编译与优化
  15. gaussdb200 理论
  16. 软件测试工程师的职业发展路线?
  17. 微软NNI进行神经网络模型剪枝压缩的踩坑记录
  18. Java项目:(小程序)前台+后台相结合水果商城系统(spring+spring mvc+mybatis+layui+微信小程)
  19. 【3D服装级设计/游戏动画引擎】Marvelous Designer软件
  20. 【算法修炼】台球碰撞 C

热门文章

  1. shields 徽标_创意讲故事徽标的剖析
  2. 19-10-29-C++基础学习二
  3. c语言中0x11是多少,C语言中的符号
  4. MySQL命令行中文显示乱码解决
  5. 移动硬盘只读属性不能改
  6. 学习使用vue实现一个简单的轮播图
  7. 王者荣耀刷金币辅助(安卓调试桥与python的联合使用)
  8. CST微波工作室端口和激励
  9. 会声会影批量处理素材设置教程
  10. 第七章 本源时空(补充)