大家好,又见面了,我是全栈君。
Grizzly开发Echoserver实战
作者:chszs,转载需注明。
博客主页:http://blog.csdn.net/chszs
用Java编写可伸缩的server应用是有难度的。用Java NIO开发、线程管理、为成千上万的用户做server扩展。这些都是难点。Grizzly NIO框架的设计目标就是帮助开发人员非常好地利用Java NIO API。编写出高可扩展性的、功能强大的server,并提高了扩展的框架组件:Web Framework(HTTP/S)、WebSocket、Comet等。
Grizzly 2.3开发Echoserver/client的样例
1、下载grizzly-framework.jar库
Maven依赖
<dependency> <groupId>org.glassfish.grizzly</groupId> <artifactId>grizzly-framework</artifactId> <version>2.3.16</version> </dependency>
或下载地址:
http://central.maven.org/maven2/org/glassfish/grizzly/grizzly-framework/2.3.16/grizzly-framework-2.3.16.jar
2014.10.23日刚公布了2.3.17版,地址见:
https://maven.java.net/content/repositories/releases/org/glassfish/grizzly/grizzly-framework/2.3.17/grizzly-framework-2.3.17.jar
也能够用这个版本号。
server端:
1)创建Echo过滤器
Echo过滤器负责把接收到的消息(无论其类型)原样返回给Grizzly连接。
import java.io.IOException; import org.glassfish.grizzly.filterchain.BaseFilter; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; public class EchoFilter extends BaseFilter{ /** * 仅处理读操作,当消息到来时进行处理 * @param ctx 处理的上下文 * @return 下一个动作 */ @Override public NextAction handleRead(FilterChainContext ctx) throws IOException{ // Peer address用于无连接的UDP连接 final Object peerAddress = ctx.getAddress(); final Object message = ctx.getMessage(); System.out.println("Server received: " + message); ctx.write(peerAddress, message, null); return ctx.getStopAction(); } }
2)server初始化代码
全部的server过滤器链都准备好,開始初始化并启动server。
import java.io.IOException; import java.nio.charset.Charset; import java.util.logging.Logger; import org.glassfish.grizzly.filterchain.FilterChainBuilder; import org.glassfish.grizzly.filterchain.TransportFilter; import org.glassfish.grizzly.nio.transport.TCPNIOTransport; import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder; import org.glassfish.grizzly.utils.StringFilter; public class EchoServer { private static final Logger logger = Logger.getLogger(EchoServer.class.getName()); public static final String HOST = "localhost"; public static final int PORT = 7777; public static void main(String[] args) throws IOException{ // 用FilterChainBuilder创建过滤器链 FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless(); // 加入TransportFilter。它负责从连接中读数据,并写数据到连接 filterChainBuilder.add(new TransportFilter()); // 字符串过滤器StringFilter负责缓冲和字符串之间的转换 filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8"))); // 过滤器EchoFilter负责把接收到的消息原样返回给连接 filterChainBuilder.add(new EchoFilter()); // 创建TCP传输 final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build(); transport.setProcessor(filterChainBuilder.build()); try{ // 绑定传输,開始对主机+端口进行监听 transport.bind(HOST, PORT); // 開始传输 transport.start(); logger.info("Press any key to stop the Echo server..."); System.in.read(); } finally{ logger.info("Stopping transport..."); // 停止传输server transport.shutdown(); logger.info("Stopped transport..."); } } }
执行Echoserver:
java -classpath grizzly-framework.jar EchoServer
client:
1)创建client过滤器
client过滤器负责重定向server的响应到标准输出。
要注意,client过滤器须要FilterChainContext消息
import java.io.IOException; import org.glassfish.grizzly.filterchain.BaseFilter; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; public class ClientFilter extends BaseFilter{ /** * 仅处理读操作。当消息到来时进行处理 * @param ctx 处理的上下文 * @return 下一个动作 */ @Override public NextAction handleRead(final FilterChainContext ctx) throws IOException{ // 从上下文得到字符串消息,过滤器链仅仅使用了字符串过滤器StringFilter final String serverResponse = ctx.getMessage(); System.out.println("Server echo: " + serverResponse); return ctx.getStopAction(); } }
2)client代码
简单的client,向Echoserver发送消息并等待响应。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Logger; import org.glassfish.grizzly.Connection; import org.glassfish.grizzly.Grizzly; import org.glassfish.grizzly.filterchain.FilterChainBuilder; import org.glassfish.grizzly.filterchain.TransportFilter; import org.glassfish.grizzly.nio.transport.TCPNIOTransport; import org.glassfish.grizzly.nio.transport.TCPNIOTransportBuilder; import org.glassfish.grizzly.utils.StringFilter; import ch.echo.server.EchoServer; public class EchoClient { private static final Logger logger = Grizzly.logger(EchoClient.class); public static void main(String[] args) throws IOException, ExecutionException, InterruptedException, TimeoutException{ Connection connection = null; // 用FilterChainBuilder类创建过滤器链 FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless(); // 加入传输过滤器,它负责从连接读数据并向连接写数据 filterChainBuilder.add(new TransportFilter()); // 加入字符串过滤器,它负责缓冲和字符串之间的转换 filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8"))); // 加入client过滤器,他负责把server响应重定向到标准输出 filterChainBuilder.add(new ClientFilter()); // 创建TCP传输 final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build(); transport.setProcessor(filterChainBuilder.build()); try{ // 启动传输 transport.start(); // 异步执行。连接到server Future<Connection> future = transport.connect(EchoServer.HOST, EchoServer.PORT); // 等待连接操作的完毕 connection = future.get(10, TimeUnit.SECONDS); assert connection!=null; System.out.println("Ready...(\"q\" to exit"); final BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in)); do{ final String userInput = inReader.readLine(); if(userInput==null || "q".equals(userInput)) break; connection.write(userInput); } while(true); } finally{ // 关闭client连接 if(connection!=null) connection.close(); // 停止传输 transport.shutdownNow(); } } }
执行Echoclient:
java -classpath grizzly-framework.jar EchoClient
已经通过測试,程序执行的非常完美。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115753.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...