基于node+websocket+html实现腾讯课堂聊天室聊天功能


Posted in Javascript onMarch 04, 2020

受疫情影响很多中小学选择线上教程,大多数学校采用腾讯课堂直播,那么今天小编给大家分享一段代码关于基于node+websocket+html实现腾讯课堂聊天室聊天功能。

前端部分用到的知识:websocket,h5,contenteditable属性服务端部分:node, websocket部分效果:

基于node+websocket+html实现腾讯课堂聊天室聊天功能

基于node+websocket+html实现腾讯课堂聊天室聊天功能

基于node+websocket+html实现腾讯课堂聊天室聊天功能

功能细节需要注意的地方

前端部分:

(1)输入框要可以输入表情图片( 不能用textarea,要用contenteditable='true'来实现)

(2)消息数量的显示限制,比如我最多只显示最新的30条消息 (通过对dom节点的长度判断和移除实现)

  (3) 最新消息要始终显示在底部(通过scrollTop来实现)

 (4)对信息分类进行区分,是用户进入,离开,普通消息,还是送花进行划分

服务端部分:

websocket相关知识的运用

代码:

<!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">
 <link rel="stylesheet" type="text/css" href="css/style.css" rel="external nofollow" />
 <title>聊天室</title>
</head>
 
<body>
 <div class="container">
 <header>不充钱你觉得你会变得更强吗!!!</header>
 <div class="cont">
  <video src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" controls="controls"></video>
 </div>
 <div class="right">
  <div class="right_top">
  <div class="item ac_border">讨论</div>
  <div class="item" id="person">成员</div>
  </div>
  <div class="r_item">
  <div class="right_cont">
   <ul id="messageWrap"></ul>
  </div>
  <div class="right_bot">
   <div class="r_b_t clearfix">
   <div class="emoji " title="选择标签"></div>
   <div class="flower" title="献花"></div>
   </div>
   <div class="inputMeg_f">
   <!--inputMeg外添加div inputMeg_f 的原因是为了自定义滚动条的手势是箭头,如果不加,改成inputMeg设置滚动条样式,那么滚动条的熟悉是输入手势-->
   <div class="inputMeg" contenteditable="true" placeholder="请输入文字"></div>
   </div>
   <div class="send_btn">发送</div>
   <div id="emojiBox" class="clearfix"></div>
  </div>
  </div>
  <div class="r_item" style="display: none">
   <ul class="personWrap"></ul>
  </div>
 </div>
 </div>
</body>
 
<script src="../jquery.js"></script>
<script>
 $(".right_top .item").click(function () {
 $(this).siblings().removeClass('ac_border')
 $(this).addClass('ac_border')
 $('.r_item').css('display','none').eq($(this).index()).css('display','block')
 })
 
 function checkValue() {
 
 $(".emoji").off('click').click(function (e) {
  $("#emojiBox").css('display', 'block')
  var ev = e || window.event;
  ev.stopPropagation();
 })
 $(".container").off('click').click(function () {
  $("#emojiBox").css('display', 'none')
 })
 
 
 }
 checkValue();
 
 //生成表情
 var emojiHtml = '';
 var emojiBox = document.getElementById('emojiBox');
 for (var i = 0; i < 7; i++) {
 for (var j = 0; j < 15; j++) {
  var dom = document.createElement('div');
  dom.className = 'emojiItem';
  dom.style.backgroundPositionX = -24 * j + 'px';
  dom.style.backgroundPositionY = -29 * i + 'px';
  emojiBox.appendChild(dom)
  chooseEmoji(i, j, dom)
 }
 
 }
 
 function chooseEmoji(i, j, dom) {
 dom.onclick = function (e) {
  const src = 'img/icon' + (i * 15 + j) + '.gif';
  var img = $('<img class="emojiImg" src=' + src + '>')
  $('.inputMeg').append(img)
  $("#emojiBox").css('display', 'none')
  var ev = e || window.event;
  ev.stopPropagation();
 }
 }
 
 var userName=''; //当前登录的用户
 //websocket
 var websocket = new WebSocket(
 'ws://localhost:8001/'); //连接的地址,是ws协议,不是http协议(本地地址localhost:8001,要想手机也能访问到,改成本地ip192.168.0.107:8001)
 websocket.onopen = function () { //监听建立连接
 $('.send_btn').off('click').click(function () {
  var text = $('.inputMeg').html()
  if (text != '' && text != '请输入文字') {
  websocket.send(JSON.stringify({data:text,type:'message'})) //发送消息
  $('.inputMeg').html('')
  }
 });
 
 $('.flower').off('click').click(function(){ //送花
  var dom= '<span>"'+userName+'"</span>送给<br> "春哥" 一朵小花<i class="flowIcon"></i>'
  
  websocket.send(JSON.stringify({data:dom,type:'flower'})) //发送消息
 })
 
 }
 websocket.onmessage = function (e) {
 var res = JSON.parse(e.data);
 message(res)
 }
 
 
 function message(res) {
 var dom = document.createElement('li');
 switch (res.type) {
  case 'enter':
  dom.innerHTML = res.data;
  dom.style.color = 'green';
  userName=res.nickname;
  person(res);
  break;
  case 'leave':
  dom.innerHTML = res.data;
  dom.style.color = 'red';
  person(res)
  break;
  case 'message':
  name.innerHTML = res.nickname + ': ';
  dom.innerHTML = "<span class='nickName'>" + res.nickname + ": </span> " + res.data + ""
  break;
  case 'flower':
  dom.className='flowerLi';
  dom.innerHTML=res.data;
  break;
  default:
  break;
 }
 document.getElementById('messageWrap').appendChild(dom);
 limitLength(30)
 scrollBottom();
 
 //成员显示
 
 }
 
 function scrollBottom() { //显示最新消息在底部
 var h1 = document.getElementsByClassName('right_cont')[0].offsetHeight;
 var h2 = document.getElementById('messageWrap').offsetHeight;
 if (h2 > h1) {
  $('.right_cont').scrollTop(h2 - h1);
 }
 }
 
 function limitLength(num) { //限制聊天室最多能显示几条消息
 var li = $('#messageWrap li')
 if (li.length > num) {
  li.eq(0).remove();
 }
 }
 
 function person(res){ //成员显示
 var html=''
 for(var i=0;i<res.client.length;i++){
  html+= '<li><span class="nickname">'+res.client[i]+'</span></li>'
 }
 $('.personWrap').html(html);
 
 $('#person').html('成员('+res.client.length+')')
 
 }
</script>
 
</html>
 
 
server.js:
var ws = require("nodejs-websocket")
var port=8001;
var clientCount=0;
var nicknameArr=[];
var server = ws.createServer(function (conn) {
	clientCount++;
	conn.nickname='user'+clientCount;
	nicknameArr.push(conn.nickname)
	var mes={type:'enter',data:'欢迎 '+conn.nickname+' 进入聊天',nickname:conn.nickname,client:nicknameArr}
	broadcast(JSON.stringify(mes))
	conn.on("text", function (str) { //监听客户端发送过来的消息
		var zstr=JSON.parse(str)
		var mes={type:zstr.type,data:zstr.data,nickname:conn.nickname,client:nicknameArr}
		broadcast(JSON.stringify(mes))
		
	})
	conn.on("close", function (code, reason) {
		clientCount--;
		for(var i=nicknameArr.length-1;i>=0;i--){ //删除退出的用户
			if(conn.nickname==nicknameArr[i]){
				nicknameArr.splice(i,1)
			}
		}
		var mes={type:'leave',data:conn.nickname+' 离开聊天',nickname:conn.nickname,client:nicknameArr}
		broadcast(JSON.stringify(mes))
	});
	conn.on('error',function(err){
		console.log('handle err')
	})
}).listen(port)
function broadcast(str){ //获取客户端连接的人数并返回消息
	server.connections.forEach(function(connection){
		connection.sendText(str)
	})
 
}

总结

到此这篇关于基于node+websocket+html实现腾讯课堂聊天室聊天功能的文章就介绍到这了,更多相关node+websocket+html聊天室内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jQuery UI AutoComplete 自动完成使用小记
Aug 21 Javascript
基于Jquery制作的幻灯片图集效果打包下载
Feb 12 Javascript
js中switch case循环实例代码
Dec 30 Javascript
JavaScript中操作字符串小结
May 04 Javascript
jQuery添加和删除输入文本框标签代码
May 20 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
Oct 10 Javascript
jQuery制作图片旋转效果
Feb 02 Javascript
Vue.js父与子组件之间传参示例
Feb 28 Javascript
WdatePicker.js时间日期插件的使用方法
Jul 26 Javascript
浅谈angularJS2中的界面跳转方法
Aug 31 Javascript
vue实现导航菜单和编辑文本的示例代码
Jul 04 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
Jul 19 Javascript
VUE实现Studio管理后台之鼠标拖放改变窗口大小
Mar 04 #Javascript
微信小程序如何加载数据库真实数据的实现
Mar 04 #Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
Mar 04 #Javascript
微信小程序云函数添加数据到数据库的方法
Mar 04 #Javascript
jquery实现垂直手风琴菜单
Mar 04 #jQuery
JS数据类型(基本数据类型、引用数据类型)及堆和栈的区别分析
Mar 04 #Javascript
微信浏览器左上角返回按钮监听的实现
Mar 04 #Javascript
You might like
IStream与TStream之间的相互转换
2008/08/01 PHP
php时间戳转换的示例
2014/03/31 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
浅谈PHP安全防护之Web攻击
2017/01/03 PHP
JavaScript中的对象化编程
2008/01/16 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
2009/12/07 Javascript
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
详解JavaScript的流程控制语句
2015/11/30 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
2017/07/31 Javascript
JavaScript实现焦点进入文本框内关闭输入法的核心代码
2017/09/20 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
在移动端使用vue-router和keep-alive的方法示例
2018/12/02 Javascript
jQuery无冲突模式详解
2019/01/17 jQuery
使用vue cli4.x搭建vue项目的过程详解
2020/05/08 Javascript
[08:07]DOTA2每周TOP10 精彩击杀集锦vol.8
2014/06/25 DOTA
Python中设置变量作为默认值时容易遇到的错误
2015/04/03 Python
Python中shutil模块的常用文件操作函数用法示例
2016/07/05 Python
Python实现的多线程同步与互斥锁功能示例
2017/11/30 Python
Python实现KNN邻近算法
2021/01/28 Python
Python实现识别手写数字大纲
2018/01/29 Python
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
在cmd命令行里进入和退出Python程序的方法
2018/05/12 Python
Python代码打开本地.mp4格式文件的方法
2019/01/03 Python
Python3 单行多行万能正则匹配方法
2019/01/07 Python
Python面向对象之类的定义与继承用法示例
2019/01/14 Python
python 3.74 运行import numpy as np 报错lib\site-packages\numpy\__init__.py
2019/10/06 Python
python、Matlab求定积分的实现
2019/11/20 Python
使用tensorflow显示pb模型的所有网络结点方式
2020/01/23 Python
利用css3画个同心圆示例代码
2017/07/03 HTML / CSS
客房主管岗位职责
2013/12/09 职场文书
工作疏忽检讨书
2014/01/25 职场文书
护士进修自我鉴定
2014/02/07 职场文书
护理实习生带教计划
2015/01/16 职场文书
项目经理助理岗位职责
2015/04/13 职场文书
个人求职意向书
2015/05/11 职场文书
Java中常用解析工具jackson及fastjson的使用
2021/06/28 Java/Android