栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Netty:创建WebSocket服务器和客户端

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Netty:创建WebSocket服务器和客户端

一、有点复杂的方式,自己处理协议升级、握手等信息
1.创建ServerHandler

package cn.edu.tju;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.*;

public class MyWebSocketServerHandler extends SimpleChannelInboundHandler {
    private WebSocketServerHandshaker handshaker;
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if(msg instanceof FullHttpRequest){
            handleHttpRequest(ctx,(FullHttpRequest)msg);
        }
        else if(msg instanceof WebSocketframe){
            handleWebSocketframe(ctx,(WebSocketframe)msg);
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception{
        ctx.flush();
    }

    private void handleHttpRequest(ChannelHandlerContext ctx,FullHttpRequest req) throws Exception{
        if(!req.getDecoderResult().isSuccess()||(!"websocket".equals(req.headers().get("Upgrade")))){
            return;
        }
        WebSocketServerHandshakerFactory wsFactory=new WebSocketServerHandshakerFactory("ws://localhost:1234/websocket",null,false);
        handshaker=wsFactory.newHandshaker(req);
        if(handshaker==null){
            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
        }
        else{
            handshaker.handshake(ctx.channel(),req);
        }
    }
    private void handleWebSocketframe(ChannelHandlerContext ctx,WebSocketframe webSocketframe){
        if(webSocketframe instanceof CloseWebSocketframe){
            handshaker.close(ctx.channel(),(CloseWebSocketframe)webSocketframe.retain());
            return;
        }
        if(webSocketframe instanceof PingWebSocketframe){
            ctx.channel().write(new PongWebSocketframe(webSocketframe.content().retain()));
            return;
        }

        String request=((TextWebSocketframe)webSocketframe).text();
        System.out.println(ctx.channel()+" received: "+request);
        ctx.channel().writeAndFlush(new TextWebSocketframe(new java.util.Date().toLocaleString()));
    }
}

 

2.创建WebSocket服务器:

package cn.edu.tju;


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.*;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;

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

        try{
            ServerBootstrap serverBootstrap=new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childHandler(new ChannelInitializer() {

                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline channelPipeline=socketChannel.pipeline();
                    channelPipeline.addLast(new HttpServerCodec());
                    channelPipeline.addLast(new HttpObjectAggregator(65536));
                    channelPipeline.addLast(new ChunkedWriteHandler());
                    channelPipeline.addLast(new MyWebSocketServerHandler());

                }
            });
            ChannelFuture channelFuture=serverBootstrap.bind(1234).sync();
            channelFuture.channel().closeFuture().sync();

        }catch (Exception ex){
            System.out.println(ex.getMessage());
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

二、更简便的方式,使用WebSocketServerProtocolHandler:
1.创建ServerHandler

package cn.edu.tju;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketframe;

import java.time.LocalDateTime;

public class MyWebSocketServerHandler2 extends SimpleChannelInboundHandler {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketframe msg) throws Exception {
        Channel channel = ctx.channel();
        System.out.println(channel.remoteAddress() + ": " + msg.text());
        ctx.channel().writeAndFlush(new TextWebSocketframe("来自服务端: " + LocalDateTime.now()));
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("ChannelId:" + ctx.channel().id().asLongText());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("用户下线: " + ctx.channel().id().asLongText());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }
}

2.创建WebSocket服务器:

package cn.edu.tju;


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.*;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

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

        try{
            ServerBootstrap serverBootstrap=new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.handler(new LoggingHandler(LogLevel.INFO));
            serverBootstrap.childHandler(new ChannelInitializer() {

                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline channelPipeline=socketChannel.pipeline();
                    channelPipeline.addLast(new HttpServerCodec());
                    channelPipeline.addLast(new ChunkedWriteHandler());
                    channelPipeline.addLast(new HttpObjectAggregator(8192));
                    channelPipeline.addLast(new WebSocketServerProtocolHandler("/websocket"));
                    channelPipeline.addLast(new MyWebSocketServerHandler2());

                }
            });
            ChannelFuture channelFuture=serverBootstrap.bind(1234).sync();
            channelFuture.channel().closeFuture().sync();

        }catch (Exception ex){
            System.out.println(ex.getMessage());
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

三、连接WebSocket的html




    WebSocket Demo





转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号