public virtual void Initialize(IDependencyResolver resolver, HostContext context) { if (_initialized) { return; } _newMessageBus = resolver.Resolve<IMessageBus>(); _connectionIdPrefixGenerator = resolver.Resolve<IConnectionIdPrefixGenerator>(); _jsonSerializer = resolver.Resolve<IJsonSerializer>(); _transportManager = resolver.Resolve<ITransportManager>(); _trace = resolver.Resolve<ITraceManager>(); _serverMessageHandler = resolver.Resolve<IServerCommandHandler>(); _counters = resolver.Resolve<IPerformanceCounterManager>(); _ackHandler = resolver.Resolve<IAckHandler>(); _initialized = true; }
private ITransport GetTransport(HostContext context) { return _transportManager.GetTransport(context); }
/// <summary> /// Handles all requests for <see cref="PersistentConnection"/>s. /// </summary> /// <param name="context">The <see cref="HostContext"/> for the current request.</param> /// <returns>A <see cref="Task"/> that completes when the <see cref="PersistentConnection"/> pipeline is complete.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Thrown if connection wasn't initialized. /// Thrown if the transport wasn't specified. /// Thrown if the connection id wasn't specified. /// </exception> public virtual Task ProcessRequestAsync(HostContext context) { if (!_initialized) { throw new InvalidOperationException("Connection not initialized."); } if (IsNegotiationRequest(context.Request)) { return ProcessNegotiationRequest(context); } _transport = GetTransport(context); if (_transport == null) { throw new InvalidOperationException("Protocol error: Unknown transport."); } string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } var groups = new List<string>(_transport.Groups); Connection connection = CreateConnection(connectionId, groups, context.Request); Connection = connection; Groups = new GroupManager(connection, DefaultSignal); _transport.TransportConnected = () => { var command = new ServerCommand { Type = ServerCommandType.RemoveConnection, Value = connectionId }; return _serverMessageHandler.SendCommand(command); }; _transport.Connected = () => { return OnConnectedAsync(context.Request, connectionId); }; _transport.Reconnected = () => { return OnReconnectedAsync(context.Request, groups, connectionId); }; _transport.Received = data => { return OnReceivedAsync(context.Request, connectionId, data); }; _transport.Error = OnErrorAsync; _transport.Disconnected = () => { return OnDisconnectAsync(connectionId); }; return _transport.ProcessRequest(connection) ?? TaskAsyncHelper.Empty; }
public virtual Task ProcessRequestAsync(HostContext context) { if (IsNegotiationRequest(context.Request)) { return ProcessNegotiationRequest(context); } _transport = GetTransport(context); if (_transport == null) { throw new InvalidOperationException("Unknown transport."); } string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } IEnumerable<string> groups = _transport.Groups; Connection = CreateConnection(connectionId, groups, context.Request); _transport.Connected = () => { return OnConnectedAsync(context.Request, connectionId); }; _transport.Received = data => { return OnReceivedAsync(connectionId, data); }; _transport.Error = OnErrorAsync; _transport.Disconnected = () => { return OnDisconnectAsync(connectionId); }; return _transport.ProcessRequest(Connection) ?? TaskAsyncHelper.Empty; }
private Task ProcessNegotiationRequest(HostContext context) { context.Response.ContentType = Json.MimeType; return context.Response.EndAsync(_jsonSerializer.Stringify(new { Url = context.Request.Url.LocalPath.Replace("/negotiate", ""), ConnectionId = _connectionIdFactory.CreateConnectionId(context.Request), TryWebSockets = context.SupportsWebSockets(), WebSocketServerUrl = context.WebSocketServerUrl(), ProtocolVersion = "1.0" })); }
public virtual Task ProcessRequestAsync(HostContext context) { Task transportEventTask = null; if (IsNegotiationRequest(context.Request)) { return ProcessNegotiationRequest(context); } _transport = GetTransport(context); string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } IEnumerable<string> groups = _transport.Groups; Connection = CreateConnection(connectionId, groups, context.Request); // Wire up the events we need _transport.Connected += () => { transportEventTask = OnConnectedAsync(context.Request, connectionId); }; _transport.Received += (data) => { transportEventTask = OnReceivedAsync(connectionId, data); }; _transport.Error += (e) => { transportEventTask = OnErrorAsync(e); }; _transport.Disconnected += () => { transportEventTask = OnDisconnectAsync(connectionId); }; Func<Task> transportProcessRequest = _transport.ProcessRequest(Connection); if (transportProcessRequest != null) { if (transportEventTask != null) { return transportEventTask.Then(transportProcessRequest).FastUnwrap(); } return transportProcessRequest(); } return transportEventTask ?? TaskAsyncHelper.Empty; }
private ITransport GetTransport(HostContext context) { return TransportManager.GetTransport(context) ?? new LongPollingTransport(context, _jsonSerializer); }
/// <summary> /// Handles all requests for <see cref="PersistentConnection"/>s. /// </summary> /// <param name="context">The <see cref="HostContext"/> for the current request.</param> /// <returns>A <see cref="Task"/> that completes when the <see cref="PersistentConnection"/> pipeline is complete.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Thrown if connection wasn't initialized. /// Thrown if the transport wasn't specified. /// Thrown if the connection id wasn't specified. /// </exception> public virtual Task ProcessRequestAsync(HostContext context) { if (!_initialized) { throw new InvalidOperationException("Connection not initialized."); } if (IsNegotiationRequest(context.Request)) { return(ProcessNegotiationRequest(context)); } _transport = GetTransport(context); if (_transport == null) { throw new InvalidOperationException("Protocol error: Unknown transport."); } string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } var groups = new List <string>(_transport.Groups); Connection connection = CreateConnection(connectionId, groups, context.Request); Connection = connection; Groups = new GroupManager(connection, DefaultSignal); _transport.TransportConnected = () => { var command = new ServerCommand { Type = ServerCommandType.RemoveConnection, Value = connectionId }; return(_serverMessageHandler.SendCommand(command)); }; _transport.Connected = () => { return(OnConnectedAsync(context.Request, connectionId)); }; _transport.Reconnected = () => { return(OnReconnectedAsync(context.Request, groups, connectionId)); }; _transport.Received = data => { return(OnReceivedAsync(context.Request, connectionId, data)); }; _transport.Disconnected = () => { return(OnDisconnectAsync(connectionId)); }; return(_transport.ProcessRequest(connection) ?? TaskAsyncHelper.Empty); }
private ITransport GetTransport(HostContext context) { return(_transportManager.GetTransport(context)); }
private Task ProcessNegotiationRequest(HostContext context) { var keepAlive = _configurationManager.KeepAlive; var payload = new { Url = context.Request.Url.LocalPath.Replace("/negotiate", ""), ConnectionId = _connectionIdPrefixGenerator.GenerateConnectionIdPrefix(context.Request) + Guid.NewGuid().ToString("d"), KeepAlive = (keepAlive != null) ? keepAlive.Value.TotalSeconds : (double?)null, TryWebSockets = _transportManager.SupportsTransport(WebSocketsTransportName) && context.SupportsWebSockets(), WebSocketServerUrl = context.WebSocketServerUrl(), ProtocolVersion = "1.0" }; if (!String.IsNullOrEmpty(context.Request.QueryString["callback"])) { return ProcessJsonpNegotiationRequest(context, payload); } context.Response.ContentType = Json.MimeType; return context.Response.EndAsync(_jsonSerializer.Stringify(payload)); }
/// <summary> /// Handles all requests for <see cref="PersistentConnection"/>s. /// </summary> /// <param name="context">The <see cref="HostContext"/> for the current request.</param> /// <returns>A <see cref="Task"/> that completes when the <see cref="PersistentConnection"/> pipeline is complete.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Thrown if connection wasn't initialized. /// Thrown if the transport wasn't specified. /// Thrown if the connection id wasn't specified. /// </exception> public virtual Task ProcessRequestAsync(HostContext context) { if (!_initialized) { throw new InvalidOperationException("Connection not initialized."); } if (IsNegotiationRequest(context.Request)) { return ProcessNegotiationRequest(context); } _transport = GetTransport(context); if (_transport == null) { throw new InvalidOperationException("Protocol error: Unknown transport."); } string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } IEnumerable<string> signals = GetSignals(connectionId); IEnumerable<string> groups = OnRejoiningGroups(context.Request, _transport.Groups, connectionId); Connection connection = CreateConnection(connectionId, signals, groups); Connection = connection; Groups = new GroupManager(connection, DefaultSignal); _transport.TransportConnected = () => { var command = new ServerCommand { Type = ServerCommandType.RemoveConnection, Value = connectionId }; return _serverMessageHandler.SendCommand(command); }; _transport.Connected = () => { return OnConnectedAsync(context.Request, connectionId).OrEmpty(); }; _transport.Reconnected = () => { return OnReconnectedAsync(context.Request, connectionId).OrEmpty(); }; _transport.Received = data => { return OnReceivedAsync(context.Request, connectionId, data).OrEmpty(); }; _transport.Disconnected = () => { return OnDisconnectAsync(context.Request, connectionId).OrEmpty(); }; return _transport.ProcessRequest(connection).OrEmpty().Catch(_counters.ErrorsAllTotal, _counters.ErrorsAllPerSec); }
private ITransport GetTransport(HostContext context) { return(TransportManager.GetTransport(context) ?? new LongPollingTransport(context, _jsonSerializer)); }
private Task ProcessNegotiationRequest(HostContext context) { context.Response.ContentType = Json.MimeType; return context.Response.WriteAsync(_jsonSerializer.Stringify(new { Url = context.Request.Path.Replace("/negotiate", ""), ConnectionId = _connectionIdFactory.CreateConnectionId(context.Request), TryWebSockets = context.SupportsWebSockets() })); }
private Task ProcessJsonpNegotiationRequest(HostContext context, object payload) { context.Response.ContentType = Json.JsonpMimeType; var data = Json.CreateJsonpCallback(context.Request.QueryString["callback"], _jsonSerializer.Stringify(payload)); return context.Response.EndAsync(data); }
/// <summary> /// Handles all requests for <see cref="PersistentConnection"/>s. /// </summary> /// <param name="context">The <see cref="HostContext"/> for the current request.</param> /// <returns>A <see cref="Task"/> that completes when the <see cref="PersistentConnection"/> pipeline is complete.</returns> /// <exception cref="T:System.InvalidOperationException"> /// Thrown if connection wasn't initialized. /// Thrown if the transport wasn't specified. /// Thrown if the connection id wasn't specified. /// </exception> public virtual Task ProcessRequestAsync(HostContext context) { if (!_initialized) { throw new InvalidOperationException("Connection not initialized."); } if (IsNegotiationRequest(context.Request)) { return(ProcessNegotiationRequest(context)); } _transport = GetTransport(context); if (_transport == null) { throw new InvalidOperationException("Protocol error: Unknown transport."); } string connectionId = _transport.ConnectionId; // If there's no connection id then this is a bad request if (String.IsNullOrEmpty(connectionId)) { throw new InvalidOperationException("Protocol error: Missing connection id."); } IEnumerable <string> signals = GetSignals(connectionId, context.Request); IEnumerable <string> groups = OnRejoiningGroups(context.Request, _transport.Groups, connectionId); Connection connection = CreateConnection(connectionId, signals, groups); Connection = connection; Groups = new GroupManager(connection, DefaultSignal); _transport.TransportConnected = () => { var command = new ServerCommand { Type = ServerCommandType.RemoveConnection, Value = connectionId }; return(_serverMessageHandler.SendCommand(command)); }; _transport.Connected = () => { return(OnConnectedAsync(context.Request, connectionId).OrEmpty()); }; _transport.Reconnected = () => { return(OnReconnectedAsync(context.Request, groups, connectionId).OrEmpty()); }; _transport.Received = data => { return(OnReceivedAsync(context.Request, connectionId, data).OrEmpty()); }; _transport.Disconnected = () => { return(OnDisconnectAsync(connectionId).OrEmpty()); }; return(_transport.ProcessRequest(connection).OrEmpty().Catch(_allErrorsTotalCounter, _allErrorsPerSecCounter)); }
private Task ProcessNegotiationRequest(HostContext context) { var payload = new { Url = context.Request.Url.LocalPath.Replace("/negotiate", ""), ConnectionId = _connectionIdGenerator.GenerateConnectionId(context.Request), TryWebSockets = _transportManager.SupportsTransport(WebSocketsTransportName) && context.SupportsWebSockets(), WebSocketServerUrl = context.WebSocketServerUrl(), ProtocolVersion = "1.0" }; if (!String.IsNullOrEmpty(context.Request.QueryString["callback"])) { return ProcessJsonpNegotiationRequest(context, payload); } context.Response.ContentType = Json.MimeType; return context.Response.EndAsync(_jsonSerializer.Stringify(payload)); }
private Task ProcessRequestAsync(HttpListenerContext context) { try { Debug.WriteLine("Server: Incoming request to {0}.", context.Request.Url); PersistentConnection connection; string path = ResolvePath(context.Request.Url); foreach (var embeddedFileHandler in _embeddedFileHandlers) { var result = embeddedFileHandler.Handle(path, context); if (result != null) { return result; } } if (_routingHost.TryGetConnection(path, out connection)) { // https://developer.mozilla.org/En/HTTP_Access_Control string origin = context.Request.Headers["Origin"]; if (!String.IsNullOrEmpty(origin)) { context.Response.AddHeader("Access-Control-Allow-Origin", origin); context.Response.AddHeader("Access-Control-Allow-Credentials", "true"); } var request = new HttpListenerRequestWrapper(context); var response = new HttpListenerResponseWrapper(context.Response, _disconnectHandler.GetDisconnectToken(context)); var hostContext = new HostContext(request, response); #if NET45 hostContext.Items[HostConstants.SupportsWebSockets] = Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor >= 2; #endif if (OnProcessRequest != null) { OnProcessRequest(hostContext); } #if DEBUG hostContext.Items[HostConstants.DebugMode] = true; #endif hostContext.Items["System.Net.HttpListenerContext"] = context; // Initialize the connection connection.Initialize(_routingHost.DependencyResolver); return connection.ProcessRequestAsync(hostContext); } if (path.Equals("/clientaccesspolicy.xml", StringComparison.InvariantCultureIgnoreCase)) { using (var stream = typeof(WebAppServer).Assembly.GetManifestResourceStream(typeof(WebAppServer), "clientaccesspolicy.xml")) { if (stream == null) { var response = new HttpResponseMessage(HttpStatusCode.NotFound); return context.SendResponseAsync(response); } var bytes = new byte[1024]; int byteCount = stream.Read(bytes, 0, bytes.Length); return context.Response.WriteAsync(new ArraySegment<byte>(bytes, 0, byteCount)); } } HttpRequestMessage requestMessage = context.GetHttpRequestMessage(); return _webApiServer.PublicSendAsync(requestMessage, _disconnectHandler.GetDisconnectToken(context)) .Then(response => { var responseMessage = response ?? new HttpResponseMessage(HttpStatusCode.InternalServerError) { RequestMessage = requestMessage }; return context.SendResponseAsync(responseMessage); }); } catch (Exception ex) { return TaskAsyncHelper.FromError(ex); } }