netty websocket demo

测试ui

 

环境:

<dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.20.Final</version>
</dependency>

jdk8

Server.java
package com.lhh.demo.netty.websocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import java.time.LocalDateTime;

public class Server {


    public static void main(String[] args) {
        NioEventLoopGroup boos = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        try {

            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boos,worker)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();

                            //http协议;使用http的编解码器
                            pipeline.addLast(new HttpServerCodec());
                            //http 是以块的方式写,需要ChunkedWriteHandler处理
                            pipeline.addLast(new ChunkedWriteHandler());
                            //http在传输过程中是可以分段的,HttpObjectAggregator可以把多个段合并
                            //http发送post请求,如果数据过大会分段,就会发送多次http请求
                            pipeline.addLast(new HttpObjectAggregator(8192));
                            //webSocket是以桢(frame)的形式传递数据
                            //WebSocketFrame有6个子类(TextWebSocketFrame 会用到)
                            //浏览器请求时: ws://localhost:8888/hello  这是请求的uri
                            //WebSocketServerProtocolHandler核心功能http协议升级为webSocket协议 长链接
                            pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));

                            //自定义handler
                            pipeline.addLast(new MyHandler());
                        }
                    });

            ChannelFuture sync = bootstrap.bind(8888).sync();
            sync.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            boos.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }

    //这里 TextWebSocketFrame 表示一个文本桢 frame
    static class MyHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            System.out.println("服务器收到消息:"+msg.text());

            String respMsg = "服务器时间:"+LocalDateTime.now()+";"+msg.text();

            ctx.writeAndFlush(new TextWebSocketFrame(respMsg));
        }

        //客户端链接触发
        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            //asLongText 唯一,asShortText 非唯一
            System.out.println("handlerAdded asLongText"+ctx.channel().id().asLongText());
            System.out.println("handlerAdded asShortText"+ctx.channel().id().asShortText());
            //super.handlerAdded(ctx);
        }

        //客户端退出触发
        @Override
        public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
            //asLongText 唯一,asShortText 非唯一
            System.out.println("handlerRemoved asLongText"+ctx.channel().id().asLongText());
            System.out.println("handlerRemoved asShortText"+ctx.channel().id().asShortText());
            //super.handlerRemoved(ctx);
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            System.out.println("异常发生"+cause.getMessage());
            //super.exceptionCaught(ctx, cause);
            ctx.close();
        }
    }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<script>
    var socket;
    if(window.WebSocket){
        socket = new WebSocket("ws://localhost:8888/hello");
        //可以收到服务器端发送的消息
        socket.onmessage = function(p1){
            var rt = document.getElementById('responseTxt');
            rt.value = rt.value + "\n" + p1.data+"\n";
        };
        //链接成功
        socket.onopen = function(p1){
            var rt = document.getElementById('responseTxt');
            rt.value = "链接开启\n";
        };

        //链接关闭
        socket.onclose = function(p1){
            var rt = document.getElementById('responseTxt');
            rt.value = rt.value+"链接关闭了\n";
        };
    }else{
        alert("当前浏览器不支持websocket");
    }

    //发送消息
    function send(){
        var msg = document.getElementById("msg").value;

        if(!window.socket){
            return;
        }
        if(socket.readyState == WebSocket.OPEN){
            socket.send(msg);
        }else{
            alert("链接没有打开");
        }


    }
</script>
<body>
    <form onsubmit="return false" >
        <textarea id = "msg" name = "message" style="height: 300px;width: 300px"></textarea>
        <input type="button" value="发送消息" onclick="send()" >

        <textarea id = "responseTxt" style="height: 300px;width: 300px"></textarea>
        <input type="button" value="情况内容"
               onclick="document.getElementById('responseTxt').value = ''" >
    </form>

</body>

</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值