示例#1
0
文件: Proxy.cs 项目: knocte/netmq
    public static bool proxy(SocketBase frontend_,
        SocketBase backend_, SocketBase capture_)
    {
        //  The algorithm below assumes ratio of requests and replies processed
        //  under full load to be 1:1.

        //  TODO: The current implementation drops messages when
        //  any of the pipes becomes full.

        bool success = true;
        int rc;
        long more;
        Msg msg;
        PollItem[] items = new PollItem[2];

        items[0] = new PollItem (frontend_, ZMQ.ZmqPollin );
        items[1] = new PollItem (backend_, ZMQ.ZmqPollin );

        Selector selector;
        try {
            selector = Selector.open();
        } catch (IOException e) {
            throw new ZError.IOException(e);
        }

        try {
            while (!Thread.currentThread().isInterrupted()) {
                //  Wait while there are either requests or replies to process.
                rc = ZMQ.zmq_poll (selector, items, -1);
                if (rc < 0)
                    return false;

                //  Process a request.
                if (items [0].isReadable()) {
                    while (true) {
                        msg = frontend_.Recv (0);
                        if (msg == null) {
                            return false;
                        }

                        more = frontend_.getsockopt (ZMQ.ZMQ_RCVMORE);

                        if (more < 0)
                            return false;

                        //  Copy message to capture socket if any
                        if (capture_ != null) {
                            Msg ctrl = new Msg (msg);
                            success = capture_.Send (ctrl, more > 0 ? ZMQ.ZMQ_SNDMORE: 0);
                            if (!success)
                                return false;
                        }

                        success = backend_.Send (msg, more > 0 ? ZMQ.ZMQ_SNDMORE: 0);
                        if (!success)
                            return false;
                        if (more == 0)
                            break;
                    }
                }
                //  Process a reply.
                if (items [1].isReadable()) {
                    while (true) {
                        msg = backend_.Recv (0);
                        if (msg == null) {
                            return false;
                        }

                        more = backend_.getsockopt (ZMQ.ZMQ_RCVMORE);

                        if (more < 0)
                            return false;

                        //  Copy message to capture socket if any
                        if (capture_ != null) {
                            Msg ctrl = new Msg (msg);
                            success = capture_.Send (ctrl, more > 0 ? ZMQ.ZMQ_SNDMORE: 0);
                            if (!success)
                                return false;
                        }

                        success = frontend_.Send (msg, more > 0 ? ZMQ.ZMQ_SNDMORE: 0);
                        if (!success)
                            return false;
                        if (more == 0)
                            break;
                    }
                }

            }
        } finally {
            try {
                selector.close();
            } catch (Exception e) {
            }
        }

        return true;
    }
示例#2
0
文件: ZMQ.cs 项目: knocte/netmq
        ////  The proxy functionality
        //public static bool zmq_proxy(SocketBase frontend_, SocketBase backend_, SocketBase control_)
        //{
        //    if (frontend_ == null || backend_ == null)
        //    {
        //        ZError.errno = (ZError.EFAULT);
        //        throw new ArgumentException();
        //    }
        //    return Proxy.proxy(
        //        frontend_,
        //        backend_,
        //        control_);
        //}
        //[Obsolete]
        //public static bool zmq_device(int device_, SocketBase insocket_,
        //        SocketBase outsocket_)
        //{
        //    return Proxy.proxy(insocket_, outsocket_, null);
        //}
        public static int Poll(PollItem[] items, int timeout)
        {
            if (items == null)
            {
                ZError.ErrorNumber = (ErrorNumber.EFAULT);
                throw new ArgumentException();
            }
            if (items.Length == 0)
            {
                if (timeout == 0)
                    return 0;
                Thread.Sleep(timeout);
                return 0;
            }

            bool firstPass = true;

            Socket[] writeList =
                    items.Where(p => (p.Events & PollEvents.PollOut) == PollEvents.PollOut).Select(
                        p => p.Socket != null ? p.Socket.FD : p.FileDescriptor).ToArray();

            Socket[] readList =
                items.Where(p => (p.Events & PollEvents.PollOut) == PollEvents.PollIn).Select(
                    p => p.Socket != null ? p.Socket.FD : p.FileDescriptor).ToArray();

            Socket[] errorList =
                items.Where(p => (p.Events & PollEvents.PollOut) == PollEvents.PollError).Select(
                    p => p.Socket != null ? p.Socket.FD : p.FileDescriptor).ToArray();

            Socket[] inset = new Socket[writeList.Length];
            Socket[] outset = new Socket[readList.Length];
            Socket[] errorset = new Socket[errorList.Length];

            Dictionary<Socket, PollItem> socketsToItems = items.Select(
                p => new { Socket = p.Socket != null ? p.Socket.FD : p.FileDescriptor, Item = p }).
                ToDictionary(i => i.Socket, i => i.Item);

            Stopwatch stopwatch = null;

            while (true)
            {
                int currentTimeoutMicroSeconds;

                if (firstPass)
                {
                    currentTimeoutMicroSeconds = 0;
                }
                else
                {
                    currentTimeoutMicroSeconds = (int)((timeout - stopwatch.ElapsedMilliseconds) % 1000 * 1000);
                }

                Buffer.BlockCopy(readList, 0, inset, 0, readList.Length);
                Buffer.BlockCopy(writeList, 0, inset, 0, writeList.Length);
                Buffer.BlockCopy(errorList, 0, inset, 0, errorList.Length);

                try
                {
                    System.Net.Sockets.Socket.Select(inset, outset, errorset, currentTimeoutMicroSeconds);
                }
                catch (SocketException ex)
                {
                    // TODO: change to right error
                    ZError.ErrorNumber = ErrorNumber.ESOCKET;

                    return -1;
                }

                foreach (var pollItem in items)
                {
                    pollItem.ResultEvent = PollEvents.None;
                }

                foreach (var socket in inset)
                {
                    if (socket != null)
                    {
                        var item = socketsToItems[socket];

                        if (item.Socket != null)
                        {
                            PollEvents value = (PollEvents)GetSocketOption(item.Socket, ZmqSocketOptions.Events);

                            if (value == PollEvents.PollIn)
                            {
                                item.ResultEvent |= PollEvents.PollIn;
                            }
                        }
                        else
                        {
                            item.ResultEvent |= PollEvents.PollIn;
                        }
                    }
                }

                foreach (var socket in outset)
                {
                    if (socket != null)
                    {
                        var item = socketsToItems[socket];

                        if (item.Socket != null)
                        {
                            PollEvents value = (PollEvents)GetSocketOption(item.Socket, ZmqSocketOptions.Events);

                            if (value == PollEvents.PollOut)
                            {
                                item.ResultEvent |= PollEvents.PollOut;
                            }
                        }
                        else
                        {
                            item.ResultEvent |= PollEvents.PollOut;
                        }
                    }
                }

                foreach (var socket in errorList)
                {
                    if (socket != null)
                    {
                        var item = socketsToItems[socket];

                        if (item.Socket == null)
                        {
                            item.ResultEvent |= PollEvents.PollError;
                        }
                    }
                }

                if (timeout == 0)
                {
                    break;
                }

                if (items.Any(i => i.ResultEvent != PollEvents.None))
                {
                    break;
                }

                if (timeout < 0)
                {
                    if (firstPass)
                    {
                        firstPass = false;
                    }

                    continue;
                }

                if (firstPass)
                {
                    stopwatch = Stopwatch.StartNew();
                    firstPass = false;
                    continue;
                }

                if (stopwatch.ElapsedMilliseconds > timeout)
                {
                    break;
                }
            }

            return items.Where(i => i.ResultEvent != PollEvents.None).Count();
        }