Example #1
0
        /// <summary>
        /// Send application data to the connected endpoint
        /// </summary>
        /// <remarks>This method is blocking</remarks>
        /// <param name="payload"></param>
        public Response Send(byte[] payload)
        {
            var id = _messageIdProvider.Next();

            try
            {
                // disallow sending if the session is not in the open state
                if (State != SessionState.Open)
                {
                    throw new SessionException();
                }

                // create message with next message ID - do not add the payload to the message as message is just for tracking
                var message = new Message(this, id, null);

                // add to the message pending settlement collection - will be accessed async
                lock (_pendingMessages)
                {
                    _pendingMessages.Add(message.ID, message);
                }

                // pass the message down to the connection for transmission
                Connection.SendMessage(ID, message.ID, payload);

                // wait for the message to be settled or time out
                if (!message.Settled.WaitOne(60000))
                {
                    throw new MessageTimeoutException();
                }

                // return the response
                return(new Response(message.Accepted, message.ResponseData));
            }
            finally
            {
                lock (_pendingMessages)
                {
                    _pendingMessages.Remove(id);
                }

                _messageIdProvider.Remove(id);
            }
        }
Example #2
0
        /// <summary>
        /// Creates a new session between both endpoints
        /// </summary>
        /// <param name="name">The application-defined name for the session</param>
        /// <param name="data">Optional payload data to be sent to the remote endpoint</param>
        /// <returns>The created session</returns>
        public Session CreateSession(string name, byte[] data = null)
        {
            if (State != ConnectionState.Open)
            {
                throw new ConnectionException();
            }

            uint id = uint.MaxValue;

            try
            {
                // create the session descriptor which is sent to the remote endpoint
                var descriptor = new SessionDescriptor
                {
                    Name = name,
                    Data = data
                };

                // construct new session frame
                Session session;
                lock (_pendingSessions)
                {
                    id      = _sessionIdProvider.Next();
                    session = new Session(this, descriptor, id);
                    _pendingSessions.Add(session.ID, session);
                }

                // send the session start frame
                _sendFrame(FrameType.SessionStart, Frame.CreateSessionStartFrame(session.ID, BsonCodec.Encode(descriptor)));

                // block until the connection is settled or a timeout occurs
                var index = WaitHandle.WaitAny(new[] { session.Settled, session.SessionError }, 5000);

                switch (index)
                {
                // session was settled (application needs to check if it was accepted/rejected
                case 0: return(session);

                // the session was rejected by the remote endpoint
                case 1: throw new SessionRejectedException($"The session was rejected by the remote endpoint");

                // the session creation timedout
                case WaitHandle.WaitTimeout: throw new SessionTimeoutException($"Session settlement timed out after {5000} ms");

                // should never hit here, but have to return something
                default: throw new Exception();
                }
            }
            catch (Exception)
            {
                lock (_pendingSessions)
                {
                    if (_pendingSessions.ContainsKey(id))
                    {
                        _pendingSessions.Remove(id);
                    }

                    _sessionIdProvider.Remove(id);
                }

                throw;
            }
        }