Browse Source

dadasd1

feature/MultiClientLog
root 1 month ago
parent
commit
71ec4d8a74
  1. 46
      LTEMvcApp/Controllers/MessageController.cs
  2. 8
      LTEMvcApp/Views/Home/ClientMessages.cshtml
  3. 18
      LTEMvcApp/Views/Home/Index.cshtml

46
LTEMvcApp/Controllers/MessageController.cs

@ -34,8 +34,8 @@ namespace LTEMvcApp.Controllers
/// <summary>
/// SSE推送客户端消息流
/// </summary>
[HttpGet("{clientName}/stream")]
public async Task StreamClientMessages(string clientName)
[HttpGet("{address}/stream")]
public async Task StreamClientMessages(string address)
{
try
{
@ -44,16 +44,16 @@ namespace LTEMvcApp.Controllers
Response.Headers.Append("Connection", "keep-alive");
Response.Headers.Append("Access-Control-Allow-Origin", "*");
var client = _webSocketManager.GetClientInstance(clientName);
var client = _webSocketManager.GetClientInstance(address);
if (client == null)
{
await SendSseEvent("error", new { message = "客户端未连接或不存在", clientName });
await SendSseEvent("error", new { message = "客户端未连接或不存在", address });
return;
}
await SendSseEvent("open", new {
message = "成功连接到服务器事件流",
clientName,
address,
timestamp = DateTime.UtcNow
});
await Response.Body.FlushAsync(HttpContext.RequestAborted);
@ -62,8 +62,8 @@ namespace LTEMvcApp.Controllers
int lastReceivedCount = 0;
var cancellationToken = HttpContext.RequestAborted;
var sentLogFilePath = Path.Combine(_logsDirectory, $"{clientName}_sent_messages.log");
var receivedLogFilePath = Path.Combine(_logsDirectory, $"{clientName}_received_messages.log");
var sentLogFilePath = Path.Combine(_logsDirectory, $"{address}_sent_messages.log");
var receivedLogFilePath = Path.Combine(_logsDirectory, $"{address}_received_messages.log");
while (!cancellationToken.IsCancellationRequested)
{
@ -79,7 +79,7 @@ namespace LTEMvcApp.Controllers
var newMessages = sentMessages.Skip(lastSentCount).ToList();
if (newMessages.Any())
{
await LogMessagesToFile(sentLogFilePath, newMessages, "SENT", clientName);
await LogMessagesToFile(sentLogFilePath, newMessages, "SENT", address);
await SendSseEvent("update", new {
type = "sent",
messages = newMessages,
@ -100,7 +100,7 @@ namespace LTEMvcApp.Controllers
var newMessages = receivedMessages.Skip(lastReceivedCount).ToList();
if (newMessages.Any())
{
await LogMessagesToFile(receivedLogFilePath, newMessages, "RECEIVED", clientName);
await LogMessagesToFile(receivedLogFilePath, newMessages, "RECEIVED", address);
await SendSseEvent("update", new {
type = "received",
messages = newMessages,
@ -124,11 +124,11 @@ namespace LTEMvcApp.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "StreamClientMessages 循环中发生错误,客户端: {ClientName}", clientName);
_logger.LogError(ex, "StreamClientMessages 循环中发生错误,客户端: {ClientName}", address);
await SendSseEvent("error", new {
message = "处理消息流时发生错误",
error = ex.Message,
clientName,
address,
timestamp = DateTime.UtcNow
});
await Response.Body.FlushAsync(cancellationToken);
@ -137,24 +137,24 @@ namespace LTEMvcApp.Controllers
}
await SendSseEvent("disconnected", new {
message = "客户端消息流连接已断开",
clientName,
address,
timestamp = DateTime.UtcNow
});
await Response.Body.FlushAsync(cancellationToken);
}
catch (OperationCanceledException)
{
_logger.LogInformation("StreamClientMessages 连接被客户端取消,客户端: {ClientName}", clientName);
_logger.LogInformation("StreamClientMessages 连接被客户端取消,客户端: {ClientName}", address);
}
catch (Exception ex)
{
_logger.LogError(ex, "StreamClientMessages 方法执行时发生未处理的异常,客户端: {ClientName}", clientName);
_logger.LogError(ex, "StreamClientMessages 方法执行时发生未处理的异常,客户端: {ClientName}", address);
try
{
await SendSseEvent("fatal_error", new {
message = "服务器内部错误",
error = ex.Message,
clientName,
address,
timestamp = DateTime.UtcNow
});
await Response.Body.FlushAsync();
@ -166,14 +166,14 @@ namespace LTEMvcApp.Controllers
/// <summary>
/// 发送消息到客户端
/// </summary>
[HttpPost("{clientName}/send")]
public ActionResult SendMessage(string clientName, [FromBody] JObject message)
[HttpPost("{address}/send")]
public ActionResult SendMessage(string address, [FromBody] JObject message)
{
var messageId = _webSocketManager.SendMessageToClient(clientName, message);
var messageId = _webSocketManager.SendMessageToClient(address, message);
if (messageId >= 0)
return Ok(new { messageId, message = $"消息已发送到客户端 '{clientName}'" });
return Ok(new { messageId, message = $"消息已发送到客户端 '{address}'" });
else
return BadRequest($"发送消息到客户端 '{clientName}' 失败");
return BadRequest($"发送消息到客户端 '{address}' 失败");
}
/// <summary>
@ -195,7 +195,7 @@ namespace LTEMvcApp.Controllers
filePath = filePath,
size = new FileInfo(filePath).Length,
lastModified = System.IO.File.GetLastWriteTime(filePath),
clientName = Path.GetFileNameWithoutExtension(filePath).Replace("_sent_messages", "").Replace("_received_messages", ""),
address = Path.GetFileNameWithoutExtension(filePath).Replace("_sent_messages", "").Replace("_received_messages", ""),
type = filePath.Contains("_sent_messages") ? "发送消息" : "接收消息"
})
.OrderByDescending(f => f.lastModified)
@ -329,7 +329,7 @@ namespace LTEMvcApp.Controllers
}
}
private async Task LogMessagesToFile(string logFilePath, List<string> messages, string messageType, string clientName)
private async Task LogMessagesToFile(string logFilePath, List<string> messages, string messageType, string address)
{
try
{
@ -337,7 +337,7 @@ namespace LTEMvcApp.Controllers
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
foreach (var message in messages)
{
logBuilder.AppendLine($"[{timestamp}] [{clientName}] [{messageType}] {message}");
logBuilder.AppendLine($"[{timestamp}] [{address}] [{messageType}] {message}");
logBuilder.AppendLine(new string('-', 80));
}
await System.IO.File.AppendAllTextAsync(logFilePath, logBuilder.ToString(), Encoding.UTF8);

8
LTEMvcApp/Views/Home/ClientMessages.cshtml

@ -1,6 +1,6 @@
@{
ViewData["Title"] = "客户端消息队列";
var clientName = ViewBag.ClientName as string ?? "TestClient";
var address = ViewBag.Address as string ?? "TestClient";
}
<style>
@ -166,7 +166,7 @@
<div class="col-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">客户端消息队列 - @clientName</h3>
<h3 class="card-title">客户端消息队列 - @address</h3>
<div class="card-tools">
<span id="connection-status" class="badge badge-secondary">正在连接...</span>
<button id="refreshLogFiles" class="btn btn-outline-primary btn-sm">
@ -266,7 +266,7 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script>
const clientName = '@clientName';
const address = '@address';
const MAX_MESSAGES_IN_MEMORY = 10000; // JS内存中最多保留1万条数据
let sentMessagesData = [];
@ -436,7 +436,7 @@
}
function initializeEventSource() {
const source = new EventSource(`/api/message/${encodeURIComponent(clientName)}/stream`);
const source = new EventSource(`/api/message/${encodeURIComponent(address)}/stream`);
const statusBadge = $('#connection-status');
source.addEventListener('open', function(e) {

18
LTEMvcApp/Views/Home/Index.cshtml

@ -200,22 +200,18 @@
</td>
<td class="project-actions text-right">
<a class="btn btn-primary btn-sm @(state == LTEMvcApp.Models.ClientState.Connected ? "disabled" : "")" href="#" onclick="startTestClient('@config.Address')">
<i class="fas fa-play"></i>
启动
<i class="fas fa-play"></i> 启动
</a>
<a class="btn btn-danger btn-sm @(state != LTEMvcApp.Models.ClientState.Connected ? "disabled" : "")" href="#" onclick="stopTestClient('@config.Address')">
<i class="fas fa-stop"></i>
停止
<i class="fas fa-stop"></i> 停止
</a>
<a class="btn btn-info btn-sm" href="@Url.Action("ClientMessages", "Home", new { clientName = config.Name })">
<i class="fas fa-list"></i>
消息
<a class="btn btn-info btn-sm @(state != LTEMvcApp.Models.ClientState.Connected ? "disabled" : "")" href="@Url.Action("ClientMessages", "Home", new { address = config.Address })">
<i class="fas fa-list"></i> 消息
</a>
<a href="@Url.Action("TestClientConfig", "Home", new { address = config.Address })" class="btn btn-sm btn-warning">
<i class="fas fa-cog"></i>
配置
<a href="@Url.Action("TestClientConfig", "Home", new { address = config.Address })" class="btn btn-sm btn-warning @(state != LTEMvcApp.Models.ClientState.Connected ? "disabled" : "")">
<i class="fas fa-cog"></i> 配置
</a>
<a class="btn btn-sm btn-outline-danger" href="#" onclick="deleteTestClient('@config.Address')">
<a class="btn btn-sm btn-outline-danger @(state != LTEMvcApp.Models.ClientState.Connected ? "disabled" : "")" href="#" onclick="deleteTestClient('@config.Address')">
<i class="fas fa-trash"></i> 删除
</a>
</td>

Loading…
Cancel
Save