예제 #1
0
        /// <summary>
        /// What is the result of the this request?
        /// The method will keep waiting/requesting an answer till the answer is received or the timeout is reached
        /// </summary>
        /// <param name="message">The request</param>
        /// <param name="timeOut">The time to wait in milliseconds, 0 means forever</param>
        /// <returns>The result, null in the case an answer isn't received</returns>
        public object SendRequest(object message, long timeOut)
        {
            Contract.Requires(message != null);
            Contract.Requires(timeOut >= 0);

            // Send a request
            this.requestId++;
            Packet packet = new Packet("server", this.name, this.requestId.ToString(), message);
            this.udpMulticast.Send(packet);

            // Start listening for a reply
            long preTime = DateTime.Now.ToFileTime();

            // Test if the timeout is 0 or the timeout value has run out
            while (timeOut == 0 || DateTime.Now.ToFileTime() < preTime + (timeOut * 10000)) {
                // Wait for reply
                object result = this.udpMulticast.Receive(500);
                if (result == null) {
                    // No reply - resend...
                    Debug.WriteLine("Client repeats");
                    this.udpMulticast.Send(packet);
                }
                else if (result is Packet) {
                    // A packet was received
                    Packet recPacket = (Packet)result;

                    // Test if the packet is for us
                    if (recPacket.GetReceiverId.Equals(this.name) && recPacket.GetRequestId.Equals(this.requestId.ToString())) {
                        return recPacket.GetMessage;
                    }
                }
            }

            // The timeout value has expired
            return null;
        }
예제 #2
0
        /// <summary>
        /// Listen for calls for this amount of time
        /// If a request with the same request id is repeated, the reply is repeated
        /// </summary>
        /// <param name="timeOut">The time to wait in miliseconds</param>
        public void ListenForCalls(long timeOut)
        {
            Contract.Requires(timeOut >= 0);
            Contract.Requires(this.RequestHandler != null);

            // If the server should listen for requests forever
            bool runForever = timeOut == 0;

            // The time before the loop was entered
            long preTime = DateTime.Now.ToFileTime();

            // Listen
            while (runForever || DateTime.Now.ToFileTime() < preTime + (timeOut * 10000)) {
                // Receive the packet
                object data;
                if (runForever) {
                    // The udpMulticast is allowed to block forever
                    data = this.udpMulticast.Receive(0);
                }
                else {
                    // The udpMulticast is allowed to block for the time left
                    long timeLeft = ((preTime + (timeOut * 10000)) - DateTime.Now.ToFileTime()) / 10000;
                    data = this.udpMulticast.Receive(timeLeft);
                }

                // Test if it's a valid packet
                if (data == null || !(data is Packet)) {
                    continue;
                }

                // Test if the packet is for the server
                Packet recPacket = (Packet)data;

                if (recPacket.GetReceiverId.Equals("server")) {
                    // If the packet has been received before
                    if (this.prevPackets.ContainsKey(recPacket.GetSenderId + "#" + recPacket.GetRequestId)) {
                        // Repeat the reply
                        this.udpMulticast.Send(this.prevPackets[recPacket.GetSenderId + "#" + recPacket.GetRequestId]);
                    }
                    else {
                        // The package has not been seen before and we need to generate a response
                        Console.Out.WriteLine("Server sends fresh");
                        string senderId = recPacket.GetSenderId;
                        string requestId = recPacket.GetRequestId;
                        object resultMessage = this.RequestHandler.Invoke(recPacket.GetMessage);
                        Packet resultPacket = new Packet(senderId, "server", requestId, resultMessage);

                        // Add this request and reply to the list of previous packets
                        this.prevPackets.Add(recPacket.GetSenderId + "#" + recPacket.GetRequestId, resultPacket);
                        this.udpMulticast.Send(resultPacket);
                    }
                }
            }
        }