??xml version="1.0" encoding="utf-8" standalone="yes"?>天堂在线一二区,一级精品视频在线观看宜春院,91精品久久久久久久久不口人http://www.aygfsteel.com/paulwong/category/53575.htmlzh-cnTue, 14 May 2013 17:15:45 GMTTue, 14 May 2013 17:15:45 GMT60MINA资源http://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.htmlpaulwongpaulwongTue, 14 May 2013 09:41:00 GMThttp://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.htmlhttp://www.aygfsteel.com/paulwong/comments/399270.htmlhttp://www.aygfsteel.com/paulwong/archive/2013/05/14/399270.html#Feedback0http://www.aygfsteel.com/paulwong/comments/commentRss/399270.htmlhttp://www.aygfsteel.com/paulwong/services/trackbacks/399270.html http://yaojialing.iteye.com/category/115609

使用 Apache MINA 2 开发网l应?br />http://www.ibm.com/developerworks/cn/java/j-lo-mina2/

直接操作mina的IoBuffer?
http://autumnice.blog.163.com/blog/static/555200201011493410310/

pache mina 学习Q十一Q?----状态机QstateMachineQ?br />http://cages.iteye.com/blog/1530849

q用 Apache MINA 2 开发网l运?[多图]
http://www.lj8lj8.com/chengxukaifa/Java/338853_13.html




paulwong 2013-05-14 17:41 发表评论
]]>
ZApache Mina实现的TCP长连接和短连接实?/title><link>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html</link><dc:creator>paulwong</dc:creator><author>paulwong</author><pubDate>Sat, 11 May 2013 13:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html</guid><wfw:comment>http://www.aygfsteel.com/paulwong/comments/399155.html</wfw:comment><comments>http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/paulwong/comments/commentRss/399155.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/paulwong/services/trackbacks/399155.html</trackback:ping><description><![CDATA[1、前a<br /> <br /> Apache MINA是Apachel织的一个优U的项目。MINA是Multipurpose Infrastructure for NetworkApplications的羃写。它是一个网l应用程序框Ӟ用来帮助用户非常方便地开发高性能和高可靠性的|络应用E序。在本文中介l了 如何通过Apache Mina2.0来实现TCP协议长连接和短连接应用?br /> <br /> 2、系l介l?br /> <br /> 2.1pȝ框架<br /> <br /> 整个pȝ׃个服务端E序和两个客LE序l成。分别实现TCP长连接和短连接通信?br /> <br /> pȝ业务逻辑是一个客L与服务端建立长连接,一个客L与服务端建立短连接。数据从短连接客Ll过服务端发送到长连接客LQƈ从长q接客户端接收响应数据。当收到响应数据后断开q接?br /> <br /> pȝ架构囑֦下:<br /> <br /> <br /> 2.2处理程<br /> <br /> pȝ处理程如下Q?br /> <br /> 1Q? 启动服务端程序,监听8001?002端口?br /> <br /> 2Q? 长连接客L向服务端8002端口建立q接Q服务端连接对象保存到׃n内存中。由于采用长q接方式Q连接对象是唯一的?br /> <br /> 3Q? 短连接客L向服务端8001端口建立q接。徏立连接后创徏一个连接对象?br /> <br /> 4Q? 短连接客Lq接成功后发送数据。服务端接收到数据后从共享内存中得到长连接方式的q接对象Q用此对象向长q接客户端发送数据。发送前短q接对象设ؓ长连接对象的属性倹{?br /> <br /> 5Q? 长连接客L接收到数据后q回响应数据。服务端从长q接对象的属性中取得短连接对象,通过此对象将响应数据发送给短连接客L?br /> <br /> 6Q? 短连接客L收到响应数据后,关闭q接?br /> <br /> 3、服务端E序<br /> <br /> 3.1长连接服务端<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaLongConnServer {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8002;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> start()<span style="color: #0000FF; ">throws</span> IOException{<br /> <br /> IoAcceptor acceptor = <span style="color: #0000FF; ">new</span> NioSocketAcceptor();<br /> <br /> <br /> <br /> acceptor.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> acceptor.setHandler(<span style="color: #0000FF; ">new</span> MinaLongConnServerHandler());<br /> <br /> acceptor.getSessionConfig().setReadBufferSize(2048);<br /> <br /> acceptor.bind(<span style="color: #0000FF; ">new</span> InetSocketAddress(PORT));<br /> <br /> System.out.println("Listeningon port " + PORT);<br /> <br /> }<br /> <br /> }<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; ">消息处理</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaLongConnServerHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();<br /> <br /> String clientIp = remoteAddress.getAddress().getHostAddress();<br /> <br /> logger.info("LongConnect Server opened Session ID ="+String.valueOf(session.getId()));<br /> <br /> logger.info("接收来自客户?nbsp;:" + clientIp + "的连?");<br /> <br /> Initialization init = Initialization.getInstance();<br /> <br /> HashMap<String, IoSession> clientMap =init.getClientMap();<br /> <br /> clientMap.put(clientIp, session);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the long connect server..");<br /> <br /> String expression = message.toString();<br /> <br /> logger.info("Message is:" + expression);<br /> <br /> IoSession shortConnSession =(IoSession) session.getAttribute("shortConnSession");<br /> <br /> logger.info("ShortConnect Server Session ID ="+String.valueOf(shortConnSession.getId()));<br /> <br /> shortConnSession.write(expression);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionIdle(IoSession session, IdleStatus status) {<br /> <br /> logger.info("Disconnectingthe idle.");<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> disconnect an idle client</span><span style="color: #008000; "><br /> </span><br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> close the connection onexceptional situation</span><span style="color: #008000; "><br /> </span><br /> logger.warn(cause.getMessage(), cause);<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> 3.2短连接服务端<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortConnServer {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8001;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> start()<span style="color: #0000FF; ">throws</span> IOException{<br /> <br /> IoAcceptor acceptor = <span style="color: #0000FF; ">new</span> NioSocketAcceptor();<br /> <br /> <br /> <br /> acceptor.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> acceptor.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> acceptor.setHandler(<span style="color: #0000FF; ">new</span> MinaShortConnServerHandler());<br /> <br /> acceptor.getSessionConfig().setReadBufferSize(2048);<br /> <br /> acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);<br /> <br /> acceptor.bind(<span style="color: #0000FF; ">new</span> InetSocketAddress(PORT));<br /> <br /> System.out.println("Listeningon port " + PORT);<br /> <br /> }<br /> <br /> }</div> <br /> 消息处理<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortConnServerHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> InetSocketAddress remoteAddress = (InetSocketAddress)session.getRemoteAddress();<br /> <br /> logger.info(remoteAddress.getAddress().getHostAddress());<br /> <br /> logger.info(String.valueOf(session.getId()));<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the short connect server<img src="http://www.aygfsteel.com/Images/dot.gif" alt="" />");<br /> <br /> String expression = message.toString();<br /> <br /> Initialization init = Initialization.getInstance();<br /> <br /> HashMap<String, IoSession> clientMap =init.getClientMap();<br /> <br /> <span style="color: #0000FF; ">if</span> (clientMap == <span style="color: #0000FF; ">null</span> || clientMap.size() == 0) {<br /> <br /> session.write("error");<br /> <br /> } <span style="color: #0000FF; ">else</span> {<br /> <br /> IoSession longConnSession = <span style="color: #0000FF; ">null</span>;<br /> <br /> Iterator<String> iterator =clientMap.keySet().iterator();<br /> <br /> String key = "";<br /> <br /> <span style="color: #0000FF; ">while</span> (iterator.hasNext()) {<br /> <br /> key = iterator.next();<br /> <br /> longConnSession = clientMap.get(key);<br /> <br /> }<br /> <br /> logger.info("ShortConnect Server Session ID :"+String.valueOf(session.getId()));<br /> <br /> logger.info("LongConnect Server Session ID :"+String.valueOf(longConnSession.getId()));<br /> <br /> longConnSession.setAttribute("shortConnSession",session);<br /> <br /> longConnSession.write(expression);<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionIdle(IoSession session, IdleStatus status) {<br /> <br /> logger.info("Disconnectingthe idle.");<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> disconnect an idle client</span><span style="color: #008000; "><br /> </span><br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> close the connection onexceptional situation</span><span style="color: #008000; "><br /> </span><br /> logger.warn(cause.getMessage(), cause);<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> <br /> <br /> 4、客LE序<br /> <br /> 4.1长连接客L<br /> <br /> 使用java.net.Socket来实现向服务端徏立连接。Socket建立后一直保持连接,从服务端接收到数据包后直接将原文q回?br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> TcpKeepAliveClient {<br /> <br /> <span style="color: #0000FF; ">private</span> String ip;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">int</span> port;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> Socket socket = <span style="color: #0000FF; ">null</span>;<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">int</span> timeout = 50 * 1000;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> TcpKeepAliveClient(String ip, <span style="color: #0000FF; ">int</span> port) {<br /> <br /> <span style="color: #0000FF; ">this</span>.ip = ip;<br /> <br /> <span style="color: #0000FF; ">this</span>.port = port;<br /> <br /> }<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> receiveAndSend() <span style="color: #0000FF; ">throws</span> IOException {<br /> <br /> InputStream input = <span style="color: #0000FF; ">null</span>;<br /> <br /> OutputStream output = <span style="color: #0000FF; ">null</span>;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">try</span> {<br /> <br /> <span style="color: #0000FF; ">if</span> (socket == <span style="color: #0000FF; ">null</span> || socket.isClosed() || !socket.isConnected()) {<br /> <br /> socket = <span style="color: #0000FF; ">new</span> Socket();<br /> <br /> InetSocketAddress addr = <span style="color: #0000FF; ">new</span> InetSocketAddress(ip, port);<br /> <br /> socket.connect(addr, timeout);<br /> <br /> socket.setSoTimeout(timeout);<br /> <br /> System.out.println("TcpKeepAliveClientnew ");<br /> <br /> }<br /> <br /> <br /> <br /> input = socket.getInputStream();<br /> <br /> output = socket.getOutputStream();<br /> <br /> <br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> read body</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">byte</span>[] receiveBytes = {};<span style="color: #008000; ">//</span><span style="color: #008000; "> 收到的包字节数组</span><span style="color: #008000; "><br /> </span><br /> <span style="color: #0000FF; ">while</span> (<span style="color: #0000FF; ">true</span>) {<br /> <br /> <span style="color: #0000FF; ">if</span> (input.available() > 0) {<br /> <br /> receiveBytes = <span style="color: #0000FF; ">new</span> <span style="color: #0000FF; ">byte</span>[input.available()];<br /> <br /> input.read(receiveBytes);<br /> <br /> <br /> <br /> <span style="color: #008000; ">//</span><span style="color: #008000; "> send</span><span style="color: #008000; "><br /> </span><br /> System.out.println("TcpKeepAliveClientsend date :" + <span style="color: #0000FF; ">new</span> String(receiveBytes));<br /> <br /> output.write(receiveBytes, 0, receiveBytes.length);<br /> <br /> output.flush();<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> } <span style="color: #0000FF; ">catch</span> (Exception e) {<br /> <br /> e.printStackTrace();<br /> <br /> System.out.println("TcpClientnew socket error");<br /> <br /> }<br /> <br /> }<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> main(String[] args) <span style="color: #0000FF; ">throws</span> Exception {<br /> <br /> TcpKeepAliveClient client = <span style="color: #0000FF; ">new</span> TcpKeepAliveClient("127.0.0.1", 8002);<br /> <br /> client.receiveAndSend();<br /> <br /> }<br /> <br /> <br /> <br /> }</div> <br /> 4.2短连接客L<br /> <br /> 服务启动<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortClient {<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">final</span> <span style="color: #0000FF; ">int</span> PORT = 8001;<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">static</span> <span style="color: #0000FF; ">void</span> main(String[] args) <span style="color: #0000FF; ">throws</span> IOException,InterruptedException {<br /> <br /> IoConnector connector = <span style="color: #0000FF; ">new</span> NioSocketConnector();<br /> <br /> connector.getSessionConfig().setReadBufferSize(2048);<br /> <br /> <br /> <br /> connector.getFilterChain().addLast("logger", <span style="color: #0000FF; ">new</span> LoggingFilter());<br /> <br /> connector.getFilterChain().addLast("codec", newProtocolCodecFilter(<span style="color: #0000FF; ">new</span> TextLineCodecFactory(Charset.forName("UTF-8"))));<br /> <br /> <br /> <br /> connector.setHandler(<span style="color: #0000FF; ">new</span> MinaShortClientHandler());<br /> <br /> <span style="color: #0000FF; ">for</span> (<span style="color: #0000FF; ">int</span> i = 1; i <= 10; i++) {<br /> <br /> ConnectFuture future = connector.connect(<span style="color: #0000FF; ">new</span> InetSocketAddress("127.0.0.1", PORT));<br /> <br /> future.awaitUninterruptibly();<br /> <br /> IoSession session =future.getSession();<br /> <br /> session.write(i);<br /> <br /> session.getCloseFuture().awaitUninterruptibly();<br /> <br /> <br /> <br /> System.out.println("result=" + session.getAttribute("result"));<br /> <br /> }<br /> <br /> connector.dispose();<br /> <br /> <br /> <br /> }<br /> <br /> }</div> <br /> 消息处理<br /> <br /> <div style="background-color: #eeeeee; font-size: 13px; border-left-color: #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">class</span> MinaShortClientHandler <span style="color: #0000FF; ">extends</span> IoHandlerAdapter{<br /> <br /> <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Logger logger = (Logger) LoggerFactory.getLogger(getClass());<br /> <br /> <br /> <br /> <span style="color: #0000FF; ">public</span> MinaShortClientHandler() {<br /> <br /> <br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> sessionOpened(IoSession session) {<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> messageReceived(IoSession session, Object message) {<br /> <br /> logger.info("Messagereceived in the client..");<br /> <br /> logger.info("Message is:" + message.toString());<br /> <br /> session.setAttribute("result", message.toString());<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> <br /> <br /> @Override<br /> <br /> <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> exceptionCaught(IoSession session, Throwable cause) {<br /> <br /> session.close(<span style="color: #0000FF; ">true</span>);<br /> <br /> }<br /> <br /> }</div> <br /> 5、ȝ<br /> <br /> 通过本文中的例子QApache Mina在服务端可实现TCP协议长连接和短连接。在客户端只实现了短q接模式Q长q接模式也是可以实现的(在本文中q是采用传统的java Socket方式Q。两个服务端之间通过׃n内存的方式来传递连接对象也许有更好的实现方式?img src ="http://www.aygfsteel.com/paulwong/aggbug/399155.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/paulwong/" target="_blank">paulwong</a> 2013-05-11 21:56 <a href="http://www.aygfsteel.com/paulwong/archive/2013/05/11/399155.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 Apache MINA 开发高性能|络应用E序[转]http://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.htmlpaulwongpaulwongSat, 11 May 2013 13:41:00 GMThttp://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.htmlhttp://www.aygfsteel.com/paulwong/comments/399154.htmlhttp://www.aygfsteel.com/paulwong/archive/2013/05/11/399154.html#Feedback0http://www.aygfsteel.com/paulwong/comments/commentRss/399154.htmlhttp://www.aygfsteel.com/paulwong/services/trackbacks/399154.html Apache MINA(Multipurpose Infrastructure for Network Applications) ?Apache l织一个较新的目Q它为开发高性能和高可用性的|络应用E序提供了非怾利的框架。当前发行的 MINA 版本支持Z Java NIO 技术的 TCP/UDP 应用E序开发、串口通讯E序Q只在最新的预览版中提供Q,MINA 所支持的功能也在进一步的扩展中?

目前正在使用 MINA 的Y件包括有QApache Directory Project、AsyncWeb、AMQPQAdvanced Message Queuing ProtocolQ、RED5 ServerQMacromedia Flash Media RTMPQ、ObjectRADIUS、Openfire {等?

本文通过一个简单的问候程?HelloServer 来介l?MINA 的基架构的同时演C如何用MINA 开发网l应用程序?

环境准备

首先到官方网站下载最新的 MINA 版本Q地址是:http://mina.apache.org/downloads.html。下载之前先介绍一?MINA 的两个版本:1.0.x 适合q行环境?JDK1.4Q?.1.x 适合 JDK1.5 的版本,两者的~译环境都需?JDK1.5。JDK1.5 已经是非常普遍了Q本文中使用 1.1.5 版本?MINAQ编译和q行所需的文件是 mina-core-1.1.5.jar?
下蝲 MINA 的依赖包 slf4j。MINA 使用此项目作为日志信息的输出Q?MINA 本nq不附带此项目包Q请到http://www.slf4j.org/download.html 地址下蝲 slf4j 包,slf4j 目解压后有很多的文Ӟ本例中只需要其中的 slf4j-api-1.4.3.jar ?slf4j-simple-1.4.3.jar q两?jar 文g。如果没有这两个文g׃D启动例子E序的时候报 org/slf4j/LoggerFactory cL扑ֈ的错误?
当然要求机器上必装?1.5 或者更新版本的 JDK?
最好你应该选择一个顺手的 Java 开发环境例?Eclipse 或?NetBeans 之类的,可以更方便的~码和调试,虽然我们的最低要求只是一个简单的文本~辑器而已?



~写代码q执?

~写代码 HelloServer.java 如下

package demo.mina.echo;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.common.*;
import org.apache.mina.transport.socket.nio.*;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;

/**
 * HelloServer演示E序
 * 
@author liudong (
                    
http://www.dlog.cn/javayou
                )
 
*/
public class HelloServer {

    private static final int PORT = 8080;
/**
 * 
@param args
 * 
@throws IOException 
 
*/
public static void main(String[] args) throws IOException {
        IoAcceptor acceptor = new SocketAcceptor();        
        IoAcceptorConfig config = new SocketAcceptorConfig();
        DefaultIoFilterChainBuilder chain = config.getFilterChain();
        //使用字符串编?/span>
        chain.addLast("codec", 
new ProtocolCodecFilter(new TextLineCodecFactory()));
        //启动HelloServer
        acceptor.bind(new InetSocketAddress(PORT), new HelloHandler(), config);
        System.out
.println("HelloServer started on port " + 
PORT);
    }
}

/**
 * HelloServer的处理逻辑
 * 
@author liudong
 
*/
class HelloHandler extends IoHandlerAdapter {
/**
 * 当有异常发生时触?br />  
*/
@Override
    public void exceptionCaught(IoSession ssn, Throwable cause) {
        cause.printStackTrace();
        ssn.close();
    }

/**
 * 有新q接时触?br />  
*/
@Override
public void sessionOpened(IoSession ssn) throws Exception {
    System.out.println("session open for " + ssn.getRemoteAddress());
    }

/**
 * q接被关闭时触发
 
*/
@Override
public void sessionClosed(IoSession ssn) throws Exception {
    System.out.println("session closed from " + ssn.getRemoteAddress());
    }

/**
 * 收到来自客户端的消息
 
*/
public void messageReceived(IoSession ssn, Object msg) throws Exception {    
    String ip = ssn.getRemoteAddress().toString();
System.out.println("===> Message From " + ip +" : " + msg);    
    ssn.write("Hello " + msg);
    }
}

~译执行
先不用试着去读懂每一行代码的具体意思,用你手的编译器~译 HelloServer.javaQ如果报错请认是否已将前面提到的三?jar 文gd至类路径中。如果一切顺利接着可以启动HelloServer E序Q启动后提示QHelloServer started on port 8080 表示启动成功Q如果启动失败,问题无外乎是cL扑ֈ或者端口占用。如果端口被占用的话Q换一个罗Q修?PORT 帔R值后再次~译q启动?

试服务?
打开命o行窗口,输入 telnet localhost 8080 后,输入您的英文名或者其他一些ؕ七八p的字符后回车再ȝ看刚启动的服务程序有何反应。我的反应如下:

HelloServer started on port 8080
session open for /127.0.0.1:3023
===> Message From /127.0.0.1:3023 :hello
===> Message From /127.0.0.1:3023 :hello
===> Message From /127.0.0.1:3023 :liudong
===> Message From /127.0.0.1:3023 :Winter Lau



好了Q一切正常,恭喜你的W一个?MINA 开发的|络E序已经成功q行了?




MINA 基本cȝ描述

在介l架构之前先认识几个接口Q?

IoAccepter 相当于网l应用程序中的服务器?

IoConnector 相当于客L

IoSession 当前客户端到服务器端的一个连接实?

IoHandler 业务处理逻辑

IoFilter qo器用于悬接通讯层接口与业务层接?






MINA 的基架构

下图?MINA 的架构图Q?


?1QMINA 的架构图


在图中的模块链中QIoService 便是应用E序的入口,相当于我们前面代码中?IoAccepterQIoAccepter 便是 IoService 的一个扩展接口。IoService 接口可以用来d多个 IoFilterQ这?IoFilter W合责Q链模式ƈ?IoProcessor U程负责调用。?IoAccepter ?ioService 接口的基上还提供l定某个通讯端口以及取消l定的接口。在上面的例子中Q我们是q样使用 IoAccepter 的:

IoAcceptor acceptor = new SocketAcceptor();



相当于我们用了 Socket 通讯方式作ؓ服务的接入,当前版本?MINA q提供了?SocketAccepter 外的Z数据报文通讯?DatagramAccepter 以及Z道通讯?VmPipeAccepter。另外还包括串口通讯接入方式Q目前基于串口通讯的接入方式已l在最新测试版?MINA 中提供。你也可以自行实?IoService 接口来用自q通讯方式?

而在上图中最右端也就?IoHandlerQ这便是业务处理模块。相当于前面例子中的 HelloHandler cR在业务处理cM不需要去兛_实际的通讯l节Q只处理客L传输q来的信息即可。编?Handler cd是?MINA 开发网l应用程序的重心所在,相当?MINA 已经帮你处理了所有的通讯斚w的细节问题。ؓ了简?Handler c,MINA 提供?IoHandlerAdapter c,此类仅仅是实C IoHandler 接口Q但q不做Q何处理?

一?IoHandler 接口中具有如下一些方法(摘自 MINA ?API 文档Q:

void exceptionCaught(IoSession session, Throwable cause)
当接口中其他Ҏ抛出异常未被捕获时触发此Ҏ
void messageReceived(IoSession session, Object message)
当接收到客户端的h信息后触发此Ҏ.
void messageSent(IoSession session, Object message)
当信息已l传送给客户端后触发此方?
void sessionClosed(IoSession session)
当连接被关闭时触发,例如客户端程序意外退出等{?
void sessionCreated(IoSession session)
当一个新客户端连接后触发此方?
void sessionIdle(IoSession session, IdleStatus status)
当连接空闲时触发此方?
void sessionOpened(IoSession session)
当连接后打开时触发此ҎQ一般此Ҏ?sessionCreated 会被同时触发


前面我们提到 IoService 是负责底层通讯接入Q?IoHandler 是负责业务处理的。那?MINA 架构图中?IoFilter 作何用途呢Q答案是你想作何用途都可以。但是有一个用途却是必ȝQ那是作ؓ IoService ?IoHandler 之间的桥梁。IoHandler 接口中最重要的一个方法是 messageReceivedQ这个方法的W二个参数是一?Object 型的消息QL周知QObject 是所?Java 对象的基Q那到底谁来军_q个消息到底是什么类型呢Q答案也在q个 IoFilter 中。在前面使用的例子中Q我们添加了一?IoFilter ?new ProtocolCodecFilter(new TextLineCodecFactory())Q这个过滤器的作用是来自客L输入的信息{换成一行行的文本后传递给 IoHandlerQ因此我们可以在 messageReceived 中直接将 msg 对象强制转换?String 对象?

而如果我们不提供Mqo器的话,那么?messageReceived Ҏ中的W二个参数类型就是一?byte 的缓冲区Q对应的cL org.apache.mina.common.ByteBuffer。虽然你也可以将解析客户端信息放?IoHandler 中来做,但这q不是推荐的做法Q原来清晰的模型又模糊hQ变?IoHandler 不只是业务处理,q得充当协议解析的Q务?

MINA自n带有一些常用的qo器,例如LoggingFilterQ日志记录)、BlackListFilterQ黑名单qoQ、CompressionFilterQ压~)、SSLFilterQSSL加密Q等?



其他

MINA 不仅仅是用来开发网l服务器端应用程序,它一样可以?IoConnector 来连接到各种各样的网l服务程序?

通过本文?HelloServer q个例子Q我们在惊叹 MINA 可以带来多么大便利的同时Q还不得不ؓ其卓的性能而骄Ԍ据称使用MINA开发服务器E序的性能已经D使用 C/C++ 语言开发的|络服务。作?MINA 的入门文章,性能问题不在本文讨论范围内?

另外?MINA 压羃包中附带有不比 HelloServer 要好得多的例子,通过q些例子可以q一步的了解q掌?MINA?




参考资?

http://mina.apache.org MINA 官方|站


http://mina.apache.org/features.html 您可以在q里查看关于 MINA 的更多特?


http://mina.apache.org/testimonials.html 看看别h是如何评?MINA ?http://asyncweb.safehaus.org/使用 MINA 开发的高性能 WEB 服务?nbsp;


paulwong 2013-05-11 21:41 发表评论
]]>
վ֩ģ壺 Ͻ| ɽ| | ±| | ƽ| ̨ʡ| | ¦| ݸ| | | | º| | ɽ| | ɽ| Զ| | Ļ| ԭ| | ֣| Į| | | | | ʱ| Ϻӿ| | ƽ| | | | Ͻ| ¡| | ˻| |