<link rel="stylesheet" href="https://hu60.cn/q.php/api.webplug-file.17813_public_tip_css.css" />
<script src="https://hu60.cn/q.php/api.webplug-file.17813_public_wstip_js.js"></script>
以下最初源代码来自@残缘,和@老虎会游泳 的虎绿林WebSocket消息推送参考客户端,由ChatGPT修改完成,达到勉强可用的状态
期待更多虎友参与优化,目前存在的问题,悬浮窗消息展示不太美观,并且读取后不会把消息设为已读
最新版更新内容
以下是旧版本更新内容
?pageSize=1
作为查询参数,从而限制返回的消息数量,提高查询效率,节省服务器资源。
$(document).ready(function () {
showAlertDiv();
connectToWebSocket();
});
let messageList;
function connectToWebSocket() {
const socket = new WebSocket("wss://hu60.cn/ws/msg");
socket.onopen = (event) => {
console.log("WebSocket 连接已经建立");
setInterval(() => {
socket.send('{"action":"ping"}');
}, 60000);
};
socket.onmessage = (event) => {
console.log("收到 WebSocket 消息", event.data);
handleWebSocketMessage(event.data);
};
socket.onerror = (event) => {
console.error("WebSocket 连接出错", event);
socket.close();
};
socket.onclose = (event) => {
console.log("WebSocket 连接已关闭", event);
setTimeout(() => {
console.log("重新连接 WebSocket");
connectToWebSocket();
}, 5000);
};
}
function handleWebSocketMessage(eventData) {
try {
const message = JSON.parse(eventData);
if (message.event === "ping") {
console.log("收到 keep-alive 响应");
} else if (message.event === "msg") {
const msgData = message.data;
if (msgData.type === 0 || msgData.type === 1) {
showMessage(msgData);
// 把消息添加到消息列表
addToMessageList(msgData);
} else {
console.log("收到未知类型的推送消息:", msgData);
}
} else {
console.log("收到未知事件类型的推送消息:", message);
}
} catch (error) {
console.error("处理 WebSocket 消息时出错:", error);
}
}
function addToMessageList(msgData) {
if (!messageList) {
messageList = createFloatingMessageList();
}
const content = formatMessage(msgData.content); // 使用 formatMessage() 处理消息内容
const messageItem = document.createElement("div");
messageItem.innerHTML = content;
messageList.appendChild(messageItem);
}
function formatMessage(messageContent) {
let formattedContent = "";
try {
const elements = JSON.parse(messageContent);
elements.forEach((element) => {
switch (element.type) {
case "markdown":
// 处理 Markdown 内容
// 如果您需要支持完整的 Markdown,请使用一个库(如:https://github.com/showdownjs/showdown)
break;
case "text":
formattedContent += element.value;
break;
case "face":
formattedContent += `<img src="表情图片的URL" alt="${element.face}" />`;
break;
case "atMsg":
formattedContent += `<a href="${element.url}" target="_blank">${element.pos}</a> `;
element.msg.forEach((msgElement) => {
if (msgElement.type === "text") {
formattedContent += msgElement.value;
} else if (msgElement.type === "at") {
formattedContent += `<strong>@${msgElement.tag}</strong>`;
}
});
break;
default:
console.warn(`未知消息元素类型:${element.type}`);
}
});
} catch (error) {
console.error("解析消息内容时出错:", error);
}
return formattedContent;
}
function showFloatingMessageList() {
if (!messageList) {
messageList = createFloatingMessageList();
}
messageList.style.display = "block";
}
function createFloatingMessageList() {
const messageList = document.createElement("ul");
messageList.id = "messageList";
messageList.style.display = "none";
const closeButton = document.createElement("button");
closeButton.textContent = "关闭";
closeButton.addEventListener("click", function () {
messageList.style.display = "none";
});
messageList.appendChild(closeButton);
// 将浮动的div元素添加到body元素中
document.body.appendChild(messageList);
return messageList;
}
function showAlertDiv() {
// 创建浮动的div元素
const floatingDiv = document.createElement("div");
floatingDiv.id = "floatingDiv";
floatingDiv.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" width="35" height="35" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg><span id="messageCount" style="display:none;"></span>';
floatingDiv.addEventListener("click", function () {
showFloatingMessageList();
});
// 将浮动的div元素添加到body元素中
document.body.appendChild(floatingDiv);
}
function showMessage(msgData) {
const messageCount = parseInt(
document.getElementById("messageCount").textContent || "0"
);
document.getElementById("messageCount").textContent = messageCount + 1;
document.getElementById("messageCount").style.display = "inline";
}
@残缘,我不太会写,不过比较会提需求,chatgpt很牛,你可以改下这里
// 替换content中的.json为.html
content = content.replace(/.json/g, ".html");
你这轮训速度太快了,会把老虎服务器干坏的
iPhone13 PRO MAX 1T 国行远峰蓝 非海南免税版
@idc状态,可以自行修改,1500还好,会有一定的延迟
@TabKey9,有啥参考的图标吗,可以修改一下
@旧人,测试
@旧人,
这个不一定成立啊,如果连接断开,重连的这段时间来的消息就会错过。还有从开始连接到连上这段时间来的消息也会错过。
@老虎会游泳,我测试了很长时间,期间一直挂在后台,连接还算稳定,作为一个网站来说很少有用户在一个网页停留这么久吧,而且即使查询接口显示未读消息数量,似乎WebSocket也不会把未读的消息再推送一次,只有数量
@旧人,对,只有数量。那暂时忽略错过消息的问题也可以。
@老虎会游泳,底层网络协议自己会发心跳包吗?还需要 websocket 自己发吗?
@无名啊,不会。如果应用自己不主动发,一个数据包都不会有。
@残缘,有啥好的方法可以改改的吗,我本来倾向于原来那种调用jaon接口看消息的的