protected override Task InitializeResponse(IReceivingConnection connection)
 {
     return base.InitializeResponse(connection)
         .Then(initScript => Context.Response.WriteAsync(initScript),
               _initPrefix + Context.Request.QueryString["frameId"] + _initSuffix)
         .FastUnwrap();
 }
Beispiel #2
0
        private Task ProcessMessages(IReceivingConnection connection, long?lastMessageId)
        {
            var tcs = new TaskCompletionSource <object>();

            ProcessMessagesImpl(tcs, connection, lastMessageId);
            return(tcs.Task);
        }
Beispiel #3
0
        protected virtual Task InitializeResponse(IReceivingConnection connection)
        {
            // Don't timeout
            connection.ReceiveTimeout = TimeSpan.FromDays(1);

            return(TaskAsyncHelper.Empty);
        }
Beispiel #4
0
        private Task ProcessMessages(IReceivingConnection connection, long?lastMessageId)
        {
            if (!_disconnected && Context.Response.IsClientConnected)
            {
                // ResponseTask will either subscribe and wait for a signal then return new messages,
                // or return immediately with messages that were pending
                var receiveAsyncTask = lastMessageId == null
                    ? connection.ReceiveAsync()
                    : connection.ReceiveAsync(lastMessageId.Value);

                return(receiveAsyncTask.Then(response =>
                {
                    LastMessageId = response.MessageId;
                    // If the response has the Disconnect flag, just send the response and exit the loop,
                    // the server thinks connection is gone. Otherwse, send the response then re-enter the loop
                    return response.Disconnect
                        ? Send(response)
                        : Send(response)
                    .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
                    .FastUnwrap();
                }).FastUnwrap());
            }

            // Client is no longer connected
            Disconnect();

            // Nothing to do, return empty task to force the request to end
            return(TaskAsyncHelper.Empty);
        }
        private Task ProcessMessages(IReceivingConnection connection, Action postReceive = null)
        {
            var tcs = new TaskCompletionSource <object>();

            ProcessMessages(null, connection, tcs, postReceive);
            return(tcs.Task);
        }
Beispiel #6
0
        private Task ProcessReceiveRequest(IReceivingConnection connection)
        {
            HeartBeat.AddConnection(this);

            return(InitializeResponse(connection)
                   .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
                   .FastUnwrap());
        }
Beispiel #7
0
        private Task ProcessConnectRequest(IReceivingConnection connection)
        {
            if (Connected != null)
            {
                return(Connected().Then(() => ProcessReceiveRequest(connection)).FastUnwrap());
            }

            return(ProcessReceiveRequest(connection));
        }
 protected override Task InitializeResponse(IReceivingConnection connection)
 {
     return base.InitializeResponse(connection)
         .Then(() =>
         {
             Context.Response.ContentType = "text/event-stream";
             return Context.Response.WriteAsync("data: initialized\n\n");
         }).FastUnwrap();
 }
Beispiel #9
0
 private Func <Task> ProcessReceiveRequest(IReceivingConnection connection)
 {
     _heartBeat.AddConnection(this);
     // If there is a message id then we receive with that id, which will either return
     // immediately if there are already messages since that id, or wait until new
     // messages come in and then return
     return(() => connection.ReceiveAsync(MessageId.Value)
            .Then(new Func <PersistentResponse, Task>(response => Send(response)))
            .FastUnwrap());
 }
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            long lastMessageId;
            if (Int64.TryParse(Context.Request.QueryString["messageId"], out lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return base.InitializeResponse(connection)
                .Then(initScript => Context.Response.WriteAsync(initScript), String.Format(_initTemplate, Context.Request.QueryString["frameId"]))
                .FastUnwrap();
        }
Beispiel #11
0
        private Task ProcessReceiveRequest(IReceivingConnection connection)
        {
            _heartBeat.AddConnection(this);

            // ReceiveAsync() will async wait until a message arrives then return
            var receiveTask = IsConnectRequest ?
                              connection.ReceiveAsync() :
                              connection.ReceiveAsync(MessageId);

            return(receiveTask.Then(new Func <PersistentResponse, Task>(response => Send(response)))
                   .FastUnwrap());
        }
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            ulong lastMessageId;
            if (UInt64.TryParse(Context.Request.QueryString["messageId"], out lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return base.InitializeResponse(connection)
                .Then(initScript => Context.Response.WriteAsync(initScript),
                      _initPrefix + Context.Request.QueryString["frameId"] + _initSuffix)
                .FastUnwrap();
        }
Beispiel #13
0
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            string lastMessageId = Context.Request.QueryString["messageId"];

            if (!String.IsNullOrEmpty(lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return(base.InitializeResponse(connection)
                   .Then(initScript => Context.Response.WriteAsync(initScript), String.Format(_initTemplate, Context.Request.QueryString["frameId"]))
                   .FastUnwrap());
        }
Beispiel #14
0
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            string lastMessageId = Context.Request.QueryString["messageId"];
            if (!String.IsNullOrEmpty(lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return base.InitializeResponse(connection)
                .Then(initScript => Context.Response.WriteAsync(initScript),
                      _initPrefix + Context.Request.QueryString["frameId"] + _initSuffix)
                .FastUnwrap();
        }
Beispiel #15
0
        public Task ProcessRequest(IReceivingConnection connection)
        {
            // This will only be called on the first request so we return a task that fires on connect

            var taskCompletionSource = new TaskCompletionSource <object>();

            _webSocketConnection.OnOpen = () =>
            {
                if (Connected != null)
                {
                    TaskAsyncHelper.Interleave(ProcessMessages, Connected, connection).ContinueWith(taskCompletionSource);
                }
                else
                {
                    // Just process messages if there's no handler
                    ProcessMessages(connection).ContinueWith(taskCompletionSource);
                }
            };

            _webSocketConnection.OnClose = () =>
            {
                _disconnected = true;

                if (Disconnected != null)
                {
                    Disconnected().Catch();
                }
            };

            _webSocketConnection.OnError = ex =>
            {
                _disconnected = true;

                if (Error != null)
                {
                    Error(ex).Catch();
                }
            };

            _webSocketConnection.OnMessage = data =>
            {
                if (Received != null)
                {
                    Received(data).Catch();
                }
            };

            return(taskCompletionSource.Task);
        }
        public Task ProcessRequest(IReceivingConnection connection)
        {
            // This will only be called on the first request so we return a task that fires on connect

            var taskCompletionSource = new TaskCompletionSource<object>();

            _webSocketConnection.OnOpen = () =>
            {
                if (Connected != null)
                {
                    TaskAsyncHelper.Interleave(ProcessMessages, Connected, connection).ContinueWith(taskCompletionSource);
                }
                else
                {
                    // Just process messages if there's no handler
                    ProcessMessages(connection).ContinueWith(taskCompletionSource);
                }
            };

            _webSocketConnection.OnClose = () =>
            {
                _disconnected = true;

                if (Disconnected != null)
                {
                    Disconnected().Catch();
                }
            };

            _webSocketConnection.OnError = ex =>
            {
                _disconnected = true;

                if (Error != null)
                {
                    Error(ex).Catch();
                }
            };

            _webSocketConnection.OnMessage = data =>
            {
                if (Received != null)
                {
                    Received(data).Catch();
                }
            };

            return taskCompletionSource.Task;
        }
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            string lastMessageId = Context.Request.QueryString["messageId"];
            if (!String.IsNullOrEmpty(lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return base.InitializeResponse(connection)
                .Then(() =>
                {
                    Context.Response.ContentType = "text/event-stream";
                    return Context.Response.WriteAsync("data: initialized\n\n");
                }).FastUnwrap();
        }
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            ulong lastMessageId;
            if (UInt64.TryParse(Context.Request.QueryString["messageId"], out lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return base.InitializeResponse(connection)
                .Then(() =>
                {
                    Context.Response.ContentType = "text/event-stream";
                    return Context.Response.WriteAsync("data: initialized\n\n");
                }).FastUnwrap();
        }
Beispiel #19
0
        private Func <Task> ProcessConnectRequest(IReceivingConnection connection)
        {
            // Since this is the first request, there's no data we need to retrieve so just wait
            // on a message to come through
            _heartBeat.AddConnection(this);
            if (Connected != null)
            {
                Connected();
            }

            // ReceiveAsync() will async wait until a message arrives then return
            return(() => connection.ReceiveAsync()
                   .Then(new Func <PersistentResponse, Task>(response => Send(response)))
                   .FastUnwrap());
        }
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            long lastMessageId;

            if (long.TryParse(Context.Request.Headers["Last-Event-ID"], out lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return(base.InitializeResponse(connection)
                   .Then(() =>
            {
                Context.Response.ContentType = "text/event-stream";
                return Context.Response.WriteAsync("data: initialized\n\n");
            }).FastUnwrap());
        }
Beispiel #21
0
        protected override Task InitializeResponse(IReceivingConnection connection)
        {
            string lastMessageId = Context.Request.QueryString["messageId"];

            if (!String.IsNullOrEmpty(lastMessageId))
            {
                LastMessageId = lastMessageId;
            }

            return(base.InitializeResponse(connection)
                   .Then(() =>
            {
                Context.Response.ContentType = "text/event-stream";
                return Context.Response.WriteAsync("data: initialized\n\n");
            }).FastUnwrap());
        }
Beispiel #22
0
        protected virtual Task InitializeResponse(IReceivingConnection connection)
        {
            // Don't timeout
            connection.ReceiveTimeout = TimeSpan.FromDays(1);

            // This forces the IIS compression module to leave this response alone.
            // If we don't do this, it will buffer the response to suit its own compression
            // logic, resulting in partial messages being sent to the client.
            Context.Request.Headers.Remove("Accept-Encoding");

            Context.Response.Buffer       = false;
            Context.Response.BufferOutput = false;
            Context.Response.CacheControl = "no-cache";
            Context.Response.AddHeader("Connection", "keep-alive");

            return(TaskAsyncHelper.Empty);
        }
Beispiel #23
0
        public Task ProcessRequest(IReceivingConnection connection)
        {
            Connection = connection;

            if (Context.Request.Url.LocalPath.EndsWith("/send"))
            {
                return(ProcessSendRequest());
            }
            else
            {
                if (IsConnectRequest && Connected != null)
                {
                    return(Connected().Then(() => ProcessReceiveRequest(connection)).FastUnwrap());
                }

                return(ProcessReceiveRequest(connection));
            }
        }
Beispiel #24
0
        public Func <Task> ProcessRequest(IReceivingConnection connection)
        {
            _connection = connection;

            if (IsSendRequest)
            {
                ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest)
                {
                    return(ProcessConnectRequest(connection));
                }
                else if (MessageId != null)
                {
                    return(ProcessReceiveRequest(connection));
                }
            }

            return(null);
        }
Beispiel #25
0
        public Func <Task> ProcessRequest(IReceivingConnection connection)
        {
            _connection = connection;

            if (_context.Request.Path.EndsWith("/send"))
            {
                ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest && Connected != null)
                {
                    Connected();
                }

                _heartBeat.AddConnection(this);

                return(ProcessReceiveRequest(connection));
            }

            return(null);
        }
Beispiel #26
0
        private void ProcessMessages(string messageId, IReceivingConnection connection, TaskCompletionSource <object> taskCompletionSource, Action postReceive = null)
        {
            if (_disconnected)
            {
                taskCompletionSource.SetResult(null);
            }
            else
            {
                Task <PersistentResponse> receiveTask = !String.IsNullOrEmpty(messageId) ?
                                                        connection.ReceiveAsync(messageId) :
                                                        connection.ReceiveAsync();

                if (postReceive != null)
                {
                    postReceive();
                }


                var receiveState = new
                {
                    Connection = connection,
                    Tcs        = taskCompletionSource
                };

                receiveTask.Then(response => Send(response).Then((state, resp) => ProcessMessages(resp.MessageId, state.Connection, state.Tcs), receiveState, response))
                .ContinueWith(task =>
                {
                    if (task.IsCanceled)
                    {
                        taskCompletionSource.SetCanceled();
                    }
                    else if (task.IsFaulted)
                    {
                        taskCompletionSource.SetException(task.Exception);
                    }
                },
                              TaskContinuationOptions.NotOnRanToCompletion);
            }
        }
Beispiel #27
0
 private Func<Task> ProcessReceiveRequest(IReceivingConnection connection)
 {
     return () => InitializeResponse(connection)
             .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
             .FastUnwrap();
 }
Beispiel #28
0
        protected virtual Task InitializeResponse(IReceivingConnection connection)
        {
            // Don't timeout
            connection.ReceiveTimeout = TimeSpan.FromDays(1);

            // This forces the IIS compression module to leave this response alone.
            // If we don't do this, it will buffer the response to suit its own compression
            // logic, resulting in partial messages being sent to the client.
            Context.Request.Headers.Remove("Accept-Encoding");

            Context.Response.Buffer = false;
            Context.Response.BufferOutput = false;
            Context.Response.CacheControl = "no-cache";
            Context.Response.AddHeader("Connection", "keep-alive");

            return TaskAsyncHelper.Empty;
        }
        private Task ProcessConnectRequest(IReceivingConnection connection)
        {
            if (Connected != null)
            {
                return Connected().Then(() => ProcessReceiveRequest(connection)).FastUnwrap();
            }

            return ProcessReceiveRequest(connection);
        }
Beispiel #30
0
 protected override Task InitializeResponse(IReceivingConnection connection)
 {
     return(base.InitializeResponse(connection)
            .Then(initScript => Context.Response.WriteAsync(initScript), String.Format(_initTemplate, Context.Request.QueryString["frameId"]))
            .FastUnwrap());
 }
        public Task ProcessRequest(IReceivingConnection connection)
        {
            Connection = connection;

            if (IsSendRequest)
            {
                return ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest)
                {
                    return ProcessConnectRequest(connection);
                }
                else if (MessageId != null)
                {
                    if (Reconnected != null)
                    {
                        // Return a task that completes when the reconnected event task & the receive loop task are both finished
                        return TaskAsyncHelper.Interleave(ProcessReceiveRequest, Reconnected, connection);
                    }

                    return ProcessReceiveRequest(connection);
                }
            }

            return null;
        }
        private Task ProcessReceiveRequest(IReceivingConnection connection, Action postReceive = null)
        {
            HeartBeat.AddConnection(this);
            HeartBeat.MarkConnection(this);

            // ReceiveAsync() will async wait until a message arrives then return
            var receiveTask = IsConnectRequest ?
                              connection.ReceiveAsync(TimeoutToken) :
                              connection.ReceiveAsync(MessageId, TimeoutToken);

            if (postReceive != null)
            {
                postReceive();
            }

            return receiveTask.Then(response => Send(response))
                              .FastUnwrap();
        }
Beispiel #33
0
 protected virtual Task InitializeResponse(IReceivingConnection connection)
 {
     return TaskAsyncHelper.Empty;
 }
Beispiel #34
0
        private void ProcessMessagesImpl(TaskCompletionSource<object> taskCompletetionSource, IReceivingConnection connection, Action postReceive = null)
        {
            if (!IsTimedOut && !IsDisconnected && Context.Response.IsClientConnected)
            {
                // ResponseTask will either subscribe and wait for a signal then return new messages,
                // or return immediately with messages that were pending
                var receiveAsyncTask = LastMessageId == null
                    ? connection.ReceiveAsync(TimeoutToken)
                    : connection.ReceiveAsync(LastMessageId, TimeoutToken);

                if (postReceive != null)
                {
                    postReceive();
                }

                receiveAsyncTask.Then(response =>
                {
                    LastMessageId = response.MessageId;
                    // If the response has the Disconnect flag, just send the response and exit the loop,
                    // the server thinks connection is gone. Otherwse, send the response then re-enter the loop
                    Task sendTask = Send(response);
                    if (response.Disconnect || response.TimedOut)
                    {
                        // Signal the tcs when the task is done
                        return sendTask.Then(tcs => tcs.SetResult(null), taskCompletetionSource);
                    }

                    // Continue the receive loop
                    return sendTask.Then((conn) => ProcessMessagesImpl(taskCompletetionSource, conn), connection);
                })
                .ContinueWith(t =>
                {
                    if (t.IsCanceled)
                    {
                        taskCompletetionSource.SetCanceled();
                    }
                    else if (t.IsFaulted)
                    {
                        taskCompletetionSource.SetException(t.Exception);
                    }
                },
                TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnRanToCompletion);

                // Stop execution here
                return;
            }

            taskCompletetionSource.SetResult(null);
            return;
        }
 protected override Task InitializeResponse(IReceivingConnection connection)
 {
     return base.InitializeResponse(connection)
         .Then(initScript => Context.Response.WriteAsync(initScript), String.Format(_initTemplate, Context.Request.QueryString["frameId"]))
         .FastUnwrap();
 }
Beispiel #36
0
        private void ProcessMessagesImpl(TaskCompletionSource <object> taskCompletetionSource, IReceivingConnection connection, long?lastMessageId)
        {
            if (!_disconnected && _context.Response.IsClientConnected)
            {
                // ResponseTask will either subscribe and wait for a signal then return new messages,
                // or return immediately with messages that were pending
                var receiveAsyncTask = lastMessageId == null
                    ? connection.ReceiveAsync()
                    : connection.ReceiveAsync(lastMessageId.Value);

                receiveAsyncTask.Then(response =>
                {
                    LastMessageId = response.MessageId;
                    // If the response has the Disconnect flag, just send the response and exit the loop,
                    // the server thinks connection is gone. Otherwse, send the response then re-enter the loop
                    Task sendTask = Send(response);
                    if (response.Disconnect)
                    {
                        // Signal the tcs when the task is done
                        return(sendTask.Then(tcs => tcs.SetResult(null), taskCompletetionSource));
                    }

                    // Continue the receive loop
                    return(sendTask.Then((conn, id) => ProcessMessagesImpl(taskCompletetionSource, conn, id), connection, LastMessageId));
                })
                .FastUnwrap().ContinueWith(t =>
                {
                    if (t.IsCanceled)
                    {
                        taskCompletetionSource.SetCanceled();
                    }
                    else if (t.IsFaulted)
                    {
                        taskCompletetionSource.SetException(t.Exception);
                    }
                },
                                           TaskContinuationOptions.ExecuteSynchronously & TaskContinuationOptions.NotOnRanToCompletion);

                // Stop execution here
                return;
            }

            // Client is no longer connected
            Disconnect();

            // We're done
            taskCompletetionSource.SetResult(null);
            return;
        }
Beispiel #37
0
        private Task ProcessReceiveRequest(IReceivingConnection connection)
        {
            HeartBeat.AddConnection(this);
            HeartBeat.MarkConnection(this);

            return InitializeResponse(connection)
                    .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
                    .FastUnwrap();
        }
Beispiel #38
0
 private Func <Task> ProcessReceiveRequest(IReceivingConnection connection)
 {
     return(() => InitializeResponse(connection)
            .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
            .FastUnwrap());
 }
        private Func<Task> ProcessConnectRequest(IReceivingConnection connection)
        {
            // Since this is the first request, there's no data we need to retrieve so just wait
            // on a message to come through
            _heartBeat.AddConnection(this);
            if (Connected != null)
            {
                Connected();
            }

            // ReceiveAsync() will async wait until a message arrives then return
            return () => connection.ReceiveAsync()
                .Then(new Func<PersistentResponse, Task>(response => Send(response)))
                .FastUnwrap();
        }
Beispiel #40
0
        public Task ProcessRequest(IReceivingConnection connection)
        {
            Connection = connection;

            if (Context.Request.Url.LocalPath.EndsWith("/send"))
            {
                return ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest)
                {
                    if (Connected != null)
                    {
                        // Return a task that completes when the connected event task & the receive loop task are both finished
                        return TaskAsyncHelper.Interleave(ProcessReceiveRequest, Connected, connection);
                    }

                    return ProcessReceiveRequest(connection);
                }

                if (Reconnected != null)
                {
                    // Return a task that completes when the reconnected event task & the receive loop task are both finished
                    return TaskAsyncHelper.Interleave(ProcessReceiveRequest, Reconnected, connection);
                }

                return ProcessReceiveRequest(connection);
            }
        }
Beispiel #41
0
        private Task ProcessMessages(IReceivingConnection connection, long? lastMessageId)
        {
            if (!_disconnected && Context.Response.IsClientConnected)
            {
                // ResponseTask will either subscribe and wait for a signal then return new messages,
                // or return immediately with messages that were pending
                var receiveAsyncTask = lastMessageId == null
                    ? connection.ReceiveAsync()
                    : connection.ReceiveAsync(lastMessageId.Value);

                return receiveAsyncTask.Then(response =>
                {
                    LastMessageId = response.MessageId;
                    // If the response has the Disconnect flag, just send the response and exit the loop,
                    // the server thinks connection is gone. Otherwse, send the response then re-enter the loop
                    return response.Disconnect
                        ? Send(response)
                        : Send(response)
                            .Then((c, id) => ProcessMessages(c, id), connection, LastMessageId)
                            .FastUnwrap();
                }).FastUnwrap();
            }

            // Client is no longer connected
            Disconnect();

            // Nothing to do, return empty task to force the request to end
            return TaskAsyncHelper.Empty;
        }
Beispiel #42
0
 private Task ProcessMessages(IReceivingConnection connection, Action postReceive = null)
 {
     var tcs = new TaskCompletionSource<object>();
     ProcessMessagesImpl(tcs, connection, postReceive);
     return tcs.Task;
 }
Beispiel #43
0
        public Func<Task> ProcessRequest(IReceivingConnection connection)
        {
            _connection = connection;

            if (_context.Request.Url.LocalPath.EndsWith("/send"))
            {
                ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest && Connected != null)
                {
                    Connected();
                }

                _heartBeat.AddConnection(this);

                return ProcessReceiveRequest(connection);
            }

            return null;
        }
Beispiel #44
0
        private Task ProcessReceiveRequest(IReceivingConnection connection, Action postReceive = null)
        {
            HeartBeat.AddConnection(this);
            HeartBeat.MarkConnection(this);

            return InitializeResponse(connection)
                    .Then((c, pr) => ProcessMessages(c, pr), connection, postReceive);
        }
Beispiel #45
0
        protected virtual Task InitializeResponse(IReceivingConnection connection)
        {
            // Don't timeout
            connection.ReceiveTimeout = TimeSpan.FromDays(1);

            _context.Response.Buffer = false;

            return TaskAsyncHelper.Empty;
        }
        private Task ProcessConnectRequest(IReceivingConnection connection)
        {
            if (Connected != null)
            {
                // Return a task that completes when the connected event task & the receive loop task are both finished
                return TaskAsyncHelper.Interleave(ProcessReceiveRequest, Connected, connection);
            }

            return ProcessReceiveRequest(connection);
        }
Beispiel #47
0
 private Task ProcessMessages(IReceivingConnection connection, long? lastMessageId)
 {
     var tcs = new TaskCompletionSource<object>();
     ProcessMessagesImpl(tcs, connection, lastMessageId);
     return tcs.Task;
 }
        public Task ProcessRequest(IReceivingConnection connection)
        {
            _connection = connection;

            if (IsSendRequest)
            {
                return ProcessSendRequest();
            }
            else
            {
                if (IsConnectRequest)
                {
                    return ProcessConnectRequest(connection);
                }
                else if (MessageId != null)
                {
                    return ProcessReceiveRequest(connection);
                }
            }

            return null;
        }
Beispiel #49
0
        private void ProcessMessagesImpl(TaskCompletionSource<object> taskCompletetionSource, IReceivingConnection connection, long? lastMessageId)
        {
            if (!_disconnected && _context.Response.IsClientConnected)
            {
                // ResponseTask will either subscribe and wait for a signal then return new messages,
                // or return immediately with messages that were pending
                var receiveAsyncTask = lastMessageId == null
                    ? connection.ReceiveAsync()
                    : connection.ReceiveAsync(lastMessageId.Value);

                receiveAsyncTask.Then(response =>
                {
                    LastMessageId = response.MessageId;
                    // If the response has the Disconnect flag, just send the response and exit the loop,
                    // the server thinks connection is gone. Otherwse, send the response then re-enter the loop
                    Task sendTask = Send(response);
                    if (response.Disconnect)
                    {
                        // Signal the tcs when the task is done
                        return sendTask.Then(tcs => tcs.SetResult(null), taskCompletetionSource);
                    }

                    // Continue the receive loop
                    return sendTask.Then((conn, id) => ProcessMessagesImpl(taskCompletetionSource, conn, id), connection, LastMessageId);
                })
                .FastUnwrap().ContinueWith(t =>
                {
                    if (t.IsCanceled)
                    {
                        taskCompletetionSource.SetCanceled();
                    }
                    else if (t.IsFaulted)
                    {
                        taskCompletetionSource.SetException(t.Exception);
                    }
                },
                TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnRanToCompletion);

                // Stop execution here
                return;
            }

            // Client is no longer connected
            Disconnect();

            // We're done
            taskCompletetionSource.SetResult(null);
            return;
        }
        private Task ProcessReceiveRequest(IReceivingConnection connection)
        {
            _heartBeat.AddConnection(this);

            // ReceiveAsync() will async wait until a message arrives then return
            var receiveTask = IsConnectRequest ?
                              connection.ReceiveAsync() :
                              connection.ReceiveAsync(MessageId.Value);

            return receiveTask.Then(new Func<PersistentResponse, Task>(response => Send(response)))
                              .FastUnwrap();
        }
 private Func<Task> ProcessReceiveRequest(IReceivingConnection connection)
 {
     _heartBeat.AddConnection(this);
     // If there is a message id then we receive with that id, which will either return
     // immediately if there are already messages since that id, or wait until new
     // messages come in and then return
     return () => connection.ReceiveAsync(MessageId.Value)
         .Then(new Func<PersistentResponse, Task>(response => Send(response)))
         .FastUnwrap();
 }