Exemplo n.º 1
0
 public void SendDeltaToPeer(NodePeer ToPeer, NodeBase Message, NodeBase BasedOnMessage)
 {
     CommunicationManager.SendDeltaToPeer(ToPeer, this, Message, BasedOnMessage);
 }
Exemplo n.º 2
0
        internal void ThreadStart(Object o)
        {
            SslStream sslStream = o as SslStream;

            if (sslStream != null)
            {
                //Have to send the local peer list to the other end of
                //the connection, and we also need to be notified of any
                //changes to the local peer list.  This has to be done
                //in one operation so a new node can't sneak in between
                //us reading the nodelist, and us registering the event.
                lock (m_OutgoingQueue_Lock) //don't let the callback enqueue a message first
                {
                    NodePeerList localPeerList =
                        CommunicationManager.RegisterLocalPeerListChangedCallback(
                            new CommunicationManager.LocalPeerListChangedHandler(
                                LocalPeerListChangedCallback));
                    Send(localPeerList.ToXml());
                }

                //kick off a read callback chain of threads
                lock (m_ReadCallback_Lock)
                {
                    sslStream.BeginRead(m_newData, 0, m_newData.Length,
                                        new AsyncCallback(ReadCallback), sslStream);
                }

                bool stop = false;
                while (!stop)
                {
                    //send any queued messages
                    int outgoingCount = 0;
                    lock (m_OutgoingQueue_Lock)
                    {
                        outgoingCount = m_OutgoingQueue.Count;
                    }
                    while (outgoingCount > 0)
                    {
                        string data = null;
                        lock (m_OutgoingQueue_Lock)
                        {
                            data = m_OutgoingQueue.Dequeue();
                        }

                        //encode it to base 64 so we don't have to worry about control codes
                        byte[] encbuf      = System.Text.Encoding.Unicode.GetBytes(data);
                        string encodedData = Convert.ToBase64String(encbuf) + "\n"; //terminate in newline to denote the end of the message

                        //convert to a byte array
                        byte[] writebuf = System.Text.Encoding.ASCII.GetBytes(encodedData);

                        sslStream.Write(writebuf);
                        sslStream.Flush();

                        outgoingCount--;
                    }

                    //process any received messages
                    int incomingCount = 0;
                    lock (m_IncomingQueue_Lock)
                    {
                        incomingCount = m_IncomingQueue.Count;
                    }
                    while (incomingCount > 0)
                    {
                        string data = null;
                        lock (m_IncomingQueue_Lock)
                        {
                            data = m_IncomingQueue.Dequeue();
                        }

                        //message is in base 64, so convert back to a string
                        byte[] decbuff = Convert.FromBase64String(data);
                        string message = System.Text.Encoding.Unicode.GetString(decbuff);

                        Receive(message);
                        incomingCount--;
                    }

                    //wait
                    System.Threading.Thread.Sleep(100);

                    lock (m_CloseRequest_Lock)
                    {
                        if (stop == false)
                        {
                            stop = m_CloseRequest;
                        }
                    }
                }

                //See if we closed due to an exception in the reader thread
                Exception readException = null;
                lock (m_readException_Lock)
                {
                    readException = m_readException;
                }
                if (readException != null)
                {
                    //TODO propagate this exception to higher code
                }

                //clean up the stream
                sslStream.Close();
            }
        }
Exemplo n.º 3
0
 public void SendToPeer(NodePeer ToPeer, NodeBase Message)
 {
     CommunicationManager.SendToPeer(ToPeer, this, Message);
 }
Exemplo n.º 4
0
        private void Receive(string message)
        {
            //TextWriter tw = new StreamWriter("receive_" + this.ID.ToString() + ".txt", true);
            //tw.WriteLine(message);
            //tw.Close();

            if (ValidateXmlToSchema(message))
            {
                FieldGuid toPeerID   = NodeBase.ToPeerFromXML(message);
                FieldGuid fromPeerID = NodeBase.FromPeerFromXML(message);
                if (toPeerID != null && fromPeerID != null)
                {
                    //it's a peer-to-peer message

                    //find the ToPeer in the local peer list
                    NodePeer ToPeer = CommunicationManager.LocalPeerList.FindPeerByID(toPeerID);

                    //find the FromPeer in the remote peer list
                    NodePeer FromPeer = RemotePeerList.FindPeerByID(fromPeerID);

                    if (ToPeer != null && FromPeer != null)
                    {
                        //see if this message is based on another node
                        FieldGuid BasedOnNodeID = NodeBase.BasedOnNodeIDFromXML(message);
                        NodeBase  basedOnNode   = null;
                        if (BasedOnNodeID != null)
                        {
                            basedOnNode = ToPeer.ReceiveDeltaFromPeer(FromPeer, BasedOnNodeID);
                            NodeBase msg = NodeBase.NodeFromXML(message, basedOnNode.GetChildrenRecursive());
                            CommunicationManager.SendDeltaToPeer(ToPeer, FromPeer, msg, basedOnNode);
                        }
                        else
                        {
                            NodeBase msg = NodeBase.NodeFromXML(message, null);
                            CommunicationManager.SendToPeer(ToPeer, FromPeer, msg);
                        }
                    }
                    else
                    {
                        //TODO - log this - undeliverable message (peer lists not up to date?)
                    }
                }
                else
                {
                    //it's a system message (not peer-to-peer)
                    FieldNodeType nodeType = NodeBase.NodeTypeFromXML(message);
                    if (nodeType.ToString() == typeof(NodePeerList).FullName)
                    {
                        lock (m_remotePeerList_Lock) //lock so we read/write in one operation
                        {
                            //When we receive a remote peer list, it is generally just a diff
                            //from the last peer list.
                            RemotePeerList = (NodePeerList)NodeBase.NodeFromXML(
                                message, RemotePeerList.GetChildrenRecursive());
                        }
                    }
                    else
                    {
                        //TODO - log this?  Unknown root message type?
                    }
                }
            }
            else
            {
                //TODO - log this?  Unknown garbage message?
            }
        }