Grizzly快速入门

Grizzly框架组件

使用 Java™编程语言编写可扩展的服务器应用程序一直很困难。在 Java 新 I/O API (NIO) 出现之前,线程管理问题使服务器无法扩展到数千个用户。
Grizzly NIO 框架旨在帮助开发人员利用 Java™ NIO API。Grizzly 的目标是帮助开发人员使用 NIO 构建可扩展和强大的服务器,
并提供扩展的框架组件:Web 框架 (HTTP/S)、WebSocket、Comet等!

grizzly stack

快速开始

本章将介绍客户端和服务器端如何开始使用Grizzly 2.3。
首先,有必要依靠正确的Grizzly 2.4 核心版本
Maven开发人员将需要向pom添加以下依赖项:

<dependency>
    <groupId>org.glassfish.grizzly</groupId>
    <artifactId>grizzly-framework</artifactId>
    <version>2.4.0</version>
</dependency>

所有的Grizzly Maven工件都部署在Maven Central存储库中。

让我们实现简单的Echo客户端-服务器应用程序。客户端将从标准输入中获取用户数据,将数据发送到Echo服务器,并将服务器的响应重定向到标准输出。Echo服务器的职责是从网络通道读取数据,并将相同的数据回显到通道。

服务器

创建回声过滤器(Echo filter)

首先,让我们实现回声过滤器(echo filter),该过滤器会将收到的消息(不考虑其类型)回显到 Grizzly Connection。

import java.io.IOException;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChain;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;

/**
 * Implementation of {@link FilterChain} filter, which replies with the request
 * message.
 */
public class EchoFilter extends BaseFilter {

    /**
     * Handle just read operation, when some message has come and ready to be
     * processed.
     *
     * @param ctx Context of {@link FilterChainContext} processing
     * @return the next action
     * @throws java.io.IOException
     */
    @Override
    public NextAction handleRead(FilterChainContext ctx)
            throws IOException {
        // Peer address is used for non-connected UDP Connection :)
        final Object peerAddress = ctx.getAddress();

        final Object message = ctx.getMessage();

        ctx.write(peerAddress, message, null);

        return ctx.getStopAction();
    }
}

服务器初始化代码

服务器的所有FilterChain块都已准备好-让我们初始化并启动服务器。

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;

/**
 * Class initializes and starts the echo server, based on Grizzly 2.3
 */
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 {
        // Create a FilterChain using FilterChainBuilder
        FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();

        // Add TransportFilter, which is responsible
        // for reading and writing data to the connection
        filterChainBuilder.add(new TransportFilter());

        // StringFilter is responsible for Buffer <-> String conversion
        filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));

        // EchoFilter is responsible for echoing received messages
        filterChainBuilder.add(new EchoFilter());

        // Create TCP transport
        final TCPNIOTransport transport =
                TCPNIOTransportBuilder.newInstance().build();

        transport.setProcessor(filterChainBuilder.build());
        try {
            // binding transport to start listen on certain host and port
            transport.bind(HOST, PORT);

            // start the transport
            transport.start();

            logger.info("Press any key to stop the server...");
            System.in.read();
        } finally {
            logger.info("Stopping transport...");
            // stop the transport
            transport.shutdownNow();

            logger.info("Stopped transport...");
        }
    }
}
运行回显服务器(Echo Server)

正如我们在上面的代码中看到的那样,EchoServer类声明了main方法,使用IDE运行 main 方法。

客户

创建客户端过滤器

客户端过滤器负责将服务器响应重定向到标准输出。请注意,ClientFilter要求FilterChainContext消息为java.lang.String(第21行),
因此它依赖于StringFilter在FilterChain中位于它之前。

import java.io.IOException;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;

/**
 * Client filter is responsible for redirecting server response to the standard output
 */
public class ClientFilter extends BaseFilter {
    /**
     * Handle just read operation, when some message has come and ready to be
     * processed.
     *
     * @param ctx Context of {@link FilterChainContext} processing
     * @return the next action
     * @throws java.io.IOException
     */
    @Override
    public NextAction handleRead(final FilterChainContext ctx) throws IOException {
        // We get String message from the context, because we rely prev. Filter in chain is StringFilter
        final String serverResponse = ctx.getMessage();
        System.out.println("Server echo: " + serverResponse);

        return ctx.getStopAction();
    }
}

客户端初始化代码

现在我们准备初始化客户端,包括FilterChain和Transport初始化。

Connection connection = null;

// Create a FilterChain using FilterChainBuilder
FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();

// Add TransportFilter, which is responsible
// for reading and writing data to the connection
filterChainBuilder.add(new TransportFilter());

// StringFilter is responsible for Buffer <-> String conversion
filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));

// ClientFilter is responsible for redirecting server responses to the standard output
filterChainBuilder.add(new ClientFilter());

// Create TCP transport
final TCPNIOTransport transport =
        TCPNIOTransportBuilder.newInstance().build();
transport.setProcessor(filterChainBuilder.build());
添加用户交互和客户端关闭代码

让我们通过添加逻辑来完成上面的代码,该逻辑从标准输入读取用户数据,将其发送到服务器,并在输入结束时执行客户端关闭。

   package com.huyouxiao.loquat;
   
   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 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;
   
   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;
   
           // Create a FilterChain using FilterChainBuilder
           FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless();
           // Add TransportFilter, which is responsible
           // for reading and writing data to the connection
           filterChainBuilder.add(new TransportFilter());
           // StringFilter is responsible for Buffer <-> String conversion
           filterChainBuilder.add(new StringFilter(Charset.forName("UTF-8")));
           // Client is responsible for redirecting server responses to the standard output
           filterChainBuilder.add(new ClientFilter());
   
           // Create TCP transport
           final TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build();
           transport.setProcessor(filterChainBuilder.build());
   
           try {
   
               // Start the transport
               transport.start();
   
               // perform async. connect to the server
               Future<Connection> future = transport.connect(EchoServer.HOST, EchoServer.PORT);
   
               // wait for connect operation to complete
               connection = future.get(10, TimeUnit.SECONDS);
   
               assert connection != null;
   
               logger.info("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 {
               // close the client connection
               if (connection != null) {
                   connection.close();
               }
   
               // stop the transport
               transport.shutdownNow();
           }
       }
   }
运行回显客户端

用 IDE 运行 EchoClient 的 main 方法。
或您最喜欢的IDE。
默认情况下,如果标准输入和输出未更改-您将在控制台上看到以下内容:

Ready... ("q" to exit)

现在客户端已准备好您的输入。每次键入一行并按键-该行将被发送到服务器,并且响应如下:

Ready... ("q" to exit)
Hey there!
Server echo: Hey there!

代码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值