Я пытаюсь решить проблему между, как я понимаю, AJAX и событиями, отправленными сервером. У меня есть приложение, которое отправляет сообщение с некоторыми инструкциями контроллеру, и я хотел бы, чтобы контроллер отправил некоторый комментарий назад как событие, чтобы сообщить пользователю, что запрошенное действие было выполнено (может иметь ошибки или занять некоторое время) .
Идея состоит в том, что пользователь может отправить пакет различных инструкций через клиента, а сервер сообщит через SSE, когда каждое из этих действий будет выполнено.
Проблема, которую я вижу в Fiddler, заключается в том, что когда сообщение выполняется, ответ, который он возвращает, содержит мое сообщение источника событий, которое я хотел бы использовать. Тем не менее, код источника событий также, по-видимому, вызывает GET, в котором он хочет получить это сообщение источника событий. Поскольку этого не происходит, соединение постоянно закрывается.
В настоящее время у меня есть некоторый код контроллера, например:
[System.Web.Http.HttpPost]
public void Stop(ProjectViewModel model)
{
ProjectManager manager = new ProjectManager();
if (model.Servers != null && model.Servers.Count != 0)
{
string machine = model.Servers[0];
foreach (string service in model.Services)
{
manager.StopService(service, machine);
Message("stop", service);
}
}
}
и, на мой взгляд, и Ajax / XHR, и сервер отправляют события, настроенные так:
var form = document.getElementById("submitform");
form.onsubmit = function (e) {
// stop the regular form submission
e.preventDefault();
// collect the form data while iterating over the inputs
var data = {};
for (var i = 0, ii = 2; i < ii; ++i) {
var input = form[i];
if (input.name == "Servers") {
data[input.name] = document.getElementById("ServerSelect").options[document.getElementById("ServerSelect").selectedIndex].text;
}
else if (input.name == "Services")
data[input.name] = document.getElementById("ServiceSelect").options[document.getElementById("ServiceSelect").selectedIndex].text;
}
if (action) { data["action"] = action };
// construct an HTTP request
var xhr = new XMLHttpRequest();
if (action == "stop") {
xhr.open(form.method, '/tools/project/stop', true);
}
if (action == "start") {
xhr.open(form.method, '/tools/project/start', true)
}
xhr.setRequestHeader('Content-Type', 'application/json; charset=urf-8');
// send the collected data as JSON
xhr.send(JSON.stringify(data));
xhr.onloadend = function () {
// done
};
};
function events() {
if (window.EventSource == undefined) {
// If not supported
document.getElementById('eventlog').innerHTML = "Your browser doesn't support Server Sent Events.";
} else {
var source = new EventSource('../tools/project/Stop');
source.addEventListener("message", function (message) { console.log(message.data) });
source.onopen = function (event) {
document.getElementById('eventlog').innerHTML += 'Connection Opened.<br>';
console.log("Open");
};
source.onerror = function (event) {
if (event.eventPhase == EventSource.CLOSED) {
document.getElementById('eventlog').innerHTML += 'Connection Closed.<br>';
console.log("Close");
}
};
source.onmessage = function (event) {
//document.getElementById('eventlog').innerHTML += event.data + '<br>';
var newElement = document.createElement("li");
newElement.textContent = "message: " + event.data;
document.getElementById("eventlog").appendChild(newElement)
console.log("Message");
};
}
};
Я немного новичок в веб-разработке и не знаю, как решить эту проблему. Есть ли способ, которым я могу прочитать сообщение источника событий из этого POST? Или он был отправлен в GET вместо того, чтобы быть отправленным в качестве ответа на POST? В целом, кажется, что самая ужасная проблема заключается в том, что я не могу получить сообщения о событиях, отправленные в GET, которые запрашиваются API источника событий.
РЕДАКТИРОВАТЬ: После публикации я попытался создать новый метод в контроллере, который специально обрабатывает запросы к источникам событий, но похоже, что ответ на событие все равно каким-то образом заканчивается в теле ответа POST.
public void Message(string action, string service)
{
Response.ContentType = "text/event-stream";
Response.CacheControl = "no-cache";
//Response.Write($"event: message\n");
if (action == "stop")
{
Response.Write($"data: <li> {service} has stopped </li>\n\n");
}
Response.Flush();
Thread.Sleep(1000);
Response.Close();
}