예제 #1
0
 public Task<Message.Message> SendAsync(PeerAddress remotePeer, BroadcastBuilder broadcastBuilder,
     ChannelCreator channelCreator, IConnectionConfiguration configuration)
 {
     var message = CreateRequestMessage(remotePeer, Rpc.Commands.Broadcast.GetNr(),
         Message.Message.MessageType.RequestFf1);
     message.SetIntValue(broadcastBuilder.HopCounter);
     message.SetKey(broadcastBuilder.MessageKey);
     if (broadcastBuilder.DataMap != null)
     {
         message.SetDataMap(new DataMap(broadcastBuilder.DataMap));
     }
     var tcsResponse = new TaskCompletionSource<Message.Message>(message);
     var requestHandler = new RequestHandler(tcsResponse, PeerBean, ConnectionBean, configuration);
     if (!broadcastBuilder.IsUdp)
     {
         return requestHandler.SendTcpAsync(channelCreator);
     }
     else
     {
         return requestHandler.FireAndForgetUdpAsync(channelCreator);
     }
 }
        /// <summary>
        /// This method is called on relaying peers. We select a random set and we send the message
        /// to those random peers.
        /// </summary>
        /// <param name="messageKey">The key of the message.</param>
        /// <param name="dataMap">The data map to send around.</param>
        /// <param name="hopCounter">The number of hops.</param>
        /// <param name="isUdp">Flag indicating whether the message can be sent with UDP.</param>
        private void OtherPeer(Number160 messageKey, IDictionary<Number640, Data> dataMap, int hopCounter, bool isUdp)
        {
            Logger.Debug("Other");
            var list = _peer.PeerBean.PeerMap.All;
            int max = Math.Min(Nr, list.Count);

            var taskCc = _peer.ConnectionBean.Reservation.CreateAsync(isUdp ? max : 0, isUdp ? 0 : max);
            taskCc.ContinueWith(tcc =>
            {
                if (!tcc.IsFaulted)
                {
                    var taskResponses = new Task[max];
                    for (int i = 0; i < max; i++)
                    {
                        var randomAddress = list.RemoveAt2(_rnd.Next(list.Count));

                        var broadcastBuilder = new BroadcastBuilder(_peer, messageKey);
                        broadcastBuilder.SetDataMap(dataMap);
                        broadcastBuilder.SetHopCounter(hopCounter + 1);
                        broadcastBuilder.SetIsUdp(isUdp);

                        taskResponses[i] = _peer.BroadcastRpc.SendAsync(randomAddress, broadcastBuilder, tcc.Result,
                            broadcastBuilder);
                        Logger.Debug("2nd broadcast to {0}.", randomAddress);
                    }
                    Utils.Utils.AddReleaseListener(tcc.Result, taskResponses);
                }
                else
                {
                    Utils.Utils.AddReleaseListener(tcc.Result);
                }
            });
        }
        /// <summary>
        /// The first peer is the initiator. The peer that wants to start the broadcast 
        /// will send it to all its neighbors. Since this peer has an interest in sending, 
        /// it should also work more than the other peers.
        /// </summary>
        /// <param name="messageKey">The key of the message.</param>
        /// <param name="dataMap">The data map to send around.</param>
        /// <param name="hopCounter">The number of hops.</param>
        /// <param name="isUdp">Flag indicating whether the message can be sent with UDP.</param>
        private void FirstPeer(Number160 messageKey, IDictionary<Number640, Data> dataMap, int hopCounter, bool isUdp)
        {
            var list = _peer.PeerBean.PeerMap.All;
            foreach (var peerAddress in list)
            {
                var taskCc = _peer.ConnectionBean.Reservation.CreateAsync(isUdp ? 1 : 0, isUdp ? 0 : 1);
                PeerAddress address = peerAddress;
                taskCc.ContinueWith(tcc =>
                {
                    if (!tcc.IsFaulted)
                    {
                        var broadcastBuilder = new BroadcastBuilder(_peer, messageKey);
                        broadcastBuilder.SetDataMap(dataMap);
                        broadcastBuilder.SetHopCounter(hopCounter + 1);
                        broadcastBuilder.SetIsUdp(isUdp);

                        var taskResponse = _peer.BroadcastRpc.SendAsync(address, broadcastBuilder, tcc.Result,
                            broadcastBuilder);
                        Logger.Debug("1st broadcast to {0}.", address);
                        Utils.Utils.AddReleaseListener(tcc.Result, taskResponse);
                    }
                    else
                    {
                        Utils.Utils.AddReleaseListener(tcc.Result);
                    }
                });
            }
        }