рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛
рдирдорд╕реНрддреЗ рдореИрдВ CIS рдореЗрдВ рд╕рдмрд╕реЗ рдмрдбрд╝реЗ Minecraft рд╕рд░реНрд╡рд░ рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рдХрд╛рд╕рдХ рд╣реВрдВ (рдореИрдВ рд╡рд┐рдЬреНрдЮрд╛рдкрди рдирд╣реАрдВ рджреВрдВрдЧрд╛ рдХрд┐ рдЗрд╕рдХреА рдЬрд░реВрд░рдд рдХрд┐рд╕реЗ рд╣реИ, рд╡реЗ рдЬрд╛рдирддреЗ рд╣реИрдВ)ред рд▓рдЧрднрдЧ рдПрдХ рд╡рд░реНрд╖ рд╕реЗ рдЕрдм рд╣рдо рдЕрдкрдиреЗ рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ 40 рд╕реЗ рдЕрдзрд┐рдХ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рд╣рдо рдХрдо рд╕реЗ рдХрдо 500 рдХрд╛ рдЖрдВрдХрдбрд╝рд╛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ)ред рдЕрдм рддрдХ, рд╕рдм рдХреБрдЫ рд╕рдлрд▓ рдерд╛, рд▓реЗрдХрд┐рди рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдиреЗ рдЗрд╕ рддрдереНрдп рдкрд░ рдЖрд░рд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдХрд┐ рд╕рдмрд╕реЗ рд╕рдлрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП 1 рд╕реНрдЯреНрд░реАрдо, рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП 1 + рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП 1) рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг, 300 рдЦрд┐рд▓рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдСрдирд▓рд╛рдЗрди, 980 рд╕реЗ рдЕрдзрд┐рдХ рдкреНрд░рд╡рд╛рд╣ рдХрд╛рдо (рд╕рд┐рд╕реНрдЯрдо) , рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ io рдЬрд╛рд╡рд╛ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рд╣реИ, рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рднрд╛рд░реА рдЧрд┐рд░рд╛рд╡рдЯ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ 100 рдЦрд┐рд▓рд╛рдбрд╝рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде, рд╕рд░реНрд╡рд░ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рд▓рд┐рдЦрдиреЗ / рдкрдврд╝рдиреЗ / рдХрд░рдиреЗ рдореЗрдВ рд▓рдЧрд╛ рд╣реБрдЖ рд╣реИред
рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ NIO рдореЗрдВ рдЬрд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред
рдиреЗрдЯреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЧрд▓рддреА рд╕реЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рдЧрд┐рд░ рдЧрдИ, рдЬрд┐рд╕рдХреА рд╕рдВрд░рдЪрдирд╛ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд▓рдЧ рд░рд╣реА рдереАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рди рдХреЗрд╡рд▓ рд░реВрд╕реА рдореЗрдВ, рдмрд▓реНрдХрд┐ рдЕрдВрдЧреНрд░реЗрдЬреА рдореЗрдВ рднреА рдХреБрдЫ рдиреЗрдЯреА рдореИрдиреБрдЕрд▓ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛрдб рдореЗрдВ рдмрд╣реБрдд рдкреНрд░рдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ рдЪрдврд╝рд╛рдИ рдХрд░рдирд╛ рдкрдбрд╝рд╛ред
рдпрд╣рд╛рдВ рдореИрдВ рдиреЗрдЯреНрдЯреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд╕рд░реНрд╡рд░ рднрд╛рдЧ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рд╢рд╛рдпрдж рдпрд╣ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред
рд╕рд░реНрд╡рд░ рдирд┐рд░реНрдорд╛рдг
ExecutorService bossExec = new OrderedMemoryAwareThreadPoolExecutor(1, 400000000, 2000000000, 60, TimeUnit.SECONDS); ExecutorService ioExec = new OrderedMemoryAwareThreadPoolExecutor(4 , 400000000, 2000000000, 60, TimeUnit.SECONDS); ServerBootstrap networkServer = new ServerBootstrap(new NioServerSocketChannelFactory(bossExec, ioExec, 4 )); networkServer.setOption("backlog", 500); networkServer.setOption("connectTimeoutMillis", 10000); networkServer.setPipelineFactory(new ServerPipelineFactory()); Channel channel = networkServer.bind(new InetSocketAddress(address, port));
рдлреНрд░реЗрдВрдЪ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрднрд╡ рдХреЗ рдЕрдиреБрд╕рд╛рд░, Netty рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
OrderedMemoryAwareThreadPoolExecutor рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡реЗ рд╕рдмрд╕реЗ рдкреНрд░рднрд╛рд╡реА рд╣реИрдВред рдЖрдк рдЕрдиреНрдп Executors рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ
Executors.newFixedThreadPool (n) ред рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ
Executors.newCachedThreadPool () рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ, рдпрд╣ рдЕрдиреБрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрдИ рдереНрд░реЗрдб рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдиреЗрдЯреНрдЯреА рд╕реЗ рд▓рдЧрднрдЧ рдХреЛрдИ рд▓рд╛рдн рдирд╣реАрдВ рд╣реИред рдпрд╣ 4 рд╕реЗ рдЕрдзрд┐рдХ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдЕрдзрд┐рдХ рднрд╛рд░ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдиреЗ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИрдВ (4 рдереНрд░реЗрдбреНрд╕ рдкрд░ рдЬрд╝реЗрдмрд┐рдпрд╛-рдлреНрд░рд╛рдВрд╕ рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ 100,000 рд╕реЗ рдЕрдзрд┐рдХ рдПрдХ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдЦреАрдВрдЪрддреЗ рд╣реИрдВ)ред рдкреНрд░рддреНрдпреЗрдХ рд╕реБрдирдиреЗ рд╡рд╛рд▓реЗ рдмрдВрджрд░рдЧрд╛рд╣ рдХреЗ рд▓рд┐рдП рдмреЙрд╕ рдзрд╛рд░рд╛рдПрдБ рдПрдХ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
рдЪреИрдирд▓ рдЬреЛ рдмрд╛рдЗрдВрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА
ServerBootsrap рдХреЛ рднреА рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдЖрдк рд╕рд░реНрд╡рд░ рдХреЛ рдмрд╛рдж рдореЗрдВ рд░реЛрдХ рд╕рдХреЗрдВред
PipelineFactory
рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдХрдиреЗрдХреНрд╢рди рдФрд░ рдкреИрдХреЗрдЬ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╡рд╣
рдкрд╛рдЗрдкрд▓рд╛рдЗрдирд▓рд╛рдЗрди рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд╕рд╛рде рдПрдХ рдЪреИрдирд▓ рдЦреЛрд▓рдиреЗ рдкрд░, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдмрдирд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЪреИрдирд▓ рдкрд░ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣
ServerPipelineFactory рд╣реИ :
public class ServerPipelineFactory implements ChannelPipelineFactory { @Override public ChannelPipeline getPipeline() throws Exception { PacketFrameDecoder decoder = new PacketFrameDecoder(); PacketFrameEncoder encoder = new PacketFrameEncoder(); return Channels.pipeline(decoder, encoder, new PlayerHandler(decoder, encoder)); } }
рдЗрд╕ рдХреЛрдб рдореЗрдВ,
PacketFrameDecoder ,
PacketFrameEncoder, рдФрд░
PlayerHandler рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
Channels.pipeline () рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдирдИ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдмрдирд╛рддрд╛ рд╣реИ рдЬреЛ рдЗрд╕реЗ рдкрд╛рд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рд╛рд╡рдзрд╛рди рд░рд╣реЗрдВ: рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЙрд╕ рдХреНрд░рдо рдореЗрдВ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЧреБрдЬрд░реЗ рдереЗ!
рдкреНрд░реЛрдЯреЛрдХреЙрд▓
рдореИрдВ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдереЛрдбрд╝рд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛред
рдкреИрдХреЗрдЯ рдХреНрд▓рд╛рд╕ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рджреЛ рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрддреЗ рд╣реИрдВ,
рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ (ChannelBuffer рдЗрдирдкреБрдЯ) рдФрд░
рднреЗрдЬреЗрдВ (ChannelBuffer рдЖрдЙрдЯрдкреБрдЯ) ред рддрджрдиреБрд╕рд╛рд░, рдкрд╣рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдЪреИрдирд▓ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдкрдврд╝рддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ рдЪреИрдирд▓ рдХреЛ рдкреИрдХреЗрдЯ рдбреЗрдЯрд╛ рд▓рд┐рдЦрддрд╛ рд╣реИред
public abstract class Packet { public static Packet read(ChannelBuffer buffer) throws IOException { int id = buffer.readUnsignedShort();
рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреБрд▓ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
ChannelBuffer DataInputStream рдФрд░ DataOutputStream рдХреЗ рд╕рдорд╛рди рд╣реИ рдФрд░ рд╕рднреА рдПрдХ рдореЗрдВ рд▓реБрдврд╝рдХреЗ рд╣реИрдВред рдЕрдзрд┐рдХрд╛рдВрд╢ рдлрд╝рдВрдХреНрд╢рди, рдпрджрд┐ рд╕рдорд╛рди рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдореБрдЭреЗ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдлрд░ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдмрд╛рдЗрдЯреНрд╕ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдореИрдВ рдЕрд╡рд░реБрджреНрдз рдЖрдИрдУ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛ред рдЗрд╕ рдкрд░ рдФрд░ рдмрд╛рдж рдореЗрдВ ...
рдЧреНрд░рд╛рд╣рдХ рд╕реЗрд╡рд╛
рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдореБрдЦреНрдп рд░реВрдк рд╕реЗ
рдкреНрд▓реЗрдпрд░рд╣реИрдВрдбрд▓рд░ рд╡рд░реНрдЧ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
public class PlayerHandler extends SimpleChannelUpstreamHandler { private PlayerWorkerThread worker; @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдЪреИрдирд▓ рдХреЛ рдХреЗрд╡рд▓ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдбреЗрдЯрд╛ рднреЗрдЬ рд╕рдХрддрд╛ рд╣реИред рд░рд╛рдЗрдЯ (рдкреИрдХреЗрдЯ) рдлрд╝рдВрдХреНрд╢рди, рдЬрд╣рд╛рдВ рдЪреИрдирд▓ рдЦрд┐рд▓рд╛рдбрд╝реА рдХрд╛ рдЪреИрдирд▓ рд╣реИ, рдЬреЛ рдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдкрд░ рдЙрд╕реЗ рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдкреИрдХреЗрдЯ рдкреИрдХреЗрдЯ рд╡рд░реНрдЧ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рд╣реИред рдПрдиреНрдХреЛрдбрд░ рдкреИрдХреЗрдЯ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛ред
рд╡рд┐рдХреЛрдбрдХ рдФрд░ рдПрдирдХреЛрдбрд░
рджрд░рдЕрд╕рд▓, рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рдкреИрдХреЗрдЯ рдкреИрдХреЗрдЯ рдмрдирд╛рдиреЗ рдФрд░ рдЙрд╕реА рдкреИрдХреЗрдЯ рдХреЛ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВред
рдПрдирдХреЛрдбрд░ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдпрд╣ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдкреИрдХреЗрдЯ рднреЗрдЬрддрд╛ рд╣реИ:
public class PacketFrameEncoder extends OneToOneEncoder { @Override protected Object encode(ChannelHandlerContext channelhandlercontext, Channel channel, Object obj) throws Exception { if(!(obj instanceof Packet)) return obj;
рд╡рд┐рдХреЛрдбрдХ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдЖрдП рдмрдлрд░ рдореЗрдВ, рдкреВрд░реЗ рдкреИрдХреЗрдЯ рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдмрд╛рдЗрдЯреНрд╕ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд░рд┐рдкреНрд▓реЗрдЗрдВрдЧрдбреЗрдХреЛрдбрд░ рд╡рд░реНрдЧ рд╣рдорд╛рд░реА рдорджрдж рдХрд░реЗрдЧрд╛ред рд╣рдореЗрдВ рдмрд╕ рдЗрд╕рдХреЗ рдбрд┐рдХреЛрдб рдлрдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдФрд░ рдХрд┐рд╕реА рднреА рдЪреАрдЬ рдХреА рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдЗрд╕рдореЗрдВ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ:
public class PacketFrameDecoder extends ReplayingDecoder<VoidEnum> { @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { ctx.sendUpstream(e); } @Override public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { ctx.sendUpstream(e); } @Override protected Object decode(ChannelHandlerContext arg0, Channel arg1, ChannelBuffer buffer, VoidEnum e) throws Exception { return Packet.read(buffer); } }
рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ? рдмрд╣реБрдд рд╕рд░рд▓рддрд╛ рд╕реЗ, рдбрд┐рдХреЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдбрд┐рдХреЛрдбрд░ рд╡рд░реНрддрдорд╛рди рд░реАрдб рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЕрдЧрд░ рдмрдлрд░ рд╕реЗ рдкрдврд╝рддреЗ рд╕рдордп рдкрд░реНрдпрд╛рдкреНрдд рдбреЗрдЯрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдмрдлрд░ рдЕрдкрдиреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдЕрдзрд┐рдХ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдХреЛрдб рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдПрдХ рд╕рдлрд▓ рд░реАрдб (рдиреЙрди-рдирд▓ рд▓реМрдЯрд╛) рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдбрд┐рдХреЛрдбрд░ рдлрд┐рд░ рд╕реЗ рдбреАрдХреЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдЧрд╛, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдлрд░ рдореЗрдВ рд╢реЗрд╖ рдбреЗрдЯрд╛ рдкрд░, рдЕрдЧрд░ рдЗрд╕рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдФрд░ рдмрд╛рдЗрдЯ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рд╕рдм рдзреАрд░реЗ-рдзреАрд░реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЕрдЧрд░ рдпрд╣ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмрдлрд░ рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рдорд╛рддреНрд░рд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рдФрд░ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рдХрд┐ рд╡реЗ рдкреИрдХреЗрдЯ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдХреИрд╢реНрдб рдЕрдкрд╡рд╛рдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╕реНрдЯреИрдХрдЯреНрд░реЗрд╕ рдХреЛ рднрд░рдиреЗ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдирдпрд╛ рдЕрдкрд╡рд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдореЗрдВ рдХреЛрдИ рд╕рдордп рдЦрд░реНрдЪ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрдк
рдпрд╣рд╛рдБ ReplayingDecoder рдХреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдмрдврд╝рд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреБрдЫ рдЕрдиреНрдп рдкреНрд░рджрд░реНрд╢рдиреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ
редрдЖрдк рдлрд╝реНрд░реЗрдордбреЗрдХреЛрдбрд░ рдХреЗ рд╕рд╛рде рднреА рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрд┐рд╕реА рдкреИрдХреЗрдЯ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдЙрд╕рдХреА рдЖрдИрдбреА рджреНрд╡рд╛рд░рд╛ рдкреВрд░реНрд╡-рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдм рд╣реИ
рдкрд░рд┐рдгрд╛рдо рдмреЗрд╣рддрд░реАрди рдереЗред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рд░реНрд╡рд░ рдЕрдм рдПрдХ рд╣рдЬрд╛рд░ рдереНрд░реЗрдбреНрд╕ рдХреЗ рд╕рд╛рде рд╕реНрдЯреНрд░реАрдо рдХрд░рддрд╛ рд╣реИ - 4 рдиреЗрдЯреНрдЯреА рд╕реНрдЯреНрд░реАрдо + 4 рдбреЗрдЯрд╛ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдереНрд░реЗрдбреНрд╕ 250+ рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВ (рдкрд░реАрдХреНрд╖рдг рдЬрд╛рд░реА рд╣реИ)ред рджреВрд╕рд░реЗ, рдкреНрд░реЛрд╕реЗрд╕рд░ рд▓реЛрдб рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдХрдиреЗрдХреНрд╢рди рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рд░реИрдЦрд┐рдХ рд░реВрдк рд╕реЗ рдмрдврд╝рдирд╛ рдмрдВрдж рд╣реЛ рдЧрдпрд╛ рд╣реИред рддреАрд╕рд░реЗ, рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдХрдо рд╣реЛ рдЧрдпрд╛ рд╣реИред
рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рдпрд╣ рдорджрджрдЧрд╛рд░ рд▓рдЧреЗрдЧрд╛ред рдореИрдВрдиреЗ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рдореИрдВ рдмрд╣реБрдд рджреВрд░ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ред рдЖрдЦрд┐рд░рдХрд╛рд░, рдХрдИ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рд╣реИрдВ? рдЕрдкрдиреЗ рдЬрд╡рд╛рдм рдкреВрдЫреЗрдВ рдФрд░ рдХрдбрд╝рд╛рдИ рд╕реЗ рдиреНрдпрд╛рдп рди рдХрд░реЗрдВ - рдореИрдВ рдкрд╣рд▓реА рдмрд╛рд░ рд╣реИрдмрд░ рдореЗрдВ рд▓рд┐рдЦрддрд╛ рд╣реВрдВред
рдкреЛрд╕реНрдЯрд╕реНрдХреНрд░рд┐рдкреНрдЯ: рдХреБрдЫ рдФрд░ рдЙрдкрдпреЛрдЧреА рдЪреАрдЬреЗрдВ
рдиреЗрдЯреНрдЯреА рдореЗрдВ рдХреБрдЫ рдЕрдиреНрдп рд░реЛрдЪрдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реИрдВ рдЬреЛ рд╡рд┐рд╢реЗрд╖ рдЙрд▓реНрд▓реЗрдЦ рдХреЗ рдпреЛрдЧреНрдп рд╣реИрдВ:
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рд░реНрд╡рд░ рдмрдВрдж:
ChannelFuture future = channel.close(); future.awaitUninterruptibly();
рдЬрд╣рд╛рдВ
рдЪреИрдирд▓ рд╡рд╣
рдЪреИрдирд▓ рд╣реИ рдЬрд╣рд╛рдВ рдмрд╛рдЗрдВрдб рдлрдВрдХреНрд╢рди рд╢реБрд░реБрдЖрдд рдореЗрдВ рд▓реМрдЯрд╛ рдерд╛ред рдЬрдм рддрдХ рдЪреИрдирд▓ рдмрдВрдж рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдФрд░ рдХреЛрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рд╣реЗрдЧрд╛, рддрдм рддрдХ
future.awaitUninterruptibly () рдкреНрд░рддреАрдХреНрд╖рд╛
рдХрд░реЗрдЧрд╛ ред
рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ: ChannelFutureред рдЬрдм рд╣рдо Channel.write (рдкреИрдХреЗрдЯ) рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдЪреИрдирд▓ рдХреЛ рдкреИрдХреЗрдЯ рднреЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рд╡рд╣ ChannelFuture рдкрд░ рд▓реМрдЯрддрд╛ рд╣реИ - рдпрд╣ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬреЛ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЬрд╛ рд░рд╣реА рд╕реНрдерд┐рддрд┐ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЖрдк рдЬрд╛рдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдкреВрд░реА рд╣реЛ рдЧрдИ рд╣реИ рдпрд╛ рдирд╣реАрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдПрдХ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдкреИрдХреЗрдЯ рднреЗрдЬрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдХреЗ рдкреАрдЫреЗ рдЪреИрдирд▓ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдЧрд░ рд╣рдо рдХрд░рддреЗ рд╣реИрдВ
channel.write(new Packet255KickDisconnect("!")); channel.close();
рдлрд┐рд░ 99% рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ ChannelClosedException рдорд┐рд▓реЗрдЧреА рдФрд░ рдкреИрдХреЗрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдЖрдк рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
ChannelFuture future = channel.write(new Packet255KickDisconnect("!")); try { future.await(10000);
рд╕рдм рдХреБрдЫ рд╕реБрдкрд░ рд╣реЛрдЧрд╛, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдпрд╣ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдзрд╛рдЧреЗ рдХреЛ рдмреНрд▓реЙрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдкреИрдХреЗрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдирд╣реАрдВ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЖрдк ChannelFuture рдкрд░ рдПрдХ рд╢реНрд░реЛрддрд╛ рдХреЛ рд▓рдЯрдХрд╛ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рдЬрд┐рд╕реЗ рдЕрдзрд┐рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдШрдЯрдирд╛ рдкреВрд░реА рд╣реЛ рдЧрдИ рд╣реИ рдФрд░ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░реЗрдЧрд╛ред рдХрдиреЗрдХреНрд╢рди рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддреИрдпрд╛рд░ рд╢реНрд░реЛрддрд╛
ChannelFutureListener.CLOSE рд╣реИ ред рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:
ChannelFuture future = channel.write(new Packet255KickDisconnect("!")); furute.addListener(ChannelFutureListener.CLOSE);
рдкреНрд░рднрд╛рд╡ рдПрдХ рд╣реА рд╣реИ, рдХреЛрдИ рддрд╛рд▓реЗ рдирд╣реАрдВ рд╣реИрдВред рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЕрдкрдирд╛ рд╢реНрд░реЛрддрд╛ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП - рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдХрд╛рд░реНрдп рд╣реИред рдХрд┐рд╕реА рднреА рддреИрдпрд╛рд░ рд╡рд░реНрдЧ рдХреЛ рдЦреЛрд▓реЗрдВ, рдпрд╣рд╛рдВ рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рджреВрдВрдЧрд╛ред
рдЕрдзрд┐рдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА
рдЬреИрд╕рд╛ рдХрд┐ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдиреЛрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдпрд╣ рдЪреЗрддрд╛рд╡рдиреА рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЕрд╡рд░реБрджреНрдз рд╕рдВрдЪрд╛рд▓рди рдпрд╛ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ (рд╣реИрдВрдбрд▓рд░ рдЬреЛ рдкрд╛рдЗрдк рд▓рд╛рдЗрди рдкрд░ рд▓рдЯрдХрд╛ рд╣реБрдЖ рд╣реИ)ред рдЕрдиреНрдпрдерд╛, рдЖрдк рд╕реНрдерд╛рдпреА рд░реВрдк рд╕реЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдХреЛ рдЦреЛрдиреЗ рдпрд╛ рдЕрдиреНрдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдзреАрдорд╛ рдХрд░рдиреЗ рдХрд╛ рдЬреЛрдЦрд┐рдо рдЪрд▓рд╛рддреЗ рд╣реИрдВред
рд╕рд╛рде рд╣реА, рд╣реИрдВрдбрд▓рд░ рдореЗрдВ, рдХрд┐рд╕реА рднреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ "рднрд╡рд┐рд╖реНрдп рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛" рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдЕрд░реНрдерд╛рддред execute .wait () рдпрд╛ .awaitUninterruptibly () рдХрд┐рд╕реА рднреА ChannelFuture рдкрд░ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдк рд╕рдлрд▓ рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВ, рдЖрдк рдЙрдиреНрд╣реЗрдВ рд╣реИрдВрдбрд▓рд░ рд╕реЗ рдирд╣реАрдВ рдмреБрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ - рд╕рд┐рд╕реНрдЯрдо рдЖрдкрдХреЛ рдРрд╕реА рдореВрд░реНрдЦрддрд╛ рдирд╣реАрдВ рдХрд░рдиреЗ рджреЗрдЧрд╛ рдФрд░ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрдЧрд╛ред рджреВрд╕рд░реЗ, рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рдерд╛, рддреЛ рдЖрдкрдХрд╛ рдкреНрд░рд╡рд╛рд╣ рдлрд┐рд░ рд╕реЗ рд╕реЗрд╡рд╛ рдХреЗ рдмрд┐рдирд╛ рдЕрдиреНрдп рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдорд░ рд╕рдХрддрд╛ рд╣реИред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, ChannelHandlers рдореЗрдВ рдХрд┐рдП рдЧрдП рд╕рднреА рдХрд╛рд░реНрдп рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рдФрд░ рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдПред рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕реАрдзреЗ рдЙрди рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рди рдХрд░реЗрдВ - рдкреИрдХреЗрдЯ рдХреЛ рдХрддрд╛рд░ рдореЗрдВ рд░рдЦреЗрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рджреВрд╕рд░реЗ рдзрд╛рдЧреЗ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВред