Vedo un comportamento strano con il codice here.Il client risponde sempre al precedente evento inviato dal server, non all'evento corrente
lato client (JavaScript):
<input type="text" id="userid" placeholder="UserID" /><br />`
<input type="button" id="ping" value="Ping" />
<script>
var es = new EventSource('/home/message');
es.onmessage = function (e) {
console.log(e.data);
};
es.onerror = function() {
console.log(arguments);
};
$(function() {
$('#ping').on('click', function() {
$.post('/home/ping', {
UserID: parseInt($('#userid').val()) || 0
});
});
});
</script>
lato server (C#):
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Web.Mvc;
using Newtonsoft.Json;
namespace EventSourceTest2.Controllers {
public class PingData {
public int UserID { get; set; }
public DateTime Date { get; set; } = DateTime.Now;
}
public class HomeController : Controller {
public ActionResult Index() {
return View();
}
static ConcurrentQueue<PingData> pings = new ConcurrentQueue<PingData>();
public void Ping(int userID) {
pings.Enqueue(new PingData { UserID = userID });
}
public void Message() {
Response.ContentType = "text/event-stream";
do {
PingData nextPing;
if (pings.TryDequeue(out nextPing)) {
var msg = "data:" + JsonConvert.SerializeObject(nextPing, Formatting.None) + "\n\n";
Response.Write(msg);
}
Response.Flush();
Thread.Sleep(1000);
} while (true);
}
}
}
Una volta che ho premuto il ping per aggiungere un nuovo elemento alla coda pings
, il ciclo all'interno del metodo Message
seleziona il nuovo oggetto ed emette un evento, tramite Response.Write
(confermato utilizzando Debug.Print sul server). Tuttavia, il browser non attiva onmessage
fino a quando non preme il ping una seconda volta e il browser emette un altro evento; a questo punto i dati dal primo evento raggiungono onmessage
.
Come posso risolvere questo?
Per chiarire, questo è il comportamento che ci si aspetterebbe:
Client Server
-------------------------------------------------------------------
Press Ping button
XHR to /home/ping
Eneque new item to pings
Message loop issues server-sent event
EventSource calls onmessage
Questo è ciò che sta realmente accadendo:
Client Server
-------------------------------------------------------------------
Press Ping button
XHR to /home/ping
Eneque new item to pings
Message loop issues server-sent event
(Nothing happens)
Press Ping button again
New XHR to /home/ping
EventSource calls onmessage with previous event data
(Durante l'esecuzione in Chrome richiesta message
è elencato in la scheda Rete come sempre in sospeso. Non sono sicuro se questo è il comportamento normale degli eventi inviati dal server o forse è correlato al problema.)
Modifica
La rappresentazione della stringa della variabile msg
dopo Response.Write
assomiglia a questo:
"data:{\"UserID\":105,\"Date\":\"2016-03-11T04:20:24.1854996+02:00\"}\n\n"
compreso molto chiaramente le nuove righe.
controllo questo link ti aiuterà a controllare il tuo ultimo aggiornamento js e .css o non http://stackoverflow.com/questions/2185872/force-browsers-to-get-latest-js-and-css-files-in-asp-net -applicazione. Altrimenti aggiungi Expiration e Expires Header con questo link ti aiuterà https://support.microsoft.com/en-us/kb/234067 – Saineshwar
@Saineshwar Hai persino letto la domanda? (1) Non ho bisogno di aggiornare la pagina; Ho già l'ultimo Javascript. (2) Microsoft KB non ha nulla a che fare con gli eventi inviati dal server (né potrebbe, dato che si concentra su Internet Explorer che non supporta eventi inviati dal server. –