/// <summary> /// Sets the listener in listening state on a particular end-point. /// </summary> /// <param name="address">End-point to listen to.</param> /// <param name="thread">The thread to use for listening.</param> public Task ListenAsync(ServiceAddress address, EventThread thread) { ServerAddress = address; Thread = thread; ConnectionManager = new ConnectionManager(thread); var tcs = new TaskCompletionSource <int>(this); Thread.Post(state => { var tcs2 = (TaskCompletionSource <int>)state; try { var listener = ((Listener)tcs2.Task.AsyncState); listener.ListenSocket = listener.CreateListenSocket(); tcs2.SetResult(0); } catch (Exception ex) { tcs2.SetException(ex); } }, tcs); return(tcs.Task); }
public async Task StartAsync( string pipeName, ServiceAddress address, EventThread thread) { _pipeName = pipeName; await ListenAsync(address, thread).ConfigureAwait(false); await Thread.PostAsync(state => ((ListenerPrimary)state).PostCallback(), this).ConfigureAwait(false); }
public IDisposable CreateServer(ServiceAddress address, IBinding binding) { var listeners = new List <IAsyncDisposable>(); var usingPipes = address.IsUnixPipe; try { var pipeName = (Libuv.IsWindows ? @"\\.\pipe\emitter_" : "/tmp/emitter_") + Guid.NewGuid().ToString("n"); var single = Threads.Count == 1; var first = true; foreach (var thread in Threads) { if (single) { var listener = new TcpListener(this); listeners.Add(listener); listener.Binding = binding; listener.ListenAsync(address, thread).Wait(); binding.Context = listener; } else if (first) { var listener = new TcpListenerPrimary(this); listeners.Add(listener); listener.Binding = binding; listener.StartAsync(pipeName, address, thread).Wait(); binding.Context = listener; } else { var listener = new TcpListenerSecondary(this); listeners.Add(listener); listener.Binding = binding; listener.StartAsync(pipeName, address, thread).Wait(); } first = false; } return(new Disposable(() => { DisposeListeners(listeners); })); } catch { DisposeListeners(listeners); throw; } }
public Task StartAsync( string pipeName, ServiceAddress address, EventThread thread) { _pipeName = pipeName; _buf = thread.Loop.Libuv.buf_init(_ptr, 4); ServerAddress = address; Thread = thread; ConnectionManager = new ConnectionManager(thread); DispatchPipe = new UvPipeHandle(); var tcs = new TaskCompletionSource <int>(this); Thread.Post(state => StartCallback((TaskCompletionSource <int>)state), tcs); return(tcs.Task); }
/// <summary> /// Creates a <see cref="ServiceAddress"/> from a url. /// </summary> /// <param name="url">The url to create from.</param> /// <returns></returns> public static ServiceAddress FromUrl(string url) { url = url ?? string.Empty; int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); if (schemeDelimiterStart < 0) { int port; if (int.TryParse(url, NumberStyles.None, CultureInfo.InvariantCulture, out port)) { return(new ServiceAddress() { Scheme = "http", Host = "+", Port = port, PathBase = "/" }); } return(null); } int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; var isUnixPipe = url.IndexOf(Constants.UnixPipeHostPrefix, schemeDelimiterEnd, StringComparison.Ordinal) == schemeDelimiterEnd; int pathDelimiterStart; int pathDelimiterEnd; if (!isUnixPipe) { pathDelimiterStart = url.IndexOf("/", schemeDelimiterEnd, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart; } else { pathDelimiterStart = url.IndexOf(":", schemeDelimiterEnd + Constants.UnixPipeHostPrefix.Length, StringComparison.Ordinal); pathDelimiterEnd = pathDelimiterStart + ":".Length; } if (pathDelimiterStart < 0) { pathDelimiterStart = pathDelimiterEnd = url.Length; } var serverAddress = new ServiceAddress(); serverAddress.Scheme = url.Substring(0, schemeDelimiterStart); var hasSpecifiedPort = false; if (!isUnixPipe) { int portDelimiterStart = url.LastIndexOf(":", pathDelimiterStart - 1, pathDelimiterStart - schemeDelimiterEnd, StringComparison.Ordinal); if (portDelimiterStart >= 0) { int portDelimiterEnd = portDelimiterStart + ":".Length; string portString = url.Substring(portDelimiterEnd, pathDelimiterStart - portDelimiterEnd); int portNumber; if (int.TryParse(portString, NumberStyles.Integer, CultureInfo.InvariantCulture, out portNumber)) { hasSpecifiedPort = true; serverAddress.Host = url.Substring(schemeDelimiterEnd, portDelimiterStart - schemeDelimiterEnd); serverAddress.Port = portNumber; } } if (!hasSpecifiedPort) { if (string.Equals(serverAddress.Scheme, "http", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 80; } else if (string.Equals(serverAddress.Scheme, "https", StringComparison.OrdinalIgnoreCase)) { serverAddress.Port = 443; } } } if (!hasSpecifiedPort) { serverAddress.Host = url.Substring(schemeDelimiterEnd, pathDelimiterStart - schemeDelimiterEnd); } // Path should not end with a / since it will be used as PathBase later if (url[url.Length - 1] == '/') { serverAddress.PathBase = url.Substring(pathDelimiterEnd, url.Length - pathDelimiterEnd - 1); } else { serverAddress.PathBase = url.Substring(pathDelimiterEnd); } //serverAddress.PathBase = PathNormalizer.NormalizeToNFC(serverAddress.PathBase); return(serverAddress); }