示例#1
0
 public DistributedRouting(PeerBean peerBean, NeighborRpc neighbors)
 {
     _neighbors = neighbors;
     _peerBean  = peerBean;
     // stable random number: no need to be truly random
     _rnd = new Random(peerBean.ServerPeerAddress.PeerId.GetHashCode());
 }
示例#2
0
 /// <summary>
 /// Setup the RPC and register for incoming messages.
 /// </summary>
 /// <param name="peerBean">The peer bean.</param>
 /// <param name="connectionBean">The connection bean.</param>
 /// <param name="register">Whether incoming messages should be registered.</param>
 public NeighborRpc(PeerBean peerBean, ConnectionBean connectionBean, bool register)
     : base(peerBean, connectionBean)
 {
     if (register)
     {
         Register(Rpc.Commands.Neighbor.GetNr());
     }
 }
示例#3
0
 /// <summary>
 /// Constructor that is only called from this class or from test cases.
 /// </summary>
 /// <param name="peerBean">The peer bean.</param>
 /// <param name="connectionBean">The connection bean.</param>
 /// <param name="enable">Used for test cases, set to true in production.</param>
 /// <param name="register">Used for test cases, set to true in production.</param>
 /// <param name="wait">Used for test cases, set to false in production.</param>
 public PingRpc(PeerBean peerBean, ConnectionBean connectionBean, bool enable, bool register, bool wait)
     : base(peerBean, connectionBean)
 {
     _enable = enable;
     _wait   = wait;
     if (register)
     {
         ConnectionBean.Dispatcher.RegisterIOHandler(peerBean.ServerPeerAddress.PeerId, peerBean.ServerPeerAddress.PeerId, this, Rpc.Commands.Ping.GetNr());
     }
 }
示例#4
0
 /// <summary>
 /// Registers the storage RPC for PUT, COMPARE PUT, GET, ADD and REMOVE.
 /// </summary>
 /// <param name="peerBean"></param>
 /// <param name="connectionBean"></param>
 /// <param name="storageLayer"></param>
 public StorageRpc(PeerBean peerBean, ConnectionBean connectionBean, StorageLayer storageLayer)
     : base(peerBean, connectionBean)
 {
     Register(
         Rpc.Commands.Put.GetNr(),
         Rpc.Commands.Get.GetNr(),
         Rpc.Commands.Add.GetNr(),
         Rpc.Commands.Remove.GetNr(),
         Rpc.Commands.Digest.GetNr(),
         Rpc.Commands.DigestBloomfilter.GetNr(),
         Rpc.Commands.DigestAllBloomfilter.GetNr(),
         Rpc.Commands.PutMeta.GetNr(),
         Rpc.Commands.DigestMetaValues.GetNr(),
         Rpc.Commands.PutConfirm.GetNr(),
         Rpc.Commands.GetLatest.GetNr(),
         Rpc.Commands.GetLatestWithDigest.GetNr(),
         Rpc.Commands.ReplicaPut.GetNr());
     _bloomfilterFactory = peerBean.BloomfilterFactory;
     _storageLayer       = storageLayer;
 }
示例#5
0
 /// <summary>
 /// Creates a handler with a peer bean and a connection bean.
 /// </summary>
 /// <param name="peerBean">The peer bean.</param>
 /// <param name="connectionBean">The connection bean.</param>
 protected DispatchHandler(PeerBean peerBean, ConnectionBean connectionBean)
 {
     PeerBean       = peerBean;
     ConnectionBean = connectionBean;
 }
示例#6
0
 public NeighborRpc(PeerBean peerBean, ConnectionBean connectionBean)
     : this(peerBean, connectionBean, true)
 {
 }
示例#7
0
 public BroadcastRpc(PeerBean peerBean, ConnectionBean connectionBean, IBroadcastHandler broadcastHandler)
     : base(peerBean, connectionBean)
 {
     Register(Rpc.Commands.Broadcast.GetNr());
     BroadcastHandler = broadcastHandler;
 }
示例#8
0
 /// <summary>
 /// Creates a new handshake RPC with listeners.
 /// </summary>
 /// <param name="peerBean">The peer bean.</param>
 /// <param name="connectionBean">The connection bean.</param>
 public PingRpc(PeerBean peerBean, ConnectionBean connectionBean)
     : this(peerBean, connectionBean, true, true, false)
 {
 }
示例#9
0
        public override void HandleResponse(Message.Message requestMessage, PeerConnection peerConnection, bool sign, IResponder responder)
        {
            // server-side:
            // comes from DispatchHandler
            // IResponder now responds the result...

            if (!((requestMessage.Type == Message.Message.MessageType.RequestFf1 ||
                   requestMessage.Type == Message.Message.MessageType.Request1 ||
                   requestMessage.Type == Message.Message.MessageType.Request2 ||
                   requestMessage.Type == Message.Message.MessageType.Request3 ||
                   requestMessage.Type == Message.Message.MessageType.Request3) &&
                  requestMessage.Command == Rpc.Commands.Ping.GetNr()))
            {
                throw new ArgumentException("Request message type or command is wrong for this handler.");
            }
            Message.Message responseMessage;

            // probe
            if (requestMessage.Type == Message.Message.MessageType.Request3)
            {
                Logger.Debug("Respond to probing. Firing message to {0}.", requestMessage.Sender);
                responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);

                if (requestMessage.IsUdp)
                {
                    ConnectionBean.Reservation.CreateAsync(1, 0).ContinueWith(t =>
                    {
                        if (!t.IsFaulted)
                        {
                            Logger.Debug("Fire UDP to {0}.", requestMessage.Sender);
                            var taskResponse = FireUdpAsync(requestMessage.Sender, t.Result,
                                                            ConnectionBean.ChannelServer.ChannelServerConfiguration);
                            Utils.Utils.AddReleaseListener(t.Result, taskResponse);
                        }
                        else
                        {
                            Utils.Utils.AddReleaseListener(t.Result);
                            Logger.Warn("Handling response for Request3 failed. (UDP) {0}", t.Exception);
                        }
                    });
                }
                else
                {
                    ConnectionBean.Reservation.CreateAsync(0, 1).ContinueWith(t =>
                    {
                        if (!t.IsFaulted)
                        {
                            Logger.Debug("Fire TCP to {0}.", requestMessage.Sender);
                            var taskResponse = FireTcpAsync(requestMessage.Sender, t.Result,
                                                            ConnectionBean.ChannelServer.ChannelServerConfiguration);
                            Utils.Utils.AddReleaseListener(t.Result, taskResponse);
                        }
                        else
                        {
                            Utils.Utils.AddReleaseListener(t.Result);
                            Logger.Warn("Handling response for Request3 failed. (TCP) {0}", t.Exception);
                        }
                    });
                }
            }
            // discover
            else if (requestMessage.Type == Message.Message.MessageType.Request2)
            {
                Logger.Debug("Respond to discovering. Found {0}.", requestMessage.Sender);
                responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);
                responseMessage.SetNeighborSet(CreateNeighborSet(requestMessage.Sender));
            }
            // regular ping
            else if (requestMessage.Type == Message.Message.MessageType.Request1 ||
                     requestMessage.Type == Message.Message.MessageType.Request4)
            {
                Logger.Debug("Respond to regular ping from {0}.", requestMessage.Sender);
                // Test, if this is a broadcast message to ourselves.
                // If it is, do not reply.
                if (requestMessage.IsUdp &&
                    requestMessage.Sender.PeerId.Equals(PeerBean.ServerPeerAddress.PeerId) &&
                    requestMessage.Recipient.PeerId.Equals(Number160.Zero))
                {
                    Logger.Warn("Don't respond. We are on the same peer, you should make this call.");
                    responder.ResponseFireAndForget();
                }
                if (_enable)
                {
                    responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);
                    if (_wait)
                    {
                        Thread.Sleep(WaitTime);
                    }
                }
                else
                {
                    Logger.Debug("Don't respond.");
                    // used for debugging
                    if (_wait)
                    {
                        Thread.Sleep(WaitTime);
                    }
                    return;
                }
                if (requestMessage.Type == Message.Message.MessageType.Request4)
                {
                    lock (_receivedBroadcastPingListeners)
                    {
                        foreach (IPeerReceivedBroadcastPing listener in _receivedBroadcastPingListeners)
                        {
                            listener.BroadcastPingReceived(requestMessage.Sender);
                        }
                    }
                }
            }
            else
            {
                // fire-and-forget if requestMessage.Type == MessageType.RequestFf1
                // we received a fire-and forget ping
                // this means we are reachable from the outside
                PeerAddress serverAddress = PeerBean.ServerPeerAddress;
                if (requestMessage.IsUdp)
                {
                    // UDP
                    PeerAddress newServerAddress = serverAddress.ChangeIsFirewalledUdp(false);
                    PeerBean.SetServerPeerAddress(newServerAddress);
                    lock (_reachableListeners)
                    {
                        foreach (IPeerReachable listener in _reachableListeners)
                        {
                            listener.PeerWellConnected(newServerAddress, requestMessage.Sender, false);
                        }
                    }
                    responseMessage = requestMessage;
                }
                else
                {
                    // TCP
                    PeerAddress newServerAddress = serverAddress.ChangeIsFirewalledTcp(false);
                    PeerBean.SetServerPeerAddress(newServerAddress);
                    lock (_reachableListeners)
                    {
                        foreach (IPeerReachable listener in _reachableListeners)
                        {
                            listener.PeerWellConnected(newServerAddress, requestMessage.Sender, true);
                        }
                    }
                    responseMessage = CreateResponseMessage(requestMessage, Message.Message.MessageType.Ok);
                }
            }
            responder.Response(responseMessage);
        }
示例#10
0
 public DirectDataRpc(PeerBean peerBean, ConnectionBean connectionBean)
     : base(peerBean, connectionBean)
 {
     Register(Rpc.Commands.DirectData.GetNr());
 }
示例#11
0
 /// <summary>
 /// Constructor that registers this RPC with the message handler.
 /// </summary>
 /// <param name="peerBean">The peer bean.</param>
 /// <param name="connectionBean">The connection bean.</param>
 public QuitRpc(PeerBean peerBean, ConnectionBean connectionBean)
     : base(peerBean, connectionBean)
 {
     Register(Rpc.Commands.Quit.GetNr());
 }