You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
9.2 KiB
225 lines
9.2 KiB
@{
|
|
ViewData["Title"] = "客户端消息队列";
|
|
var clientName = ViewBag.ClientName as string ?? "TestClient";
|
|
}
|
|
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<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">
|
|
<i class="fas fa-cog"></i> 配置
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-paper-plane text-success"></i> 发送消息
|
|
<span class="badge badge-primary" id="sentCount">0</span>
|
|
</h5>
|
|
</div>
|
|
<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> 暂无发送消息
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-download text-info"></i> 接收消息
|
|
<span class="badge badge-info" id="receivedCount">0</span>
|
|
</h5>
|
|
</div>
|
|
<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> 暂无接收消息
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<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秒更新一次
|
|
});
|
|
|
|
// 首次加载
|
|
function loadInitialMessages() {
|
|
// 清空现有内容
|
|
$('#sentMessages').empty();
|
|
$('#receivedMessages').empty();
|
|
sentIndex = 0;
|
|
receivedIndex = 0;
|
|
|
|
// 加载所有消息
|
|
loadMessages(true);
|
|
}
|
|
|
|
// 增量加载
|
|
function loadIncrementalMessages() {
|
|
loadMessages(false);
|
|
}
|
|
|
|
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
|
|
});
|
|
}
|
|
|
|
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>');
|
|
}
|
|
|
|
if (!newMessages || newMessages.length === 0) {
|
|
$(`#${type}Count`).text(totalCount);
|
|
return;
|
|
}
|
|
|
|
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) {
|
|
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';
|
|
|
|
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 py-0" onclick="toggleMessage(this)">
|
|
<i class="fas fa-chevron-down"></i>
|
|
</button>
|
|
</div>
|
|
<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(button) {
|
|
$(button).closest('.card').find('.card-body').slideToggle('fast');
|
|
$(button).find('i').toggleClass('fa-chevron-down fa-chevron-up');
|
|
}
|
|
|
|
function formatJson(jsonString) {
|
|
try {
|
|
var obj = JSON.parse(jsonString);
|
|
return JSON.stringify(obj, null, 2);
|
|
} catch (e) {
|
|
return jsonString;
|
|
}
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
return text
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">")
|
|
.replace(/"/g, """)
|
|
.replace(/'/g, "'");
|
|
}
|
|
|
|
function refreshMessages() {
|
|
// 停止自动更新,手动刷新,然后重新开始
|
|
clearInterval(updateInterval);
|
|
loadInitialMessages();
|
|
updateInterval = setInterval(loadIncrementalMessages, 1000);
|
|
}
|
|
|
|
// 页面卸载时清除定时器
|
|
$(window).on('beforeunload', function() {
|
|
if (updateInterval) {
|
|
clearInterval(updateInterval);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<!-- 添加代码高亮支持 -->
|
|
<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>
|
|
}
|