protected override bool UpdateTarget( ReceiveContext context )
        {
            using( Synchronizer.Lock( context.Model.SyncRoot ) ) {
                using( Synchronizer.Lock( context.Model.ViewerState.Diagnostic.SyncRoot ) )
                    context.Model.ViewerState.Diagnostic.ExecuteLocalScript = !context.Model.ViewerState.Diagnostic.ExecuteLocalScript;
            }

            return false;
        }
        public CXPCapabilityMessageReceiver(CXPCapabilityMessageSender sender, uint ssrc, PresenterModel model, ClassroomModel classroom, ParticipantModel participant)
        {
            this.m_Model = model;
            this.m_Sender = sender;
            this.m_RemoteSSRC = ssrc;

            this.m_Context = new ReceiveContext(model, classroom, participant);
            this.m_ContextArgs = new object[] { this.m_Context };
            this.m_Queue = new MessageProcessingQueue(this);

            this.m_Assembler = new ChunkAssembler();
            this.m_Assembler.Nack += new ChunkAssembler.NackDelegate(this.HandleAssemblerNack);
        }
        protected override bool UpdateTarget(ReceiveContext context)
        {
            // For the purposes of removal, whether the group is a Group or a SingletonGroup
            // doesn't matter; all that matters is the Guid.
            Group group = new Group(this.GroupId, this.FriendlyName);

            using (Synchronizer.Lock(context.Participant.SyncRoot)) {
                if (context.Participant.Groups.Contains(group))
                    context.Participant.Groups.Remove(group);
            }

            return false;
        }
Example #4
0
        protected override bool UpdateTarget( ReceiveContext context )
        {
            using( Synchronizer.Lock( context.Model.SyncRoot ) ) {
                // Check if this message is meant for this client
                using( Synchronizer.Lock( context.Model.Participant.SyncRoot ) )
                    if( context.Model.Participant.Role is InstructorModel ||
                        context.Model.Participant.Role.Id != this.participantId )
                        return false;

                // Set Client Model Sync State
                using( Synchronizer.Lock( context.Model.ViewerState.Diagnostic.SyncRoot ) )
                    context.Model.ViewerState.Diagnostic.ClientState = DiagnosticModel.ClientSyncState.PINGING;
            }

            return false;
        }
        public RTPMessageReceiver(RTPMessageSender sender, RtpStream stream, PresenterModel model, ClassroomModel classroom, ParticipantModel participant)
        {
            this.m_Model = model;
            this.m_Sender = sender;
            this.m_RtpStream = stream;

            this.m_Context = new ReceiveContext(model, classroom, participant);
            this.m_ContextArgs = new object[] { this.m_Context };
            this.m_Queue = new MessageProcessingQueue(this);

            this.m_Serializer = new BinaryFormatter();

            this.m_Assembler = new ChunkAssembler();
            this.m_Assembler.Nack += new ChunkAssembler.NackDelegate(this.HandleAssemblerNack);

            this.m_RtpStream.FrameReceived += new RtpStream.FrameReceivedEventHandler(this.HandleFrameReceived);
        }
        protected override bool UpdateTarget(ReceiveContext context)
        {
            // Discard bogus SingletonGroups.  A participant cannot
            // belong to a SingletonGroup that does not match his Guid.
            if (this.Singleton && this.GroupId != context.Participant.Guid)
                return false;

            Group group = this.Singleton
                ? new SingletonGroup(context.Participant)
                : new Group(this.GroupId, this.FriendlyName);

            using (Synchronizer.Lock(context.Participant.SyncRoot)) {
                if (!context.Participant.Groups.Contains(group)) {
                    context.Participant.Groups.Add(group);
                }
            }

            return false;
        }
Example #7
0
        protected override bool UpdateTarget(ReceiveContext context)
        {
            using (Synchronizer.Lock(context.Model.SyncRoot)) {
                // Ensure that this message is only handled by the correct student
                using (Synchronizer.Lock(context.Model.Participant.SyncRoot))
                    if (context.Model.Participant.Role is InstructorModel ||
                        context.Model.Participant.Role.Id != this.participantId)
                        return false;

                // Set the Client Model Sync State and update the latency
                using (Synchronizer.Lock(context.Model.ViewerState.Diagnostic.SyncRoot)) {
                    context.Model.ViewerState.Diagnostic.AddLatencyEntry(UW.ClassroomPresenter.Misc.AccurateTiming.Now);
                    context.Model.ViewerState.Diagnostic.ClientState = DiagnosticModel.ClientSyncState.START;
                }
            }

            return false;
        }
Example #8
0
        protected override bool UpdateTarget( ReceiveContext context )
        {
            using( Synchronizer.Lock( context.Model.SyncRoot ) ) {
                // Ensure that this message is only handled by the instructor
                using( Synchronizer.Lock( context.Model.Participant.SyncRoot ) )
                    if( !(context.Model.Participant.Role is InstructorModel) )
                        return false;

                // Set Server Model Sync State
                using( Synchronizer.Lock( context.Model.ViewerState.Diagnostic.SyncRoot ) )
                    context.Model.ViewerState.Diagnostic.ServerState = DiagnosticModel.ServerSyncState.PONGING;
            }

            return false;
        }
            /// <summary>
            /// Enqueues a message for later execution on the message thread.
            /// If the message thread is busy, and other messages are already
            /// enqueued, the messages are combined (<see cref="Message.ZipInto"/>),
            /// which may help to avoid duplicating work in some situations.
            /// For example, multiple "Ink Erase" messages received in a row
            /// can be combined into a single message, which saves the UI work
            /// by only repainting itself once.
            /// </summary>
            /// <remarks>
            /// (In fact, there is no "queue" -- meaning a list of messages -- but
            /// rather the "zipped" messages provide all the functionality we need.)
            /// 
            /// FIXME:  If we zip messages from different remote nodes, we 
            /// call OnReceive for all of them with the context of the last. 
            /// 
            /// </remarks>
            /// <param name="message">The message to execute</param>
            public void ProcessMessage(Message message,ReceiveContext context)
            {
                using (Synchronizer.Lock(this)) {
                    if (this.m_Waiting == null) {
                        this.m_Waiting = message;
                        this.Post(delegate() {
                            Message waited;
                            using (Synchronizer.Lock(this)) {
                                if (this.m_Waiting != null) {
                                    waited = this.m_Waiting;
                                    this.m_Waiting = null;
                                }
                                else {
                                    return;
                                }
                            }

                            waited.OnReceive(context);
                        });
                    }
                    else {
                        message.ZipInto(ref this.m_Waiting);
                    }
                }
            }
        /// <summary>
        /// Processes a message received over the TCP network interface.
        /// </summary>
        private void ReceiveThread()
        {
            while (true) {
                try {
                    if (this.m_Disposed)
                        return;

                    object message = null;
                    ReceiveMessageAndParticipant rm;

                    rm = (ReceiveMessageAndParticipant)this.m_Receiver.Read(); //does not block.
                    if (rm == null) { //probably because of empty receive queue
                        Thread.Sleep(50);
                        continue;
                    }
                    message = rm.Message;
                    ReceiveContext context = new ReceiveContext(m_Model,m_Classroom,rm.Participant);

                    // If the message is a chunked, process it with the Chunk Assembler.
                    // (Messages don't have to be chunked, in which case they are processed
                    // immediately below).  If the chunk is the last remaining chunk composing
                    // a message, then the Assembler returns the completed message.
                    if (message is Chunk) {
                        Chunk chunk = message as Chunk;
                        try {
                            Debug.WriteLine(string.Format("Received message #{0}, chunk #{1} of {2}, {3} bytes.",
                                chunk.MessageSequence,
                                chunk.ChunkSequenceInMessage + 1,
                                chunk.NumberOfChunksInMessage,
                                chunk.Data.Length),
                                this.GetType().ToString());

                            message = this.m_Assembler.Add((Chunk)message);

                        }
                        catch (Exception e) {
                            Trace.WriteLine(string.Format("Error deserializing a message from message #{0}, chunk #{1} of {2} ({3} bytes): {4}",
                                chunk.MessageSequence,
                                chunk.ChunkSequenceInMessage + 1,
                                chunk.NumberOfChunksInMessage,
                                chunk.Data.Length, e.ToString()),
                                this.GetType().ToString());
                            continue;
                        }
                    }

                    // If we have a valid/complete message, queue it for processing on the separate
                    // message execution thread.
                    if (message is IEnumerable<object>) {
                        foreach (object decoded in (IEnumerable<object>)message) {
                            if (decoded is Message) {
                                Message m = (Message)decoded;

                                this.m_Model.ViewerState.Diagnostic.LogMessageRecv(m);

                                //Debug.WriteLine(string.Format("Received message: {0} bytes, type {1}",
                                //    "???", m.GetType()), this.GetType().ToString());
                                Debug.WriteLine("Received message:" + m.ToString(),"TCPMessageReceiver");
                                //If enabled, do client-slide bridging
            #if RTP_BUILD
                                if (this.m_U2MBridge != null) {
                                    this.m_U2MBridge.SendToBridge(m.Clone());
                                }
            #endif
                                // Send it off for processing.
                                this.m_Queue.ProcessMessage(m, context);
                            }
                            else if (decoded != null) {
                                Trace.WriteLine("Received unknown message type: " + decoded.GetType().ToString(),
                                    this.GetType().ToString());
                            }
                        }
                    }
                    else if (message != null) {
                        Trace.WriteLine("Received unknown message type: " + message.GetType().ToString(),
                            this.GetType().ToString());
                    }

                }
                catch (Exception e) {
                    // The application should not crash on account of malformed messages sent from remote clients.
                    // Therefore, we catch all exceptions.  We only want to print an error message.
                    Trace.WriteLine("Error processing a message: " + e.ToString(),
                        this.GetType().ToString());
                }
            }
        }