Fixing longpolling
This commit is contained in:
parent
32ed7ca0c4
commit
239b5f815f
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
namespace WebApplication95
|
||||
{
|
||||
public class ConnectionState
|
||||
public class ConnectionState
|
||||
{
|
||||
public DateTimeOffset LastSeen { get; set; }
|
||||
public bool Alive { get; set; } = true;
|
||||
public Connection Connection { get; set; }
|
||||
public bool IsReservation { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ namespace WebApplication95
|
|||
if (context.Request.Path.StartsWithSegments(path + "/sse"))
|
||||
{
|
||||
var connectionState = GetOrCreateConnection(context);
|
||||
connectionState.IsReservation = false;
|
||||
var sse = new ServerSentEvents(connectionState);
|
||||
|
||||
var ignore = endpoint.OnConnected(connectionState.Connection);
|
||||
|
|
@ -73,6 +74,8 @@ namespace WebApplication95
|
|||
else if (context.Request.Path.StartsWithSegments(path + "/ws"))
|
||||
{
|
||||
var connectionState = GetOrCreateConnection(context);
|
||||
connectionState.IsReservation = false;
|
||||
|
||||
var ws = new WebSockets(connectionState);
|
||||
|
||||
var ignore = endpoint.OnConnected(connectionState.Connection);
|
||||
|
|
@ -89,18 +92,17 @@ namespace WebApplication95
|
|||
{
|
||||
var connectionId = context.Request.Query["id"];
|
||||
ConnectionState connectionState;
|
||||
bool newConnection = false;
|
||||
if (_manager.AddConnection(connectionId, out connectionState))
|
||||
{
|
||||
newConnection = true;
|
||||
var ignore = endpoint.OnConnected(connectionState.Connection);
|
||||
|
||||
if (_manager.AddConnection(connectionId, out connectionState) || connectionState.IsReservation)
|
||||
{
|
||||
connectionState.Connection.TransportType = TransportType.LongPolling;
|
||||
connectionState.IsReservation = false;
|
||||
var ignore = endpoint.OnConnected(connectionState.Connection);
|
||||
}
|
||||
|
||||
var longPolling = new LongPolling(connectionState);
|
||||
|
||||
await longPolling.ProcessRequest(newConnection, context);
|
||||
await longPolling.ProcessRequest(context);
|
||||
|
||||
_manager.MarkConnectionDead(connectionState.Connection.ConnectionId);
|
||||
}
|
||||
|
|
@ -112,6 +114,7 @@ namespace WebApplication95
|
|||
var connectionId = _manager.GetConnectionId(context);
|
||||
ConnectionState state;
|
||||
_manager.AddConnection(connectionId, out state);
|
||||
state.IsReservation = true;
|
||||
context.Response.Headers["X-SignalR-ConnectionId"] = connectionId;
|
||||
await context.Response.WriteAsync($"{{ \"connectionId\": \"{connectionId}\" }}");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,8 @@ namespace WebApplication95
|
|||
return _lastTask;
|
||||
}
|
||||
|
||||
public async Task ProcessRequest(bool newConnection, HttpContext context)
|
||||
public async Task ProcessRequest(HttpContext context)
|
||||
{
|
||||
context.Response.ContentType = "application/json";
|
||||
|
||||
// End the connection if the client goes away
|
||||
context.RequestAborted.Register(state => OnConnectionAborted(state), this);
|
||||
|
||||
|
|
@ -48,17 +46,8 @@ namespace WebApplication95
|
|||
|
||||
_initTcs.TrySetResult(null);
|
||||
|
||||
if (newConnection)
|
||||
{
|
||||
// Flush the connection id to the connection
|
||||
var ignore = Send(default(ArraySegment<byte>));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send queue messages to the connection
|
||||
var ignore = ProcessMessages(context);
|
||||
}
|
||||
|
||||
// Send queue messages to the connection
|
||||
var ignore = ProcessMessages(context);
|
||||
|
||||
await _lifetime.Task;
|
||||
|
||||
|
|
@ -106,7 +95,7 @@ namespace WebApplication95
|
|||
var data = ((ArraySegment<byte>)state);
|
||||
_context.Response.Headers["X-SignalR-ConnectionId"] = _state.Connection.ConnectionId;
|
||||
_context.Response.ContentLength = data.Count;
|
||||
await _context.Response.Body.WriteAsync(data.Array, 0, data.Count);
|
||||
await _context.Response.Body.WriteAsync(data.Array, data.Offset, data.Count);
|
||||
},
|
||||
value);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,19 +9,17 @@
|
|||
var xhr = new XMLHttpRequest();
|
||||
var url = '/chat/send?id=' + connectionId;
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/json');
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
}
|
||||
}
|
||||
var data = JSON.stringify(data);
|
||||
xhr.send(data);
|
||||
}
|
||||
|
||||
function xhr(method, url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open(method, url);
|
||||
xhr.open(method, url, true);
|
||||
xhr.send();
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
|
|
|
|||
|
|
@ -4,57 +4,75 @@
|
|||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
var connectionId;
|
||||
function xhr(method, url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open(method, url, true);
|
||||
xhr.send();
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve(xhr.response);
|
||||
} else {
|
||||
reject({
|
||||
status: xhr.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function send() {
|
||||
var body = document.getElementById('data').value;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
var url = '/chat/send?id=' + connectionId;
|
||||
xhr.open("POST", url, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/json');
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
}
|
||||
xhr.onerror = () => {
|
||||
reject({
|
||||
status: xhr.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
var data = JSON.stringify(body);
|
||||
xhr.send(data);
|
||||
}
|
||||
|
||||
function send(connectionId, data) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var url = '/chat/send?id=' + connectionId;
|
||||
xhr.open("POST", url, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
}
|
||||
}
|
||||
xhr.send(data);
|
||||
}
|
||||
|
||||
function poll(id) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var url = '/chat/poll' + (id == null ? '' : '?id=' + id);
|
||||
xhr.open("POST", url, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
var json = JSON.parse(xhr.responseText);
|
||||
var id = json.c;
|
||||
var data = json.d;
|
||||
if (data) {
|
||||
function poll(connectionId, xhr) {
|
||||
var url = `/chat/poll?id=${connectionId}`;
|
||||
xhr.open("POST", url, true);
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
var child = document.createElement('li');
|
||||
child.innerText = data;
|
||||
child.innerText = xhr.response;
|
||||
document.getElementById('messages').appendChild(child);
|
||||
poll(connectionId, xhr);
|
||||
}
|
||||
|
||||
if (!connectionId) {
|
||||
connectionId = id;
|
||||
}
|
||||
|
||||
poll(id);
|
||||
}
|
||||
xhr.send(null);
|
||||
}
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
poll();
|
||||
xhr('GET', '/chat/getid').then(getidPayload => {
|
||||
let connectionId = JSON.parse(getidPayload).connectionId;
|
||||
|
||||
document.getElementById('sendmessage').addEventListener('click', () => {
|
||||
let data = document.getElementById('data').value;
|
||||
send(connectionId, data);
|
||||
});
|
||||
|
||||
poll(connectionId, new XMLHttpRequest());
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Long Polling</h1>
|
||||
<input type="text" id="data" />
|
||||
<input type="button" value="Send" onclick="send()" />
|
||||
<input type="button" id="sendmessage" value="Send" />
|
||||
|
||||
<ul id="messages"></ul>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Reference in New Issue