|
|
@ -10,10 +10,8 @@ |
|
|
|
<div class="card-header"> |
|
|
|
<h3 class="card-title">客户端消息队列 - @clientName</h3> |
|
|
|
<div class="card-tools"> |
|
|
|
<button type="button" class="btn btn-primary btn-sm" onclick="refreshMessages()"> |
|
|
|
<i class="fas fa-sync-alt"></i> 刷新 |
|
|
|
</button> |
|
|
|
<a href="@Url.Action("TestClientConfig", "Home")" class="btn btn-info btn-sm"> |
|
|
|
<span id="connection-status" class="badge badge-secondary">正在连接...</span> |
|
|
|
<a href="@Url.Action("TestClientConfig", "Home")" class="btn btn-info btn-sm ml-2"> |
|
|
|
<i class="fas fa-cog"></i> 配置 |
|
|
|
</a> |
|
|
|
</div> |
|
|
@ -31,7 +29,7 @@ |
|
|
|
<div class="card-body" style="max-height: 600px; overflow-y: auto;"> |
|
|
|
<div id="sentMessages"> |
|
|
|
<div class="text-muted text-center"> |
|
|
|
<i class="fas fa-info-circle"></i> 暂无发送消息 |
|
|
|
<i class="fas fa-spinner fa-spin"></i> 正在建立与服务器的连接... |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -48,7 +46,7 @@ |
|
|
|
<div class="card-body" style="max-height: 600px; overflow-y: auto;"> |
|
|
|
<div id="receivedMessages"> |
|
|
|
<div class="text-muted text-center"> |
|
|
|
<i class="fas fa-info-circle"></i> 暂无接收消息 |
|
|
|
<i class="fas fa-spinner fa-spin"></i> 正在建立与服务器的连接... |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -65,54 +63,43 @@ |
|
|
|
<script> |
|
|
|
const clientName = '@clientName'; |
|
|
|
const MAX_MESSAGES = 500; // 每个列表最多显示500条消息 |
|
|
|
let sentIndex = 0; |
|
|
|
let receivedIndex = 0; |
|
|
|
let updateInterval; |
|
|
|
|
|
|
|
$(document).ready(function() { |
|
|
|
// 立即加载一次,然后每秒请求增量更新 |
|
|
|
loadInitialMessages(); |
|
|
|
updateInterval = setInterval(loadIncrementalMessages, 1000); // 1秒更新一次 |
|
|
|
initializeEventSource(); |
|
|
|
}); |
|
|
|
|
|
|
|
// 首次加载 |
|
|
|
function loadInitialMessages() { |
|
|
|
// 清空现有内容 |
|
|
|
$('#sentMessages').empty(); |
|
|
|
$('#receivedMessages').empty(); |
|
|
|
sentIndex = 0; |
|
|
|
receivedIndex = 0; |
|
|
|
|
|
|
|
// 加载所有消息 |
|
|
|
loadMessages(true); |
|
|
|
} |
|
|
|
|
|
|
|
// 增量加载 |
|
|
|
function loadIncrementalMessages() { |
|
|
|
loadMessages(false); |
|
|
|
} |
|
|
|
function initializeEventSource() { |
|
|
|
$('#sentMessages').html('<div class="text-muted text-center"><i class="fas fa-spinner fa-spin"></i> 正在建立与服务器的连接...</div>'); |
|
|
|
$('#receivedMessages').html('<div class="text-muted text-center"><i class="fas fa-spinner fa-spin"></i> 正在建立与服务器的连接...</div>'); |
|
|
|
|
|
|
|
const source = new EventSource(`/api/websocket/clients/${encodeURIComponent(clientName)}/messages/stream`); |
|
|
|
const statusBadge = $('#connection-status'); |
|
|
|
|
|
|
|
source.addEventListener('open', function(e) { |
|
|
|
console.log("SSE connection opened."); |
|
|
|
statusBadge.removeClass('badge-secondary badge-danger').addClass('badge-success').text('已连接'); |
|
|
|
// 清空等待消息 |
|
|
|
$('#sentMessages').empty(); |
|
|
|
$('#receivedMessages').empty(); |
|
|
|
}); |
|
|
|
|
|
|
|
function loadMessages(isInitial) { |
|
|
|
$.ajax({ |
|
|
|
url: `/api/websocket/clients/${encodeURIComponent(clientName)}/messages?sentStartIndex=${sentIndex}&receivedStartIndex=${receivedIndex}`, |
|
|
|
type: 'GET', |
|
|
|
success: function(data) { |
|
|
|
updateMessageList('sent', data.newSentMessages, data.totalSentCount, isInitial); |
|
|
|
updateMessageList('received', data.newReceivedMessages, data.totalReceivedCount, isInitial); |
|
|
|
|
|
|
|
// 更新下一次请求的起始索引 |
|
|
|
sentIndex = data.totalSentCount; |
|
|
|
receivedIndex = data.totalReceivedCount; |
|
|
|
}, |
|
|
|
error: handleAjaxError |
|
|
|
source.addEventListener('update', function(e) { |
|
|
|
const data = JSON.parse(e.data); |
|
|
|
updateMessageList(data.type, data.messages, data.totalCount); |
|
|
|
}); |
|
|
|
|
|
|
|
source.addEventListener('error', function(e) { |
|
|
|
statusBadge.removeClass('badge-success').addClass('badge-danger').text('连接断开'); |
|
|
|
if (e.target.readyState === EventSource.CLOSED) { |
|
|
|
console.error("SSE connection closed."); |
|
|
|
} else { |
|
|
|
console.error("SSE error:", e); |
|
|
|
} |
|
|
|
// EventSource 会自动尝试重连 |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
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>'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function updateMessageList(type, newMessages, totalCount) { |
|
|
|
if (!newMessages || newMessages.length === 0) { |
|
|
|
$(`#${type}Count`).text(totalCount); |
|
|
|
return; |
|
|
@ -120,13 +107,14 @@ |
|
|
|
|
|
|
|
const container = $(`#${type}Messages`); |
|
|
|
const fragment = $(document.createDocumentFragment()); |
|
|
|
|
|
|
|
// 如果是首次加载,先移除"暂无消息"的提示 |
|
|
|
if (isInitial) { |
|
|
|
|
|
|
|
// 移除 "暂无消息" 或 "正在连接" 的提示 |
|
|
|
if (container.children().length === 1 && !container.children().first().hasClass('card')) { |
|
|
|
container.empty(); |
|
|
|
} |
|
|
|
|
|
|
|
let currentIndex = (type === 'sent' ? sentIndex : receivedIndex); |
|
|
|
let currentIndex = totalCount - newMessages.length; |
|
|
|
|
|
|
|
newMessages.forEach(function(message) { |
|
|
|
const card = createMessageCard(message, currentIndex, type); |
|
|
|
fragment.append(card); |
|
|
@ -134,13 +122,13 @@ |
|
|
|
}); |
|
|
|
|
|
|
|
container.append(fragment); |
|
|
|
|
|
|
|
// 数量限制 |
|
|
|
|
|
|
|
// 限制DOM节点数量 |
|
|
|
const messageCards = container.children('.card'); |
|
|
|
if (messageCards.length > MAX_MESSAGES) { |
|
|
|
messageCards.slice(0, messageCards.length - MAX_MESSAGES).remove(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$(`#${type}Count`).text(totalCount); |
|
|
|
|
|
|
|
// 高亮新添加的代码 |
|
|
@ -150,12 +138,6 @@ |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
function handleAjaxError(xhr) { |
|
|
|
if (xhr.status !== 404) { // 忽略404,因为它可能是客户端未连接的正常状态 |
|
|
|
console.error("加载消息失败:", xhr.responseText); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function createMessageCard(message, index, type) { |
|
|
|
const timestamp = new Date().toLocaleTimeString(); |
|
|
@ -178,7 +160,7 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
`; |
|
|
|
return $(cardHtml); // 返回jQuery对象 |
|
|
|
return $(cardHtml); |
|
|
|
} |
|
|
|
|
|
|
|
function toggleMessage(button) { |
|
|
@ -194,7 +176,7 @@ |
|
|
|
return jsonString; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function escapeHtml(text) { |
|
|
|
return text |
|
|
|
.replace(/&/g, "&") |
|
|
@ -203,20 +185,6 @@ |
|
|
|
.replace(/"/g, """) |
|
|
|
.replace(/'/g, "'"); |
|
|
|
} |
|
|
|
|
|
|
|
function refreshMessages() { |
|
|
|
// 停止自动更新,手动刷新,然后重新开始 |
|
|
|
clearInterval(updateInterval); |
|
|
|
loadInitialMessages(); |
|
|
|
updateInterval = setInterval(loadIncrementalMessages, 1000); |
|
|
|
} |
|
|
|
|
|
|
|
// 页面卸载时清除定时器 |
|
|
|
$(window).on('beforeunload', function() { |
|
|
|
if (updateInterval) { |
|
|
|
clearInterval(updateInterval); |
|
|
|
} |
|
|
|
}); |
|
|
|
</script> |
|
|
|
|
|
|
|
<!-- 添加代码高亮支持 --> |
|
|
|