예제 #1
0
파일: Listener.cs 프로젝트: toomasz/emitter
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }