Netty + MongoDB рдкрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдпреВрдбреАрдкреА рдмрд┐рдЯрдЯреЛрд░реЗрдВрдЯ рдЯреНрд░реИрдХрд░ рд▓рд┐рдЦрдирд╛

рдкрд░рд┐рдЪрдп


рдпрд╣ рд▓реЗрдЦ рдпреВрдбреАрдкреА рдЯреНрд░реИрдХрд░ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдХрд╛рдо рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рддрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг рдЬрд╛рд╡рд╛ рдореЗрдВ рдиреЗрдЯреА рдПрдирдЖрдИрдУ рдврд╛рдВрдЪреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред MongoDB рдХреЛ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЖрдорддреМрд░ рдкрд░, рдзрд╛рд░ рдЯреНрд░реИрдХрд░реНрд╕ HTTP рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЬреАрдИрдЯреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдбреЗрдЯрд╛ рд╕рдВрдЪрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпреВрдбреАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЯреНрд░реИрдХрд░ рдХрд╛ рдХрд╛рдо рдЯреНрд░реИрдлрд┐рдХ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ (2 рдЧреБрдирд╛ рд╕реЗ рдЕрдзрд┐рдХ), рд╕рд╛рде рд╣реА рдЯреАрд╕реАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЛ рд▓рдЧрд╛рдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рд╕реАрдорд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддрд╛ рд╣реИред

рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ UDP рдЯреНрд░реИрдХрд░ рдХрд╛ рд▓рд┐рдВрдХ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддрд╛ рд╣реИ: udp: //tracker.openbittorrent.com: 80 / рдШреЛрд╖рдгрд╛ , рдЬрд╣рд╛рдВ рдХреБрдЫ рднреА рдШреЛрд╖рдгрд╛ рдХреЗ рд╕реНрдерд╛рди рдкрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдпрд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ)ред рд▓реЗрдХрд┐рди HTTP рдЯреНрд░реИрдХрд░ рдХреЗ рд╡рд┐рдкрд░реАрдд рдкреЛрд░реНрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ ред


рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕рд┐рджреНрдзрд╛рдВрдд


рдЕрдм рд╕рд╛рдорд╛рдиреНрдп рд╢рдмреНрджреЛрдВ рдореЗрдВ рдпреВрдбреАрдкреА рдЯреНрд░реИрдХрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
1. рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЧреНрд░рд╛рд╣рдХ рдЯреНрд░реИрдХрд░ (рдкреИрдХреЗрдЯ 0x00 рдХрдиреЗрдХреНрдЯ) рдХреЗ рд▓рд┐рдП рдПрдХ рдХрдиреЗрдХреНрд╢рди рдЕрдиреБрд░реЛрдз рднреЗрдЬрддрд╛ рд╣реИред рдЗрд╕ рдЕрдиреБрд░реЛрдз рдореЗрдВ, рдХрдиреЗрдХреНрд╢рди рдЖрдИрдбреА рдлрд╝реАрд▓реНрдб 0x41727101980 рд╣реИ - рдпрд╣ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЧреНрд░рд╛рд╣рдХ рд▓реЗрди-рджреЗрди рдЖрдИрдбреА рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╡рд╣ рдЕрдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЪреБрдирддрд╛ рд╣реИред
2. рдЕрдЧрд▓рд╛, рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдХрдиреЗрдХреНрд╢рди рдЖрдИрдбреА рдмрдирд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╡рд╣ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреИрдХреЗрдЯ рдореЗрдВ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╕рд░реНрд╡рд░ рдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдЯреНрд░рд╛рдВрдЬреЗрдХреНрд╢рди рдЖрдИрдбреА рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
3. рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдкрд╛рд╕ рдЕрдм рдПрдХ рдпреВрдирд┐рдХ рдЖрдИрдбреА рд╣реИ (рдЬреЛ рдХрд┐, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпреВрдЬрд░ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдФрд░ рдЯреНрд░реИрдлрд┐рдХ рдЕрдХрд╛рдЙрдВрдЯрд┐рдВрдЧ рдХреЗ рдмрд┐рдирд╛ рдУрдкрди рдЯреНрд░реИрдХрд░ рд╣реЛрдиреЗ рдкрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИред) рдФрд░ рд╣рдореЗрдВ рдШреЛрд╖рдгрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдкреИрдХреЗрдЬ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВред
4. рдШреЛрд╖рдгрд╛ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ, рд╕рд░реНрд╡рд░ рдкреАрдпрд░ рдЯреЙрд░реЗрдВрдЯ рдХреА рдПрдХ рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ, рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╕рд░реНрд╡рд░ рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдФрд░ рдмреАрдЬ / рдкреАрдпрд░ рдХреЗ рдЖрдБрдХрдбрд╝реЛрдВ рдХрд╛ рдЕрдВрддрд░рд╛рд▓ред
5. рдПрдХ рдЕрдиреНрдп рдЧреНрд░рд╛рд╣рдХ рд╣рдореЗрдВ рд╕реНрдХреНрд░реЗрдк рдЕрдиреБрд░реЛрдз рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдЯреЙрд░реЗрдВрдЯ рдХреЗ рдХрдИ рд╣реИрд╢ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╡рд╣ рдЖрдВрдХрдбрд╝реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИред рдпреВрдбреАрдкреА рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЗ рдХрд╛рд░рдг рдкреНрд░рддрд┐ 1 рдЕрдиреБрд░реЛрдз рдкрд░ рдЕрдиреБрд░реЛрдзрд┐рдд рдЯреЙрд░реЗрдВрдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ 74 рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред

рд╕рд░реНрд╡рд░ рдХрд╛ рд╡рд┐рдХрд╛рд╕


рдЗрд╕ рд╕реНрддрд░ рдкрд░, рдореИрдВ рдЖрдкрдХреЛ рдЯреНрд░реИрдХрд░ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ, рдЬреИрд╕реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдХреЗрд╡рд▓ рдкреНрд░рдореБрдЦ рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ред рдЖрдк рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕реНрд░реЛрддреЛрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: github.com/lafayette/udp-torrent-tracker

рдиреЗрдЯрд▓реА рдХреА рд╢реБрд░реБрдЖрддред

Executor threadPool = Executors.newCachedThreadPool(); DatagramChannelFactory factory = new NioDatagramChannelFactory(threadPool); //    UDP. bootstrap = new ConnectionlessBootstrap(factory); bootstrap.getPipeline().addLast("handler", new Handler()); // Handler      . bootstrap.setOption("reuseAddress", true); //        .  ,   reuseAddress   .  ,  -    . //  ShutdowHook    ,       Netty. ,     . Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { public void run() { channel.close(); bootstrap.releaseExternalResources(); } })); String host = Config.getInstance().getString("listen.host", "127.0.0.1"); Integer port = Config.getInstance().getInt("listen.port", 8080); InetSocketAddress address = new InetSocketAddress(host, port); //  ,  ,      .       Netty     . logger.info("Listening on " + host + ":" + port); //       bind,       . bootstrap.bind(address); 


рдЧреНрд░рд╛рд╣рдХреЛрдВ рд╕реЗ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред

 public class Handler extends SimpleChannelUpstreamHandler { private static final Logger logger = Logger.getLogger(Handler.class); public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { ChannelBuffer channelBuffer = (ChannelBuffer)e.getMessage(); //  ChannelBuffer      udp-. //  ,   ,    connection ID (long), action ID (int)  transaction ID (int)      16 . if (channelBuffer.readableBytes() < 16) { logger.debug("Incorrect packet received from " + e.getRemoteAddress()); } long connectionId = channelBuffer.readLong(); //    connectionId,             . int actionId = channelBuffer.readInt(); // ID .  : 0x00 Connect; 0x01 Announce; 0x02 Scrape; 0x03: Error.  ()   . int transactionId = channelBuffer.readInt(); // ID .       ID ,    . Action action = Action.byId(actionId); ClientRequest request; switch (action) { case CONNECT: request = new ConnectionRequest(); break; case ANNOUNCE: request = new AnnounceRequest(); break; case SCRAPE: request = new ScrapeRequest(); break; default: logger.debug("Incorrect action supplied"); ErrorResponse.send(e, transactionId, "Incorrect action"); return; } //         ,     ,   . request.setContext(ctx); request.setMessageEvent(e); request.setChannelBuffer(channelBuffer); request.setConnectionId(connectionId); request.setAction(action); request.setTransactionId(transactionId); //         . request.read(); } } 


MongoDB

MongoDB рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдПрдХ рдЕрджреНрднреБрдд рдорд╛рдирдЪрд┐рддреНрд░рдг рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ - рдореЙрд░реНрдлрд┐рдпрд╛ ред

рдпрд╣рд╛рдБ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рджрд╛рд╡рдд рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХреИрд╕реЗ рдХрд┐рдпрд╛:
 @Entity("peers") public class Peer { public @Id ObjectId id; public @Indexed byte[] infoHash; public byte[] peerId; public long downloaded; public long left; public long uploaded; public @Transient int event; public int ip; public short port; public @Transient int key; public @Transient int numWant; public @Transient short extensions; public long lastUpdate; @PrePersist private void prePersist() { this.lastUpdate = System.currentTimeMillis(); } } 

рдХреНрд╖рдгрд┐рдХ рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдПрдХ рдЯреЗрдмрд▓ рдкрд░ рдирд╣реАрдВ рдмрдЪрд╛рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред InfoHash рдлрд╝реАрд▓реНрдб рдХреЛ рдЕрдиреБрдХреНрд░рдордгрд┐рдд рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдзрд╛рд░ рдХреЗ рд╣реИрд╢ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреБрдХреНрдд рд╕рд╛рдерд┐рдпреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВрдЧреЗред

рд╣рдореЗрдВ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдиреЗ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
 morphia = new Morphia(); morphia.map(Peer.class); //  ,     . mongo = new Mongo(host, port); datastore = morphia.createDatastore(mongo, "udptracker"); 


рдФрд░ info_hash рджреНрд╡рд╛рд░рд╛ рд╕рд╣рдХрд░реНрдореА рдЦреЛрдЬ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг
 Query<Peer> peersQuery = Datastore.instance().find(Peer.class); peersQuery.field("infoHash").equal(peer.infoHash); peersQuery.field("peerId").notEqual(peer.peerId); //    . peersQuery.limit(peer.numWant).offset(randomOffset); //   numWant    . 


рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдореЙрд░реНрдлрд┐рдпрд╛ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рджреЗрдЦрдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИред

рдЕрдиреНрдпрдерд╛, рд╕рдм рдХреБрдЫ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ: рдкреНрд░рд╛рдкреНрдд annelBuffer рд╕реЗ рд╣рдо рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо e.getChannel () рдХреЛ рдЙрддреНрддрд░ рднреЗрдЬрддреЗ рд╣реИрдВред рдЖрдк рд╕реНрд░реЛрдд рдореЗрдВ рд╕рднреА рдкреИрдХреЗрдЬреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреА рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЖрдкрдХреЛ xbtt.sourceforge.net/udp_tracker_protocol.html рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ

рдЙрдкрд░реЛрдХреНрдд рд╕рд░реНрд╡рд░ рдХреЗ рд╕реНрд░реЛрдд: github.com/lafayette/udp-torrent-tracker

рдкреАрдПрд╕ рдореИрдВ рддреБрд░рдВрдд рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдореЗрд░рд╛ рдкрд╣рд▓рд╛ рдЕрдиреБрднрд╡ рд╣реИ, рдЬреЛ рдХрд┐ рдиреЗрдЯреНрдЯреА рдФрд░ рдореЛрдВрдЧреЛрдмреАрдбреА рджреЛрдиреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВрдиреЗ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдЗрди рджреЛрдиреЛрдВ рдЕрджреНрднреБрдд рдЪреАрдЬреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд┐рдпрд╛ред рдЗрд╕рд▓рд┐рдП, рдЬреЗрдбреА рд╢реИрд▓реА рдореЗрдВ рдЗрд╕реЗ рдмреЗрд╣рддрд░ / рдкреНрд░реАрдЯреАрдпрд░ / рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд▓рд╛рд╣ рдмрд╣реБрдд рд╕реНрд╡рд╛рдЧрдд рд╣реИред

Source: https://habr.com/ru/post/In130563/


All Articles