예제 #1
0
        public TCPClient(IPEndPoint remoteEP, ParticipantModel participant, NetworkModel network, Guid serverID)
        {
            m_Connected         = false;
            m_Network           = network;
            m_Participant       = participant;
            m_LastMsgReceived   = DateTime.MaxValue;
            m_ServerId          = serverID;
            m_ClientTimeout     = TimeSpan.FromMilliseconds(TCP_HEARTBEAT_TIMEOUT_DEFAULT_MS);
            this.m_RemoteEP     = remoteEP;
            m_Socket            = null;
            m_ServerParticipant = null;
            m_ReceiveQueue      = new Queue();
            this.m_Encoder      = new Chunk.ChunkEncoder();
            m_NetworkStatus     = new NetworkStatus(ConnectionStatus.Disconnected, ConnectionProtocolType.TCP, TCPRole.Client, 0);
            this.m_Network.RegisterNetworkStatusProvider(this, true, m_NetworkStatus);

            //Find out if client-side bridging is enabled
            m_BridgeEnabled = false;
            string enableBridge = System.Configuration.ConfigurationManager.AppSettings[this.GetType().ToString() + ".EnableBridge"];

            if (enableBridge != null)
            {
                bool enable = false;
                if (bool.TryParse(enableBridge, out enable))
                {
                    Trace.WriteLine("Unicast to Multicast Bridge enabled=" + enable.ToString(), this.GetType().ToString());
                    m_BridgeEnabled = enable;
                }
            }
        }
예제 #2
0
        public TCPServer(IPEndPoint localEP, PresenterModel model, ClassroomModel classroom,
                         InstructorModel instructor)
        {
            string portStr = System.Configuration.ConfigurationManager.AppSettings[this.GetType().ToString() + ".TCPListenPort"];
            int    p;

            if (Int32.TryParse(portStr, out p))
            {
                TCPListenPort = p;
            }
            RestoreConfig();
            m_ClientConnected = new ManualResetEvent(false);
            m_Participant     = model.Participant;
            m_Classroom       = classroom;
            m_ClientCount     = 0;
            this.m_Network    = model.Network;
            m_NetworkStatus   = new NetworkStatus(ConnectionStatus.Disconnected, ConnectionProtocolType.TCP, TCPRole.Server, 0);
            this.m_Network.RegisterNetworkStatusProvider(this, true, m_NetworkStatus);

            if (localEP != null)
            {
                this.m_ListenEP = localEP;
            }
            else
            {
                IPAddress ip = IPAddress.Any;
                //Use IPv4 unless it is unavailable.  TODO: Maybe this should be a configurable parameter?
                if ((!Socket.OSSupportsIPv4) && (Socket.OSSupportsIPv6))
                {
                    ip = IPAddress.IPv6Any;
                }
                this.m_ListenEP = new IPEndPoint(ip, TCPListenPort);
            }

            m_AllClients   = new Hashtable();
            m_ReceiveQueue = new Queue();

            this.m_Encoder      = new Chunk.ChunkEncoder();
            this.m_ServerSender = new TCPServerSender(instructor);

            //Start bridging if config file says so
#if RTP_BUILD
            m_U2MBridge = null;
            string enableBridge = System.Configuration.ConfigurationManager.AppSettings[this.GetType().ToString() + ".EnableBridge"];
            if (enableBridge != null)
            {
                bool enable = false;
                if (bool.TryParse(enableBridge, out enable) && enable)
                {
                    Trace.WriteLine("Unicast to Multicast Bridge enabled.", this.GetType().ToString());
                    m_U2MBridge = new UnicastToMulticastBridge(model);
                }
            }
#endif
        }
예제 #3
0
        public UnicastToMulticastBridge(PresenterModel model)
        {
            GetConfig();

            //Prepare for RTP sending
            m_RtpParticipant = new RtpParticipant(m_Cname, m_Name);
            try {
                m_RtpSession = new RtpSession(m_MulticastEndpoint, m_RtpParticipant, true, false);
            }
            catch (Exception e) {
                Trace.WriteLine(e.ToString());
                m_RtpSession     = null;
                m_RtpParticipant = null;
                return;
            }

            try {
                /// Notes about FEC:  There are two types supported by the MSR RTP stack:  Frame-based and Packet-based.
                /// Setting cDataPx to zero forces frame-based.  In this case cFecPx is a percentage.  It must be greater than zero, but can be
                /// very large, eg. 1000.  Frame-based FEC appears to be better for large frames (which the stack splits into multiple packets)
                /// possibly because the FEC packets for the frame are not interlaced in time sequence with the frame packets.
                /// If cDataPx is not zero, packet-based FEC is used.  In this mode cDataPx and cFecPx are a ratio of data packets to fec packets.
                /// For single packet frames, 1:1 and 0:100 are identical.  Single packet frames are frames smaller than
                /// the MTU which is normally 1500 bytes.  Presenter's Chunk encoder creates frames up to 16kbytes.  Many frames are smaller
                /// than this, but only a few are below the MTU.  For this reason we will always use Frame-based FEC.  Usful values are expected to
                /// be from around 10 up to around 100.  More than 100 might be good in some cases, but might impact performance.
                /// More than 500 would probably never be advised.
                m_RtpSender = m_RtpSession.CreateRtpSenderFec("Classroom Presenter Unicast to Multicast Bridge", PayloadType.dynamicPresentation, null, 0, m_Fec);
                m_RtpSender.DelayBetweenPackets = m_InterpacketDelay;
            }
            catch (Exception e) {
                Trace.WriteLine(e.ToString());
                try {
                    m_RtpSession.Dispose();
                }
                catch { }
                m_RtpParticipant = null;
                m_RtpSession     = null;
                m_RtpSender      = null;
                return;
            }

            //Prepare the beacon
            this.m_ChunkSequence = 0;
            this.m_Encoder       = new Chunk.ChunkEncoder();
            this.m_BeaconService = new Beacons.BridgeBeaconService(this, model);

            //Prepare the queue and sending thread
            m_Disposing     = false;
            m_SendQueueWait = new EventWaitHandle(false, EventResetMode.AutoReset);
            m_SendQueue     = new PriorityQueue <BridgeMessage>();
            m_SendThread    = new Thread(new ThreadStart(SendThread));
            m_SendThread.Start();
        }
        public ClientUnicastToMulticastBridge(PresenterModel model) : base(model)
        {
            m_Disposing          = false;
            this.m_ChunkSequence = 0;
            this.m_Encoder       = new Chunk.ChunkEncoder();

            //make a queue and a thread
            m_SendQueueWait = new EventWaitHandle(false, EventResetMode.AutoReset);
            m_SendQueue     = new Queue <ChunksAndPriority>();
            m_SendThread    = new Thread(new ThreadStart(SendThread));
            m_SendThread.Start();
        }
예제 #5
0
        public CXPCapabilityMessageSender(PresenterModel model, PresenterCapability capability)
        {
            this.m_Model          = model;
            this.m_LocalId        = m_Model.Participant.Guid;
            this.m_Classroom      = new ClassroomModel(null, "CXP Capability Classroom", ClassroomModelType.CXPCapability);
            this.m_Capability     = capability;
            this.m_Participants   = new Dictionary <string, ParticipantModel>();
            this.m_SsrcToSenderId = new Dictionary <uint, Guid>();
            this.m_Receivers      = new Dictionary <string, CXPCapabilityMessageReceiver>();

            m_Capability.OnStreamAdded   += new PresenterCapability.OnStreamAddedHandler(OnStreamAdded);
            m_Capability.OnStreamRemoved += new PresenterCapability.OnStreamRemovedHandler(OnStreamRemoved);
            using (Synchronizer.Lock(this)) {
                // Initialize the message chunking utilities.
                this.m_Encoder = new Chunk.ChunkEncoder();
                // TODO: Make the buffer size dynamic, ie., grow if we send a single very large message.
                // Make the buffer store up to 5MB worth of data.
                this.m_FrameBuffer = new FrameBuffer(5 * 1024 * 1024 / this.m_Encoder.MaximumChunkSize);

                // Create the NackManager which is responsible for sending NACKs on behalf of
                // our set of RTPMessageReceivers.
                this.m_NackManager = new RTPNackManager(this, this.m_Classroom);
            }

            // Create network services outside of the "lock(this)" so they can lock their own objects
            // without worrying about locking order.

            // Create the PresenterNetworkService which will watch for changes to the model and send messages.
            this.m_PresenterNetworkService = new PresenterNetworkService(this, this.m_Model);

            // Create the StudentSubmissionsNetworkService which will watch for requests to submit and send messages.
            this.m_StudentSubmissionNetworkService = new StudentSubmissionNetworkService(this, this.m_Model);

            // Create the SynchronizationNetworkService which will watch for all synchronization messages.
            this.m_SynchronizationNetworkService = new SynchronizationNetworkService(this, this.m_Model);

            // Create the ScriptingNetworkService which will watch for all scripting messages.
            this.m_ScriptingNetworkService = new ScriptingNetworkService(this, this.m_Model);

            // Create the BeaconService which will broadcast periodic information about the presentation.
            this.m_BeaconService = new Beacons.DefaultBeaconService(this, this.m_Model);

            // Report Network status to the UI
            m_CapabilityNetworkStatus = new CapabilityNetworkStatus(this.m_Model);
            m_CapabilityNetworkStatus.Register();

            // Send an initial message to announce our node to others in the venue.
            SendObject(new CapabilityMessageWrapper(null, m_LocalId, Guid.Empty, m_Capability.IsSender));
        }
예제 #6
0
        public TCPMessageSender(ITCPSender server, PresenterModel model, ClassroomModel classroom)
        {
            this.m_Model     = model;
            this.m_Classroom = classroom;
            this.m_Sender    = server;

            // Initialize the message chunking utilities.
            this.m_Encoder = new Chunk.ChunkEncoder();

            // Most of the same services are created as in RTPMessageSender, with the exception
            // (for now, at least) that there is no BeaconService.

            // Create the PresenterNetworkService which will watch for changes to the model and send messages.
            this.m_PresenterNetworkService = new PresenterNetworkService(this, this.m_Model);

            // Create the StudentSubmissionsNetworkService which will watch for requests to submit and send messages.
            this.m_StudentSubmissionNetworkService = new StudentSubmissionNetworkService(this, this.m_Model);

            // Create the SynchronizationNetworkService which will watch for all synchronization messages.
            //this.m_SynchronizationNetworkService = new SynchronizationNetworkService(this, this.m_Model);

            // Create the ScriptingNetworkService which will watch for all scripting messages.
            //this.m_ScriptingNetworkService = new ScriptingNetworkService(this, this.m_Model);
        }
예제 #7
0
        public RTPMessageSender(IPEndPoint ep, PresenterModel model, ClassroomModel classroom)
        {
            this.m_Model     = model;
            this.m_Classroom = classroom;

            this.m_RtpLocalParticipant = new RtpLocalParticipant(this.m_Model.Participant);

            using (Synchronizer.Lock(this)) {
                // Register the stream event listeners first, since otherwise there would be a chance
                // that streams could be added between creating the RtpSession (which connects immediately).
                this.m_ParticipantManager = new ParticipantManager(this);

                this.m_RtpSession = new RtpSession(ep, this.m_RtpLocalParticipant, true, true);

                // TODO: Choose a meaningful value for the RtpSender name.
                ushort fec;
                short  interpacketdelay;
                using (Synchronizer.Lock(model.SyncRoot)) {
                    using (Synchronizer.Lock(model.ViewerState.SyncRoot)) {
                        fec = (ushort)model.ViewerState.ForwardErrorCorrection;
                        interpacketdelay = (short)model.ViewerState.InterPacketDelay;
                    }
                }
                if (fec == 0)
                {
                    this.m_RtpSender = this.m_RtpSession.CreateRtpSender("Classroom Presenter", PayloadType.dynamicPresentation, null);
                }
                else
                {
                    this.m_RtpSender = this.m_RtpSession.CreateRtpSenderFec("Classroom Presenter", PayloadType.dynamicPresentation, null, 0, fec);
                }
                this.m_RtpSender.DelayBetweenPackets = interpacketdelay;

                // Initialize the message chunking utilities.
                this.m_Encoder = new Chunk.ChunkEncoder();
                // TODO: Make the buffer size dynamic, ie., grow if we send a single very large message.
                // Make the buffer store up to 5MB worth of data.
                this.m_FrameBuffer = new FrameBuffer(5 * 1024 * 1024 / this.m_Encoder.MaximumChunkSize);

                // Create the NackManager which is responsible for sending NACKs on behalf of
                // our set of RTPMessageReceivers.
                this.m_NackManager = new RTPNackManager(this, this.m_Classroom);
            }

            // Create network services outside of the "lock(this)" so they can lock their own objects
            // without worrying about locking order.

            // Create the PresenterNetworkService which will watch for changes to the model and send messages.
            this.m_PresenterNetworkService = new PresenterNetworkService(this, this.m_Model);

            // Create the StudentSubmissionsNetworkService which will watch for requests to submit and send messages.
            this.m_StudentSubmissionNetworkService = new StudentSubmissionNetworkService(this, this.m_Model);

            // Create the SynchronizationNetworkService which will watch for all synchronization messages.
            this.m_SynchronizationNetworkService = new SynchronizationNetworkService(this, this.m_Model);

            // Create the ScriptingNetworkService which will watch for all scripting messages.
            this.m_ScriptingNetworkService = new ScriptingNetworkService(this, this.m_Model);

            // Create the BeaconService which will broadcast periodic information about the presentation.
            this.m_BeaconService = new Beacons.DefaultBeaconService(this, this.m_Model);
        }