加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.html 8.66 KB
一键复制 编辑 原始数据 按行查看 历史
川川 提交于 2021-09-28 06:00 . update index.html.
<!--
http://localhost:63343/socket/index.html?from_id=2&to_id=5
https://blog.csdn.net/yournevermore/article/details/102936224 心跳
-->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no"/>
<title>交流中</title>
<link rel="stylesheet" type="text/css" href="./static/newcj/css/themes.css?v=2017129">
<link rel="stylesheet" type="text/css" href="./static/newcj/css/h5app.css">
<link rel="stylesheet" type="text/css" href="./static/newcj/fonts/iconfont.css?v=2016070717">
<script src="./static/newcj/js/jquery.min.js"></script>
<script src="./static/newcj/js/dist/flexible/flexible_css.debug.js"></script>
<script src="./static/newcj/js/dist/flexible/flexible.debug.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.6/dayjs.min.js"></script>
</head>
<body ontouchstart>
<div class='fui-page-group'>
<div class='fui-page chatDetail-page'>
<div class="chat-header flex">
<span class="shop-titlte t-30">交流中</span>
</div>
<div class="fui-content navbar" style="padding:1.2rem 0 1.35rem 0;">
<div class="chat-content">
<p style="display: none;text-align: center;padding-top: 0.5rem" id="more"><a>加载更多</a></p>
<p class="chat-time"><span class="time" id="current_time"></span></p>
</div>
</div>
<div class="fix-send flex footer-bar">
<input class="send-input t-28" maxlength="200">
<span class="send-btn">发送</span>
</div>
</div>
</div>
<script>
$(function () {
let currentTime = dayjs(Date.now()).format('YYYY-MM-DD HH:mm:ss')
let lockReconnect = false //避免重复连接
let ws = null //WebSocket的引用
let wsUrl = "wss://school.qifuxiong.com/wss/"
let fromId = getQueryVariable('from_id') //url中获取参数
let toId = getQueryVariable('to_id') //url中获取参数
//创建WebSocket连接
function createWebSocket(url) {
try {
ws = new WebSocket(url);
// 核心代码
initEventHandle();
} catch (e) {
// 重连
reconnect(url);
}
}
/********************初始化开始************************/
function initEventHandle() {
// 连接成功建立后响应
ws.onopen = function () {
console.log("成功连接到: socket");
// 心跳检测重置
heartCheck.reset().start();
}
// 收到服务器消息后响应
ws.onmessage = function (e) {
//如果获取到消息,心跳检测重置
//拿到任何消息都说明当前连接是正常的
heartCheck.reset().start();
//Json转换成Object
let message = eval("(" + e.data + ")");
console.log('服务端返回的数据', message) //socket返回的信息
switch (message.type) {
case "init":
// 发送用户id, 后端拿到这个数据, 绑定fd
let build = {
type: "bind",
fromId: fromId
}
ws.send(JSON.stringify(build));
// 省略: 请求后端api, 拿到双方历史聊天记录, 渲染; 后面, 每次发送数据后, 都需要先发送(socket实时返回), 后请求后端api接口, 进行信息入库操作
// 点对点聊天判断对方是否在线,
let online = {
type: 'online',
to_id: toId,
from_id: fromId,
}
ws.send(JSON.stringify(online));
return
case "text":
if (toId == message.from_id) {
$(".chat-content").append(' <div class="chat-text section-left flex"><span class="char-img" style="background-image: url(./static/newcj/img/123.jpg)"></span> <span class="text"><i class="icon icon-sanjiao4 t-32"></i>' + message.data + '</span> </div>');
$(".chat-content").scrollTop(3000);
}
return
case 'heart':
console.log('心跳不渲染任何信息')
return
case 'online':
// 用户在线不在线, 涉及到一些业务场景需要处理
// 如果对方上线了, 后端也会主动推送到这个里面来
// 如果用户下线了, 后端也会主动推送到这个里面来
console.log(message.to_id + message.status)
return
default:
console.log('格式问题, 后端不存在这种形式返回')
return
}
}
// 链接关闭后响应
ws.onclose = function () {
console.log('连接关闭, 正在重连')
reconnect(wsUrl) //重连
}
ws.onerror = function () {
console.log('连接错误, 正在重连')
reconnect(wsUrl) //重连
}
}
/*********************初始化结束*************************/
$(".send-btn").click(function () {
if (ws.readyState == 1) {
let text = $(".send-input").val();
let message = {
data: text,
type: 'say',
from_id: fromId,
to_id: toId
}
$(".chat-content").append('<div class="chat-text section-right flex"><span class="text"><i class="icon icon-sanjiao3 t-32"></i>' + text + '</span> <span class="char-img" style="background-image: url(./static/newcj/img/132.jpg)"></span> </div>')
ws.send(JSON.stringify(message));
$(".send-input").val("");
} else {
alert("当前连接超时,请刷新重试!");
}
return false
})
// 强制退出
window.onunload = function () {
console.log('我强退了!!!')
ws.close()
}
// 心跳检测
let heartCheck = {
timeout: 30000,//毫秒
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
let self = this;
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
let heart = {
type: "heart",
fromId: fromId
}
ws.send(JSON.stringify(heart));
console.log("发送一次心跳包", heart);
self.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置,说明后端主动断开了
ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
}
}
//WebSocket重接
function reconnect(url) {
if (lockReconnect) return
lockReconnect = true
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () {
createWebSocket(url);
console.log('正在重连, 当前时间: '.currentTime)
lockReconnect = false
}, 5000) // 这里设置重连间隔(ms)
}
// url中获取参数
function getQueryVariable(variable) {
let query = window.location.search.substring(1);
let vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
let pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
return (false);
}
createWebSocket(wsUrl) /**启动连接**/
})
</script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化