[/md]
[md]var express = require('express');
var app = express();
var http = require('http').createServer(app);
var io = require('socket.io').listen(http);
app.use(express.static('public'));
//请求首页返回index.html
app.get('/', function (req, res) {
res.sendFile( __dirname + "/index.html" );
});
//开启http服务器,监听8080端口
var server = http.listen(8080, function () {
console.log("server start");
});
var j = 0; //1客服在线,0客服不在线
//分配客服和客户命名空间
var service = io.of('/service');
var custom = io.of('/custom');
//监听客服端链接
service.on('connection', function(client){
console.log('a service connected');
//监听客服发来的信息
client.on('message_service', function (msg) {
custom.to(msg.destination_id).emit("new_message", msg); //把客服发来的数据转发给对应id客户
});
//监听客服断开链接
client.on('disconnect', function () {
console.log('a service leave');
});
});
//监听客户链接
custom.on('connection', function(client){
console.log('a user connected');
//判断客服在不在线,不在线则输入框不能选取
isOnline();
if(j == 0) {
custom.to(client.id).emit('isOnline', false);
} else {
custom.to(client.id).emit('isOnline', true);
}
//监听客户发来的信息
client.on('message_custom', function (msg) {
msg.id = client.id; //socketId存入msg对象一起转发给客服
service.emit('new_message', msg); //把信息转发给客服
});
//监听客户断开连接
client.on('disconnect', function(){
console.log('a user leave');
});
});
//判断当前客服在不在线
function isOnline() {
io.of('/service').clients(function(error, clients){
if (error) throw error;
j = clients.length; //客服分组长度为0,证明没有客服在线
});
}
客服页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>客服端</title>
<link href="css/reset.css" type="text/css" rel="stylesheet">
<link href="css/chatServer.css" type="text/css" rel="stylesheet">
</head>
<body>
<div id="choose">
<select id="choose_chat">
<option value="chat_message">默认</option>
</select>
</div>
<!--在线客服-->
<div id="chat">
<div id="chat_top"><img src="images/service.svg" id="service">在线客服</div>
<div id="chat_message" class="chat_message">
<div class="message_service" id="message0">
<div class="service_left">
<img src="images/custom_head.jpg" class="service_head">
</div>
<div class="service_right">
<div class="message_time"></div>
<div class="service_message_contain">sss</div>
</div>
</div>
<div style='clear:both'></div>
<div class="message_custom" id="message1">
<div class="custom_right">
<img src="images/service_head.jpeg" class="service_head">
</div>
<div class="custom_left">
<div class="message_time"></div>
<div class="custom_message_contain"></div>
</div>
</div>
<div style='clear:both'></div>
</div>
<div id="chat_tools">
<img src="images/face_choose.svg" id="face_choose">
<img src="images/pic_choose.svg" id="pic_choose">
</div>
<textarea id="chat_input"></textarea>
<input type="button" value="发送" id="send">
</div>
<!--在线客服结束-->
<script src="js/jquery-2.1.4.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="js/chatServer.js"></script>
</body>
</html>
客服功能实现
$(function () {
var socket = io('http://127.0.0.1:8080/service');
var IDS = []; //该数组保存正在聊天的客户id
//监听服务器转发的客户消息
socket.on("new_message", function (msg) {
var length = IDS.length;
for(var i = 0; i <= length; i++) {
var id = msg.id.replace('/custom#', '');
//新消息的用户id聊天框已经有了
if(id == IDS[i]) {
var $chat = $('#' + id); //获取对应id聊天框
var $message = $chat.find('#message0').clone();
$message.attr('id', '');
$message.find('.message_time').text(msg.time);
$message.find('.service_message_contain').text(msg.message);
$chat.append($message).append("<div style='clear:both'></div>");
$chat.scrollTop($chat[0].scrollHeight); //滚动条置底
break;
}
//新消息的用户id聊天框还没有,动态生成
if(i == length){
var $pause = $('#chat_message').clone(); //克隆大聊天框
var $message_pause = $pause.find("#message0").clone(); //克隆聊天框内客户发来的消息
$pause.attr('id', id); //客户socketId做为大聊天框id
$message_pause.attr('id', '');
$message_pause.find('.message_time').text(msg.time); //插入信息发送时间
$message_pause.find('.service_message_contain').text(msg.message); //插入消息内容
$pause.css('display', 'none');
$pause.append($message_pause).append("<div style='clear:both'></div>");
$('#chat_top').after($pause);
$('#choose_chat').append("<option value=" + id + ">" + id + "</option>"); //聊天框选择增加新选项
IDS.push(id);
$pause.scrollTop($pause[0].scrollHeight); //滚动条置底
}
}
});
//点击发送按钮,发送信息给在线客服
$("#send").bind("click", function () {
var $this = $(this);
//如果输入框不为空
if ($this.prev().val() != "") {
var choosed = $("#choose_chat option:selected").val();
var destination_id = "/custom#" + choosed; //要发送到的客户端id
console.log(destination_id);
var message = $this.prev().val();
var $pause = $("#message1").clone();
var time = new Date().toLocaleTimeString(); //获得发送时间
var $chat_pause = $("#" + choosed); //获得聊天信息框准备插入新数据
//把数据通过socket.io发送给后台
socket.emit('message_service', {'message': message,
'time': time,
'destination_id': destination_id});
$this.prev().val(""); //点发送,清空输入框
$pause.find(".custom_message_contain").text(message);
$pause.css("display", "block");
$pause.attr("id", "");
$pause.find(".message_time").text(time);
$chat_pause.append($pause).append("<div style='clear:both'></div>");
$chat_pause.scrollTop($chat_pause[0].scrollHeight); //滚动条置底
}
$('#chat_input').focus();
});
//聊天框选择绑定
$('#choose_chat').change(function () {
var choosed = $("#choose_chat option:selected").val();
var unChoosed = $("#choose_chat option").not(':selected');
unChoosed.each(function () {
var val = $(this).val();
$('#' + val).hide();
});
$('#' + choosed).show();
});
});
引入其他网站的js
(function ($) {
// 加载聊天窗口样式
var style = document.createElement('style');
style.innerHTML = `
#chat {
position: fixed;
bottom: 20px;
right: 20px;
width: 300px;
height: 400px;
border-radius: 10px;
border: 1px solid rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.9);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
z-index: 9999;
display: flex;
flex-direction: column;
transition: all 0.4s ease-in-out;
overflow: hidden;
}
#chat.minimized {
height: 40px;
background: rgba(255, 255, 255, 0.7);
}
#chat_top {
background: linear-gradient(45deg, rgba(76, 175, 80, 0.9), rgba(56, 142, 60, 0.9));
color: rgba(255, 255, 255, 0.9);
padding: 10px;
text-align: center;
cursor: pointer;
font-weight: bold;
font-size: 16px;
transition: background 0.3s ease-in-out;
}
#chat_top:hover {
background: linear-gradient(45deg, rgba(76, 175, 80, 1), rgba(56, 142, 60, 1));
}
#chat_message {
flex: 1;
padding: 10px;
overflow-y: auto;
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
background-color: rgba(245, 245, 245, 0.9);
transition: background-color 0.3s ease;
}
.message_service, .message_custom {
margin-bottom: 10px;
padding: 10px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.85);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
#chat_input {
width: calc(100% - 20px);
margin: 10px;
padding: 10px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.8);
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.05);
}
#send {
margin: 10px;
padding: 10px;
background: linear-gradient(45deg, rgba(76, 175, 80, 0.8), rgba(56, 142, 60, 0.8));
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.3s ease;
}
#send:hover {
background: linear-gradient(45deg, rgba(76, 175, 80, 1), rgba(56, 142, 60, 1));
}
#close-btn {
position: absolute;
top: 5px;
right: 10px;
cursor: pointer;
font-size: 18px;
color: rgba(255, 255, 255, 0.8);
transition: color 0.3s ease;
}
#close-btn:hover {
color: rgba(255, 255, 255, 1);
}
`;
document.head.appendChild(style);
// 创建聊天窗口HTML结构
var chatWidget = document.createElement('div');
chatWidget.id = 'chat';
chatWidget.innerHTML = `
<div id="chat_top">
<span id="isOnline">在线客服为您服务(在线)</span>
<span id="close-btn">-</span>
</div>
<div id="chat_message"></div>
<textarea id="chat_input" placeholder="请输入您的消息..."></textarea>
<button id="send">发送</button>
`;
document.body.appendChild(chatWidget);
// 点击顶部栏收起或展开聊天窗口
$('#chat_top').on('click', function () {
$('#chat').toggleClass('minimized');
$('#close-btn').text($('#chat').hasClass('minimized') ? '+' : '-');
});
// 连接到Socket.io的客服命名空间
var socket = io('http://127.0.0.1:8080/custom'); // 替换为你的服务器地址
// 检查客服是否在线
socket.on("isOnline", function (msg) {
if(msg == false) {
$('#isOnline').text("客服当前不在线");
$('#chat_input').attr('disabled', 'disabled');
}
});
// 监听服务器发来的客服消息
socket.on("new_message", function (msg) {
var $chat = $('#chat_message'); //获取聊天框
var $message = $('<div class="message_service"></div>');
$message.append(`
<div class="service_left">
<img src="http://127.0.0.1:8080/images/service_head.jpeg" class="service_head">
</div>
<div class="service_right">
<div class="message_time">${msg.time}</div>
<div class="service_message_contain">${msg.message}</div>
</div>
`);
$chat.append($message).append("<div style='clear:both'></div>"); //清除浮动用的div
$chat.scrollTop($chat[0].scrollHeight); //滚动条置底
});
// 点击发送按钮,发送信息给在线客服
$("#send").bind("click", function () {
var message = $('#chat_input').val();
if (message.trim() !== "") {
var time = new Date().toLocaleTimeString(); // 获得发送时间
var $chat = $('#chat_message'); // 获得聊天信息框准备插入新数据
// 把数据通过socket.io发送给后台
socket.emit('message_custom', {'message': message, 'time': time});
// 清空输入框
$('#chat_input').val("");
// 在页面上显示用户消息
var $message = $('<div class="message_custom"></div>');
$message.append(`
<div class="custom_right">
<img src="http://127.0.0.1:8080/images/custom_head.jpg" class="service_head">
</div>
<div class="custom_left">
<div class="message_time">${time}</div>
<div class="custom_message_contain">${message}</div>
</div>
`);
$chat.append($message).append("<div style='clear:both'></div>"); // 清除浮动用的div
$chat.scrollTop($chat[0].scrollHeight); // 滚动条置底
$('#chat_input').focus(); // 聚焦到输入框
}
});
})(jQuery);
使用-安装
npm i
使用-运行
node chatserver.js
使用-访问
http://127.0.0.1:8080/kfhoutai.html
#访问测试页面
http://127.0.0.1:8080/test.html
其他网站导入客户端js
<!-- 引入jQuery -->
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<!-- 引入Socket.io -->
<script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
<!-- 引入在线客服的JS -->
<script src="http://127.0.0.1:8080/js/chat_client.js"></script>