IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Netty 专栏——Http 服务与 WebSocket长连接 -> 正文阅读

[网络协议]Netty 专栏——Http 服务与 WebSocket长连接

一、Http 服务

1、项目需求

1)服务器监听8001端口,浏览器发送请求 http://localhost:8001
2)服务器可以回复消息给客户端 “Hello 我是服务器”,并对特定请求资源进行过滤

2、案例代码

2.1、Service

public class HttpService {
    public static void main(String[] args) throws Exception {

        /*create BossGroup and WorkerGroup*/
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try{
            /*create server serverBootstrap*/
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new HttpServiceInitializer());
            ChannelFuture channelFuture = serverBootstrap.bind(8001).sync();
            channelFuture.channel().closeFuture().sync();

        }finally{
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
}

2.2、ServiceInitializer

public class HttpServiceInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        /*gain pipeline*/
        ChannelPipeline pipeline = ch.pipeline();
        /*add http server codec(coder and decoder*/
        /*Http Server Codec is and coder and decoder which supported by netty
				* it used to tackle the encode and decode task of http request and http response
				* */
        pipeline.addLast("MyHttpServerCodec",new HttpServerCodec());
        /*add a customize handler*/
        pipeline.addLast("MyHttpServiceHandler", new HttpServiceHandler());

    }
}

2.3、ServiceHandler

/**
	* @author 彭友聪
	* SimpleChannelInboundHandler is child class of ChannelInboundAdapter
	* HttpObject is Encapsulation for the data of communication between server side and client side
	*/
public class HttpServiceHandler extends SimpleChannelInboundHandler<HttpObject> {
    /**
			* this is method used to read the data come from client side
			* @param ctx context of channel
			* @param msg message from client
			* @throws Exception exception
			*/
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        /*verified the msg whether is http request or not*/
        if(msg instanceof HttpRequest){
            System.out.println("msg type= " + msg.getClass());
            System.out.println("client address: " + ctx.channel().remoteAddress());
            /*reply information to client, the reply data must use http protocol to encapsulation*/
            ByteBuf content = Unpooled.copiedBuffer("Hello I am Server side",
                                                    CharsetUtil.UTF_8);
            /*build a http response*/
            FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
                                                                    HttpResponseStatus.OK, content);
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
            /*sent the response*/
            ctx.writeAndFlush(response);
        }
    }
}

2.4、请求过滤

/*gain header of client request*/
HttpRequest httpRequest = (HttpRequest) msg;
/*get uri*/
URI uri = new URI(httpRequest.uri());
String path = "/favicon.ico";
if(path.equals(uri.getPath())){
    System.out.println("Client has request favicon.ico, not response");
    return;
}

在 ServiceHandler 的channelRead0 方法里添加上述代码段,就可以对特定的请求进行过滤,不做响应。

二、WebSocket 长连接

1、案例要求

1)基于WebSocket 实现长连接的全双工交互
2)改变 http 协议多次请求的约束,实现长连接,服务器可以发送消息
3)客户端和服务器端可以相互感知,如服务器关闭了,浏览器会感知;浏览器关闭了,服务器端同样会感知

2、案例代码

2.1、Server

public class Server {
    public static void main(String[] args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                /*add a log handler*/
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(
                new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        /*tackle http data which is a data block type*/
                        pipeline.addLast(new ChunkedWriteHandler());
                        /*the follow handler can to aggregate(combine) different segment
                   * of the same http data
                   * */
                        pipeline.addLast(new HttpObjectAggregator(8192));
                        /* the data of websocket sent or gain in the way that used one type called frame
                  * so that we must use the follow handler to tackle
                  * in browser we should use the usi: ws://localhost:8001/hello to request server to support
                  * its service
                  * WebSocketServerProtocolHandler can upgrade the http protocol into websocket protocol
                  * so that we can achieve long connect
                  * */
                        pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));
                        /*
                  * add ourselves' handler of tackle request from browser and handle task of request
                  * */
                        pipeline.addLast(new MyWebsocketHandler());
                    }
                });
            ChannelFuture future = bootstrap.bind(8001).sync();
            future.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

2.2、ServerHandler

public class MyWebsocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)
        throws Exception {
        System.out.println("received msg: " + msg.text());
        ctx.channel().writeAndFlush(new TextWebSocketFrame("server time: " +
                                                           LocalDateTime.now() + msg.text()));
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        /*use id().asLongText we can get the Uniquely Identifies of current websocket */
        System.out.println(ctx.channel().remoteAddress() + "上线, id=[" +
                           ctx.channel().id().asLongText() + "]");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "下线, id=[" +
                           ctx.channel().id().asLongText() + "]");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("Exception= " + cause.getMessage());
        ctx.close();
    }
}

2.3、Client

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocketClient</title>
</head>
<body>
<script>
    let socket;
    /*Judging current browser whether is support websocket or not*/
    if(window.WebSocket){
        socket = new WebSocket("ws://localhost:8001/hello");
        /*onmessage like read channel, can receive the msg form server*/
        socket.onmessage = function (event){
            let rt = document.getElementById(`responseText`);
            rt.value = rt.value + "\n" + event.data + "\n";
        }
        socket.onopen = function (event) {
            let rt = document.getElementById(`responseText`);
            rt.value = "connect startup !!\n";
        }
        socket.onclose = function (event) {
            let rt = document.getElementById(`responseText`);
            rt.value = rt.value +  "connect shutdown !!\n";
        }
    }else{
        alert("Sorry, your browser is not support websocket");
    }
    function send(message) {
        if(socket.readyState === WebSocket.CLOSED){
            alert("Websocket has closed!!");
            return;
        } 
      if(socket.readyState === WebSocket.OPEN){
            socket.send(message);
        }else{
            alert("websocket connect has not been built");
        }
    }
</script>
<form onsubmit="return false">
    <label>
        <textarea name="msg" style="height: 300px; width: 300px"></textarea>
    </label>
    <input type="button" value="sent" onclick="send(this.form.msg.value)">
    <label for="responseText">服务器回复:</label>
    <textarea id="responseText" style="height: 300px; width: 300px"></textarea>
    <input type="button" value="清空内容"
           onclick="document.getElementById('responseText').value=''">
</form>
</body>
</html>

2.4、测试

在这里插入图片描述

在这里插入图片描述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-26 22:36:04  更:2021-12-26 22:37:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:55:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码