One, the basic method
The previous section implements the basic connection of the Netty, which joins spring to manage the Netty and the spring to open the Netty service.
In the Netty server, we set up three classes: HelloServer (program main entry), Helloserverinitializer (transfer channel initialization), Helloserverhandler (Business Controller)
In these three classes, HelloServer New has a helloserverinitializer, and a helloserverhandler is finally new in Helloserverinitializer. The place where new is needed is where spring is to be managed.
Second, realize the source code 1, related preparation
Import the required jar package and related dependencies, mainly Spring,log4j,netty, etc., the following project source contains all the jar packages;
In addition, you can use MAVEN to build projects and add a variety of jar packages.
2, main program Testsrping.java
The main program is simple enough to load the spring configuration file.
PackageCOM.WAYHB;ImportOrg.apache.log4j.Logger;ImportOrg.springframework.context.ApplicationContext;ImportOrg.springframework.context.support.ClassPathXmlApplicationContext; Public classtestspring {Private StaticLogger log = Logger.getlogger (testspring.class); Public Static voidMain (string[] args) {//TODO auto-generated Method Stub//load the spirng configuration fileApplicationContext context=NewClasspathxmlapplicationcontext ("Server.xml"); }}
3,spring XML Configuration single server.xml and log4j configuration files
Server.xml
<beans xmlns= "Http://www.springframework.org/schema/beans"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:aop= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP"Xmlns:tx= "Http://www.springframework.org/schema/tx" xmlns:context= "Http://www.springframework.org/schema/context"Xmlns:lang= "Http://www.springframework.org/schema/lang" xmlns:util= "Http://www.springframework.org/schema/util"xsi:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP http://www.springframework.org/schema/aop/spring-aop-3.0.xsd/HTTP WWW.SPRINGFRAMEWORK.ORG/SCHEMA/TX http://www.springframework.org/schema/tx/spring-tx-3.0.xsd/HTTP Www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http ://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd/http Www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd "default-lazy-init= "false"default-autowire= "ByName" ><!--<bean id= "User"class= "Com.wayhb.User" ><property name= "userid" value= "></property><property name=" username "value=" "WAYHB" ></property></bean>--><!--open annotation mode, scan Com.wayhb,com.netty two package path--><context: Annotation-config/> <context:component-scan base- Package= "Com.wayhb,com.netty"/> <!--Traditional method Configuration Bean<bean id= "HelloServer"class= "Com.netty.HelloServer" init-method= "ServerStart" ><property name= "Helloserverinitializer" ref= " Helloserverinitializer "></property></bean><bean id=" Helloserverinitializer "class= "Com.netty.HelloServerInitializer" ><property name= "Helloserverhandler" ref= "Helloserverhandler" ></ Property></bean><bean id= "Helloserverhandler"class= "Com.netty.HelloServerHandler" scope= "prototype" ></bean>--></beans>
Log4j.properties
# # # setting #log4j. Rootlogger=Debug,stdout,d,elog4j.rootlogger=debug,stdout### output information to control lift # # #log4j. Appender.stdout=Org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=Org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern= [%-5p]%d{yyyy-mm-dd hh:mm:ss,sss} method:%l%n%m%n### output Debug levels above the log to=e://Logs/error.log # # ##log4j. APPENDER.D =Org.apache.log4j.dailyrollingfileappender#log4j.appender.d.file= C://Logs/log.log#log4j. Appender.d.append =true#log4j. Appender.d.threshold=DEBUG #log4j. Appender.d.layout=Org.apache.log4j.patternlayout#log4j.appender.d.layout.conversionpattern=%-d{yyyy-mm-dd HH:mm:ss} [%t:%r]-[%p]%m%n### output error levels above the log to=e://Logs/error.log # # ##log4j. APPENDER.E =Org.apache.log4j.dailyrollingfileappender#log4j.appender.e.file=c://Logs/error.log#log4j. Appender.e.append =true#log4j. Appender.e.threshold=ERROR #log4j. Appender.e.layout=Org.apache.log4j.patternlayout#log4j.appender.e.layout.conversionpattern=%-d{yyyy-mm-dd HH:mm:ss} [%t:%r]-[%p]%m%n
Where the output function is off, if needed, remove the # on it.
4,helloserver
PackageCom.netty;ImportIo.netty.bootstrap.ServerBootstrap;Importio.netty.channel.ChannelFuture;ImportIo.netty.channel.EventLoopGroup;ImportIo.netty.channel.nio.NioEventLoopGroup;ImportIo.netty.channel.socket.nio.NioServerSocketChannel;Importjavax.annotation.PostConstruct;ImportOrg.apache.log4j.Logger;Importorg.springframework.beans.factory.annotation.Autowired;ImportOrg.springframework.stereotype.Service;//annotation Method injected bean, name is HelloServer@Service ("HelloServer") Public classHelloServer {Private StaticLogger log = Logger.getlogger (HelloServer.class); /*** Port address for server monitoring*/ Private Static Final intPortNumber = 7878; //Automatic equipment variables, spring will be based on the name or type to equip this variable, annotation method does not need a set get method@AutowiredPrivateHelloserverinitializer Helloserverinitializer; //Program Initial method entry annotation, hint Spring This program first executes here@PostConstruct Public voidServerStart ()throwsinterruptedexception{eventloopgroup Bossgroup=NewNioeventloopgroup (); Eventloopgroup Workergroup=NewNioeventloopgroup (); Try{Serverbootstrap b=NewServerbootstrap (); B.group (Bossgroup, Workergroup); B.channel (Nioserversocketchannel.class); B.childhandler (Helloserverinitializer); //server-bound port monitoringChannelfuture f =B.bind (portnumber). sync (); //Monitoring Server shutdown monitoringF.channel (). Closefuture (). sync (); Log.info ("###########################################"); //can be shortened to /*B.bind (portnumber). sync (). Channel (). Closefuture (). sync ();*/ } finally{bossgroup.shutdowngracefully (); Workergroup.shutdowngracefully (); } } }
Annotations are easier to configure, with a lot less content
5,helloserverinitializer
PackageCom.netty;Importorg.springframework.beans.factory.annotation.Autowired;ImportOrg.springframework.context.annotation.Scope;ImportOrg.springframework.stereotype.Service;ImportIo.netty.channel.ChannelInitializer;ImportIo.netty.channel.ChannelPipeline;ImportIo.netty.channel.socket.SocketChannel;ImportIo.netty.handler.codec.DelimiterBasedFrameDecoder;Importio.netty.handler.codec.Delimiters;ImportIo.netty.handler.codec.string.StringDecoder;ImportIo.netty.handler.codec.string.StringEncoder; @Service ("Helloserverinitializer") Public classHelloserverinitializerextendsChannelinitializer<socketchannel>{@AutowiredPrivateHelloserverhandler Helloserverhandler; @Overrideprotected voidInitchannel (Socketchannel ch)throwsException {Channelpipeline pipeline=Ch.pipeline (); //decoder with the end of ("\ n")Pipeline.addlast ("Framer",NewDelimiterbasedframedecoder (8192, Delimiters.linedelimiter ())); //string decoding and encodingPipeline.addlast ("Decoder",NewStringdecoder ()); Pipeline.addlast ("Encoder",NewStringencoder ()); //own Logic HandlerPipeline.addlast ("Handler", Helloserverhandler); }}
6,helloserverhandler
PackageCom.netty;Importjava.net.InetAddress;ImportOrg.springframework.context.annotation.Scope;ImportOrg.springframework.stereotype.Service;ImportIo.netty.channel.Channel;ImportIo.netty.channel.ChannelHandlerContext;ImportIo.netty.channel.SimpleChannelInboundHandler;ImportIo.netty.channel.group.ChannelGroup;ImportIo.netty.channel.group.DefaultChannelGroup;ImportIo.netty.util.concurrent.GlobalEventExecutor;Importio.netty.channel.ChannelHandler.Sharable; @Service ("Helloserverhandler") @Scope ("Prototype")//pay special attention to this note @sharable, the default version 4 does not automatically import matching packages, you need to manually join//address is import io.netty.channel.ChannelHandler.Sharable;@Sharable Public classHelloserverhandlerextendsSimplechannelinboundhandler<string> { Public StaticChannelgroup channels =NewDefaultchannelgroup (globaleventexecutor.instance); @Override Public voidhandleradded (Channelhandlercontext ctx)throwsException {//(2)Channel incoming =Ctx.channel (); for(Channel channel:channels) {Channel.writeandflush ("[SERVER]-" + incoming.remoteaddress () + "Add \ n"); } channels.add (Ctx.channel ()); } @Override Public voidHandlerremoved (Channelhandlercontext ctx)throwsException {//(3)Channel incoming =Ctx.channel (); for(Channel channel:channels) {Channel.writeandflush ("[SERVER]-" + incoming.remoteaddress () + "Leave \ n"); } channels.remove (Ctx.channel ()); } @Overrideprotected voidChannelRead0 (Channelhandlercontext ctx, String msg)throwsException {//Receive message print output directlySystem.out.println (Ctx.channel (). Remoteaddress () + "Say:" +msg); //return Client Message-I have received your messageCtx.writeandflush ("Received Your message!\n"); } /** * Overwrite channelactive method triggers when channel is enabled (when connection is established) * * Channelactive and channelinactive are described in the following sections, which Don't do a detailed description of it first .*/@Override Public voidChannelactive (Channelhandlercontext ctx)throwsException {System.out.println ("Ramoteaddress:" + Ctx.channel (). Remoteaddress () + "Active!"); Ctx.writeandflush ("Welcome to" + inetaddress.getlocalhost (). GetHostName () + "service!\n"); Super. channelactive (CTX); }}
Pay special attention to this note @sharable, the default version 4 does not automatically import matching packages, you need to manually join
Address is import io.netty.channel.ChannelHandler.Sharable;
Three, run the test
1, open Testspring.java, right button to run, under normal circumstances the server will open;
2, open the item written on the previous section, open Helloclient.java, right-click to run;
3,helloclient.java run again, there are two clients, if the connection is successful, the project is not a problem.
Note: Netty4 need to @sharable to open more than handler, so need to join the handler class on multiple connections to add the annotation @sharable, the annotation automatically import a problem, manually add the package import io.netty.channel.ChannelHandler.Sharable;
Netty Building a game server (iii)--netty spring Simple integration