/// <summary> /// Move the specified <see cref="P2PSession"/> to the new <see cref="P2PBridge"/> specified. /// </summary> /// <param name="session"></param> /// <param name="newBridge"></param> public virtual void MigrateQueue(P2PSession session, P2PBridge newBridge) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, String.Format("P2PBridge {0} migrating session {1} queue to new bridge {2}", this.ToString(), session.SessionId, (newBridge != null) ? newBridge.ToString() : "null"), GetType().Name); P2PSendQueue newQueue = new P2PSendQueue(); lock (sendingQueues) { if (sendingQueues.ContainsKey(session)) { if (newBridge != null) { lock (sendingQueues[session]) { foreach (P2PSendItem item in sendingQueues[session]) newQueue.Enqueue(item); } } sendingQueues.Remove(session); } } lock (sendQueues) { if (sendQueues.ContainsKey(session)) { if (newBridge != null) { while (sendQueues[session].Count > 0) newQueue.Enqueue(sendQueues[session].Dequeue()); } sendQueues.Remove(session); } } lock (stoppedSessions) { if (stoppedSessions.Contains(session)) { stoppedSessions.Remove(session); } } if (newBridge != null) newBridge.AddQueue(session, newQueue); }
/// <summary> /// Send a P2P Message to the specified P2PSession. /// </summary> /// <param name="session"> /// The application layer, which is a <see cref="P2PSession"/> /// </param> /// <param name="remote"> /// he receiver <see cref="Contact"/> /// </param> /// <param name="remoteGuid"> /// A <see cref="Guid"/> /// </param> /// <param name="msg"> /// he <see cref="P2PMessage"/> to be sent. /// </param> /// <param name="ackTimeout"> /// The maximum time to wait for an ACK. <see cref="System.Int32"/> /// </param> /// <param name="ackHandler"> /// The <see cref="AckHandler"/> to handle the ACK. /// </param> public virtual void Send(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage msg, int ackTimeout, AckHandler ackHandler) { if (remote == null) throw new ArgumentNullException("remote"); P2PMessage[] msgs = SetSequenceNumberAndRegisterAck(session, remote, msg, ackHandler, ackTimeout); if (session == null) { if (!IsOpen) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Send called with no session on a closed bridge", GetType().Name); return; } // Bypass queueing foreach (P2PMessage m in msgs) { SendOnePacket(null, remote, remoteGuid, m); } return; } if (!SuitableFor(session)) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Send called with a session this bridge is not suitable for", GetType().Name); return; } lock (sendQueues) { if (!sendQueues.ContainsKey(session)) sendQueues[session] = new P2PSendQueue(); } lock (sendQueues[session]) { foreach (P2PMessage m in msgs) sendQueues[session].Enqueue(remote, remoteGuid, m); } ProcessSendQueues(); }
/// <summary> /// /// </summary> /// <param name="session"></param> /// <param name="queue"></param> public virtual void AddQueue(P2PSession session, P2PSendQueue queue) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, String.Format("P2PBridge {0} received queue for session {1}", this.ToString(), session.SessionId), GetType().Name); if (sendQueues.ContainsKey(session)) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "A queue is already present for this session, merging the queues", GetType().Name); lock (sendQueues[session]) { while (queue.Count > 0) sendQueues[session].Enqueue(queue.Dequeue()); } } else { lock (sendQueues) sendQueues[session] = queue; } ProcessSendQueues(); }