private void RouteTo(Message message, Elastic3D to) { // peer lists ElasticAddress[] peers = Peers.ToArray <ElasticAddress>(to, message.Layout()).Shuffle(); // send me if peers contains me if (peers.Contains(LocalEndPoint)) { new BConsole.MessageBuilder() .Append("(+) Routing message(") .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis()) .Append(") To:") .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to) .Append(", Me:") .Append(ConsoleColor.DarkCyan, LocalEndPoint.Ellipsis()) //.WriteLine( $", message={message}"); .WriteLine(); SendTo(message, LocalEndPoint); return; } // send message to randomly picked one // try next if failed foreach (var peer in peers) { new BConsole.MessageBuilder() .Append("(+) Routing message(") .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis()) .Append(") To:") .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to) .Append(", Peer:") .Append(ConsoleColor.DarkCyan, peer.Ellipsis()) //.WriteLine($", message={message}"); .WriteLine(); if (SendTo(message, peer)) { break; } } }
private void OnElasticMessage(Message message) { // routes info byte ttl = message.TimeToLive(); Elastic3D to = message.To(); ElasticLayout layout = message.Layout(); Elastic3D me = layout.DefineCoordinates(NodeKey.Address); // message router Address router = message.Router(); // router permitted? if (!Peers.Exists(router)) { Logger.warning("Unauthorized router!"); return; } // verify message if (ShouldVerifyRouter && !message.VerifyRouter(router)) { Logger.warning("Router signature not verified!"); return; } new BConsole.MessageBuilder() .Append("(-) Received ShouldRoute message(") .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis()) .Append(") To:") .Append(to.Mul() == 0 ? ConsoleColor.DarkYellow : ConsoleColor.DarkGreen, to) //.WriteLine($", message={message}"); .WriteLine(); // broadcast to all cell if (to.Mul() > 0 && ttl == 1) { ElasticAddress[] peers = Peers.ToArray <ElasticAddress>(to, layout); new BConsole.MessageBuilder() .Append("(!) Broadcasting message(") .Append(ConsoleColor.DarkCyan, message.ID.Ellipsis()) .Append("), To=") .Append(ConsoleColor.DarkGreen, to) .Append(", nPeers=") .Append(ConsoleColor.DarkGreen, peers.Length) //.WriteLine($", message={message}"); .WriteLine(); // 해당 좌표의 모든 노드에 전송한다. message.RouteTo(0, to, layout, NodeKey); SendTo(message, peers); return; } // z-axis must be > 0 if (to.Z < 1) { Logger.error($"to.z < 1"); return; } // y-axis if (ttl == 3) { for (byte y = 1; y <= layout.Y; y++) { to.Y = y; message.RouteTo(2, to, layout, NodeKey); RouteTo(message, to); } } // x-axis else if (ttl == 2 && to.Y > 0) { for (byte x = 1; x <= layout.X; x++) { to.X = x; message.RouteTo(1, to, layout, NodeKey); RouteTo(message, to); } } }