Grizzly开发Echo服务器实战

Grizzly开发Echo服务器实战

作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs

用Java编写可伸缩的服务器应用是有难度的,用Java NIO开发、线程管理、为成千上万的用户做服务器扩展,这些都是难点。Grizzly NIO框架的设计目标就是帮助开发者很好地利用Java NIO API,编写出高可扩展性的、功能强大的服务器,并提高了扩展的框架组件:Web Framework(HTTP/S)、WebSocket、Comet等。

Grizzly 2.3开发Echo服务器/客户端的例子

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
也可以用这个版本。

服务器端:

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)服务器初始化代码
所有的服务器过滤器链都准备好,开始初始化并启动服务器。

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...");
			// 停止传输服务器
			transport.shutdown();

			logger.info("Stopped transport...");
		}
	}
}

运行Echo服务器:

java -classpath grizzly-framework.jar EchoServer

客户端:

1)创建客户端过滤器
客户端过滤器负责重定向服务器的响应到标准输出。要注意,客户端过滤器需要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)客户端代码
简单的客户端,向Echo服务器发送消息并等待响应。

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")));
		// 添加客户端过滤器,他负责把服务器响应重定向到标准输出
		filterChainBuilder.add(new ClientFilter());

		// 创建TCP传输
		final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
		transport.setProcessor(filterChainBuilder.build());

		try{
			// 启动传输
			transport.start();

			// 异步执行,连接到服务器
			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{
			// 关闭客户端连接
			if(connection!=null)
				connection.close();

			// 停止传输
			transport.shutdownNow();
		}
	}
}

运行Echo客户端:

java -classpath grizzly-framework.jar EchoClient

已经通过测试,程序运行的非常完美。

时间: 2024-10-21 07:56:49

Grizzly开发Echo服务器实战的相关文章

[UNIX网络编程] sun rpc实现的简单echo服务器

RPC的全称是Remote Procedure Call,它能够在本地以函数调用的形式来实现网络操作,让程序员集中关注于业务逻辑,不用关心底层的数据通信. 这里不会详细讲解RPC的原理,而是用一个简单的echo服务器的例子来说明如何使用RPC. 最早实现的RPC是sun rpc,现在它已经移植到了大多数操作系统. 使用RPC,程序员只需要关注客户与服务器之间数据传送的格式以及如何远程过程的定位,客户端如何调用本地函数以调用远程函数,服务器远程过程的实现. 1 客户端与服务器之间数据的交互 客户与

组件化封装开发Android App实战

详情请交流  QQ  709639943 01.组件化封装开发Android App实战 02.Kotlin系统入门与进阶 03.Node.js入门到企业Web开发中的应用 04.精通高级RxJava 2响应式编程思想 05.Java秒杀系统方案优化 高性能高并发实战 06.Java深入微服务原理改造房产销售平台 07.快速上手Linux 玩转典型应用 08.快速上手Ionic3 多平台开发企业级问答社区 09.Java Spring Security开发安全的REST服务 10.深入Java虚

[转帖]华为鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例

鲲鹏云服务器实战:华为云鲲鹏KC1实例 vs. 阿里云G5实例 https://m.ithome.com/html/444828.htm 2019-09-12 15:25IT之家 (阿迷) 今年一月份,华为正式发布了鲲鹏920数据中心高性能处理器,该处理器兼容ARM架构,采用7纳米制造,最高支持64核,主频达到2.6GHz,支持八通道DDR4.PCIe 4.0.100G RoCE网络. 华为云基于鲲鹏920处理器的通用计算增强型KC1实例,作为市面上为数不多基于ARM架构的云服务器表现究竟如何,

全流程开发 TP6.0实战高并发电商服务系统

第1章 课程简介[PHP行情分析]本章主要讲解本课程的主线, 导学内容,PHP行情分析等让同学们对当前PHP发展充满信心等,同时还分析了企业级开发流程以及规范说明,让同学们对中大型公司的敏捷开发有一个初步认知. 第2章 环境及框架准备[必备基础]本章主要讲解环境的安装,通过composer获取TP6源码,nginx的配置等工作,环境是我们一切学习的根源,造起来. 第3章 TP6基础知识[新框架]本章主要讲解了TP5/TP6异同之处,基础的控制器层.模型层的使用,杜绝无效请求让代码更加健壮,数据库

使用Go开发web服务器

原文链接 Go(Golang.org)是在标准库中提供HTTP协议支持的系统语言,通过他可以快速简单的开发一个web服务器.同时,Go语言为开发者提供了很多便利.这本篇博客中我们将列出使用Go开发HTTP 服务器的方式,然后分析下这些不同的方法是如何工作,为什么工作的.    在开始之前,假设你已经知道Go的一些基本语法,明白HTTP的原理,知道什么是web服务器.然后我们就可以开始HTTP 服务器版本的著名的“Hello world”. 首先看到结果,然后再解释细节这种方法更好一点.创建一个叫

JAVA+PHP+阿里云组件纯手工实现POP、SMTP、IMAP开发邮件服务器(二)

java开发邮件服务器的接收模块 用java建立socket服务端,监听端口25,实现SMTP协议.即可完成邮件服务器的接收模块. 这里要注意的是,SMTP协议其实可以分为两种.一种是你用手机.PC等客户端发邮件到邮件服务商的服务器的时候用的SMTP协议,这一类是需要登录验证的.一种是邮件服务商之间传递邮件的SMTP协议,此类协议是不需要登录的.比如你用Foxmail上你的QQ邮箱发送了一封邮件到163的邮箱.过程是这样的: 邮件从Foxmail通过SMTP协议发送到QQ邮箱的服务器. QQ邮箱

iOS开发——完整项目实战OC篇&amp;百思不得姐第四天

iOS开发——完整项目实战OC篇&百思不得姐第四天 上午 一:自定义按钮使用九宫格布局 二:控件不能点击 三:获取用户点击了那个按钮 四:调整按钮内部控件的位置:主流->上下 五:不能直接使用self.navigationController中或者View中获取导航控制器 方法一: 方法二: 六:布局取整 1 // 总行数 2 3 // NSUInteger rows = sqaures.count / maxCols; 4 5 // if (sqaures.count % maxCols)

架设DNS服务器 实战指南(主、从、子、定向转发多图)

一.DNS基础知识(先科普一下): 1.DNS出现的环境: TCP/IP协议通信是基于IP地址的,但是网络管理员无法记住那一串串单调的数字.因此大家基本上是通过访问计算机域名,然后通过 DNS服务器将计算机域名解析为IP地址来实现的.     2.什么是DNS: DNS:域名系统(Domain  Name  System)用于命名组织到域层次结构中的计算机和网络服务.DNS命名用于TCP/IP网络中,通过用户友好的名称查找计算机.当用户在应用程序中输入DNS名称时,DNS服务可以将此名称解析为与

?Jersey 开发RESTFUL服务器

?Jersey 开发RESTFUL服务器 RESTful 一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制. REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序.REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-R