|
|
@ -63,94 +63,127 @@ |
|
|
|
|
|
|
|
@section Scripts { |
|
|
|
<script> |
|
|
|
var clientName = '@clientName'; |
|
|
|
var refreshInterval; |
|
|
|
const clientName = '@clientName'; |
|
|
|
const MAX_MESSAGES = 500; // 每个列表最多显示500条消息 |
|
|
|
let sentIndex = 0; |
|
|
|
let receivedIndex = 0; |
|
|
|
let updateInterval; |
|
|
|
|
|
|
|
$(document).ready(function() { |
|
|
|
loadMessages(); |
|
|
|
// 每5秒自动刷新一次 |
|
|
|
refreshInterval = setInterval(loadMessages, 5000); |
|
|
|
// 立即加载一次,然后每秒请求增量更新 |
|
|
|
loadInitialMessages(); |
|
|
|
updateInterval = setInterval(loadIncrementalMessages, 1000); // 1秒更新一次 |
|
|
|
}); |
|
|
|
|
|
|
|
// 首次加载 |
|
|
|
function loadInitialMessages() { |
|
|
|
// 清空现有内容 |
|
|
|
$('#sentMessages').empty(); |
|
|
|
$('#receivedMessages').empty(); |
|
|
|
sentIndex = 0; |
|
|
|
receivedIndex = 0; |
|
|
|
|
|
|
|
// 加载所有消息 |
|
|
|
loadMessages(true); |
|
|
|
} |
|
|
|
|
|
|
|
// 增量加载 |
|
|
|
function loadIncrementalMessages() { |
|
|
|
loadMessages(false); |
|
|
|
} |
|
|
|
|
|
|
|
function loadMessages() { |
|
|
|
function loadMessages(isInitial) { |
|
|
|
$.ajax({ |
|
|
|
url: '/api/websocket/clients/' + encodeURIComponent(clientName) + '/messages', |
|
|
|
url: `/api/websocket/clients/${encodeURIComponent(clientName)}/messages?sentStartIndex=${sentIndex}&receivedStartIndex=${receivedIndex}`, |
|
|
|
type: 'GET', |
|
|
|
success: function(data) { |
|
|
|
displayMessages(data); |
|
|
|
updateMessageList('sent', data.newSentMessages, data.totalSentCount, isInitial); |
|
|
|
updateMessageList('received', data.newReceivedMessages, data.totalReceivedCount, isInitial); |
|
|
|
|
|
|
|
// 更新下一次请求的起始索引 |
|
|
|
sentIndex = data.totalSentCount; |
|
|
|
receivedIndex = data.totalReceivedCount; |
|
|
|
}, |
|
|
|
error: function(xhr) { |
|
|
|
if (xhr.status === 404) { |
|
|
|
$('#sentMessages').html('<div class="text-warning text-center"><i class="fas fa-exclamation-triangle"></i> 客户端未连接</div>'); |
|
|
|
$('#receivedMessages').html('<div class="text-warning text-center"><i class="fas fa-exclamation-triangle"></i> 客户端未连接</div>'); |
|
|
|
} else { |
|
|
|
$('#sentMessages').html('<div class="text-danger text-center"><i class="fas fa-times-circle"></i> 加载失败</div>'); |
|
|
|
$('#receivedMessages').html('<div class="text-danger text-center"><i class="fas fa-times-circle"></i> 加载失败</div>'); |
|
|
|
} |
|
|
|
} |
|
|
|
error: handleAjaxError |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function displayMessages(data) { |
|
|
|
// 更新计数 |
|
|
|
$('#sentCount').text(data.sentCount || 0); |
|
|
|
$('#receivedCount').text(data.receivedCount || 0); |
|
|
|
|
|
|
|
// 显示发送消息 |
|
|
|
var sentHtml = ''; |
|
|
|
if (data.sentMessages && data.sentMessages.length > 0) { |
|
|
|
data.sentMessages.forEach(function(message, index) { |
|
|
|
sentHtml += createMessageCard(message, index, 'sent'); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
sentHtml = '<div class="text-muted text-center"><i class="fas fa-info-circle"></i> 暂无发送消息</div>'; |
|
|
|
|
|
|
|
function updateMessageList(type, newMessages, totalCount, isInitial) { |
|
|
|
if (isInitial && newMessages.length === 0) { |
|
|
|
$(`#${type}Messages`).html('<div class="text-muted text-center"><i class="fas fa-info-circle"></i> 暂无消息</div>'); |
|
|
|
} |
|
|
|
$('#sentMessages').html(sentHtml); |
|
|
|
|
|
|
|
// 显示接收消息 |
|
|
|
var receivedHtml = ''; |
|
|
|
if (data.receivedMessages && data.receivedMessages.length > 0) { |
|
|
|
data.receivedMessages.forEach(function(message, index) { |
|
|
|
receivedHtml += createMessageCard(message, index, 'received'); |
|
|
|
}); |
|
|
|
} else { |
|
|
|
receivedHtml = '<div class="text-muted text-center"><i class="fas fa-info-circle"></i> 暂无接收消息</div>'; |
|
|
|
|
|
|
|
if (!newMessages || newMessages.length === 0) { |
|
|
|
$(`#${type}Count`).text(totalCount); |
|
|
|
return; |
|
|
|
} |
|
|
|
$('#receivedMessages').html(receivedHtml); |
|
|
|
|
|
|
|
// 高亮JSON语法 |
|
|
|
$('pre code').each(function() { |
|
|
|
const container = $(`#${type}Messages`); |
|
|
|
const fragment = $(document.createDocumentFragment()); |
|
|
|
|
|
|
|
// 如果是首次加载,先移除"暂无消息"的提示 |
|
|
|
if (isInitial) { |
|
|
|
container.empty(); |
|
|
|
} |
|
|
|
|
|
|
|
let currentIndex = (type === 'sent' ? sentIndex : receivedIndex); |
|
|
|
newMessages.forEach(function(message) { |
|
|
|
const card = createMessageCard(message, currentIndex, type); |
|
|
|
fragment.append(card); |
|
|
|
currentIndex++; |
|
|
|
}); |
|
|
|
|
|
|
|
container.append(fragment); |
|
|
|
|
|
|
|
// 数量限制 |
|
|
|
const messageCards = container.children('.card'); |
|
|
|
if (messageCards.length > MAX_MESSAGES) { |
|
|
|
messageCards.slice(0, messageCards.length - MAX_MESSAGES).remove(); |
|
|
|
} |
|
|
|
|
|
|
|
$(`#${type}Count`).text(totalCount); |
|
|
|
|
|
|
|
// 高亮新添加的代码 |
|
|
|
container.find('pre code').not('.hljs').each(function() { |
|
|
|
if (typeof hljs !== 'undefined') { |
|
|
|
hljs.highlightElement(this); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function handleAjaxError(xhr) { |
|
|
|
if (xhr.status !== 404) { // 忽略404,因为它可能是客户端未连接的正常状态 |
|
|
|
console.error("加载消息失败:", xhr.responseText); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function createMessageCard(message, index, type) { |
|
|
|
var timestamp = new Date().toLocaleTimeString(); |
|
|
|
var messageType = type === 'sent' ? '发送' : '接收'; |
|
|
|
var bgClass = type === 'sent' ? 'border-success' : 'border-info'; |
|
|
|
var iconClass = type === 'sent' ? 'fas fa-paper-plane text-success' : 'fas fa-download text-info'; |
|
|
|
const timestamp = new Date().toLocaleTimeString(); |
|
|
|
const messageType = type === 'sent' ? '发送' : '接收'; |
|
|
|
const bgClass = type === 'sent' ? 'border-success' : 'border-info'; |
|
|
|
const iconClass = type === 'sent' ? 'fas fa-paper-plane text-success' : 'fas fa-download text-info'; |
|
|
|
|
|
|
|
return ` |
|
|
|
const cardHtml = ` |
|
|
|
<div class="card mb-2 ${bgClass}"> |
|
|
|
<div class="card-header py-2"> |
|
|
|
<small class="text-muted"> |
|
|
|
<i class="${iconClass}"></i> ${messageType} #${index + 1} - ${timestamp} |
|
|
|
</small> |
|
|
|
<button class="btn btn-sm btn-outline-secondary float-right" onclick="toggleMessage('${type}-${index}')"> |
|
|
|
<button class="btn btn-sm btn-outline-secondary float-right py-0" onclick="toggleMessage(this)"> |
|
|
|
<i class="fas fa-chevron-down"></i> |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
<div class="card-body py-2" id="${type}-${index}" style="display: none;"> |
|
|
|
<pre><code class="json">${formatJson(message)}</code></pre> |
|
|
|
<div class="card-body py-2" style="display: none;"> |
|
|
|
<pre><code class="json">${escapeHtml(formatJson(message))}</code></pre> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
`; |
|
|
|
return $(cardHtml); // 返回jQuery对象 |
|
|
|
} |
|
|
|
|
|
|
|
function toggleMessage(id) { |
|
|
|
$('#' + id).slideToggle(); |
|
|
|
function toggleMessage(button) { |
|
|
|
$(button).closest('.card').find('.card-body').slideToggle('fast'); |
|
|
|
$(button).find('i').toggleClass('fa-chevron-down fa-chevron-up'); |
|
|
|
} |
|
|
|
|
|
|
|
function formatJson(jsonString) { |
|
|
@ -161,15 +194,27 @@ |
|
|
|
return jsonString; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function escapeHtml(text) { |
|
|
|
return text |
|
|
|
.replace(/&/g, "&") |
|
|
|
.replace(/</g, "<") |
|
|
|
.replace(/>/g, ">") |
|
|
|
.replace(/"/g, """) |
|
|
|
.replace(/'/g, "'"); |
|
|
|
} |
|
|
|
|
|
|
|
function refreshMessages() { |
|
|
|
loadMessages(); |
|
|
|
// 停止自动更新,手动刷新,然后重新开始 |
|
|
|
clearInterval(updateInterval); |
|
|
|
loadInitialMessages(); |
|
|
|
updateInterval = setInterval(loadIncrementalMessages, 1000); |
|
|
|
} |
|
|
|
|
|
|
|
// 页面卸载时清除定时器 |
|
|
|
$(window).on('beforeunload', function() { |
|
|
|
if (refreshInterval) { |
|
|
|
clearInterval(refreshInterval); |
|
|
|
if (updateInterval) { |
|
|
|
clearInterval(updateInterval); |
|
|
|
} |
|
|
|
}); |
|
|
|
</script> |
|
|
@ -177,5 +222,4 @@ |
|
|
|
<!-- 添加代码高亮支持 --> |
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github.min.css"> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script> |
|
|
|
<script>hljs.highlightAll();</script> |
|
|
|
} |