netty-写websocket从ws到wss升级

1 篇文章 0 订阅
1 篇文章 0 订阅

本文描述将使用netty搭建的websokcet服务升级为支持https的wss协议
本文通过2种方式实现
1依赖jdk提供的jks
2依赖签名证书.crt,.key文件实现

JKS

1生成秘钥

keytool -genkey -keysize 2048 -validity 365 -keyalg RSA -keypass netty123 -storepass netty123 -keystore wss.jks

2写一个工具类 构造SSLContext 对象

package com.iptv.rtc.server.netty;

import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;

/**
 * @author tq
 * @version V1.0
 * @Package com.iptv.rtc.server.netty
 * @date 2021-04-01 15:49
 * @Copyright © 2018-2019 *******
 */
public class SslUtil {

    public static SSLContext createSSLContext(String type , String path , String password) throws Exception {
        KeyStore ks = KeyStore.getInstance(type); /// "JKS"
        InputStream ksInputStream = new FileInputStream(path); /// 证书存放地址
        ks.load(ksInputStream, password.toCharArray());
        //KeyManagerFactory充当基于密钥内容源的密钥管理器的工厂。
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//getDefaultAlgorithm:获取默认的 KeyManagerFactory 算法名称。
        kmf.init(ks, password.toCharArray());
        //SSLContext的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, null);
        return sslContext;
    }


}

3将handler放置整个流程第一位

package com.iptv.rtc.server.netty;

import com.iptv.rtc.server.handler.ChatHandler;
import com.iptv.rtc.server.handler.HeartBeatHandler;
import com.iptv.rtc.server.handler.RTCHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
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.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

public class ServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline=socketChannel.pipeline();


        SSLContext sslContext = SslUtil.createSSLContext("JKS","/home/iptv/Documents/csr/server.csr","netty123");
        //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
        SSLEngine engine = sslContext.createSSLEngine();
        engine.setUseClientMode(false);
        engine.setNeedClientAuth(false);


        pipeline.addLast(new SslHandler(engine));

        pipeline.addLast(new HttpServerCodec());
        //对大数据流支持
        pipeline.addLast(new ChunkedWriteHandler());
        //添加对http request和response的支持
        pipeline.addLast(new HttpObjectAggregator(1024*64));

        //添加ws路由 以及对websocket的 握手 心跳等动作的支持
        pipeline.addLast(new WebSocketServerProtocolHandler("/im"));


        //自定义handler

        pipeline.addLast(new RTCHandler());

        //处理心跳断开
       // pipeline.addLast(new HeartBeatHandler());
    }
}

SSL双向验证

1首先准备好证书以及秘钥文件

server.crt证书文件
server.key秘钥文件

2工具类构造SslContext对象

package com.iptv.rtc.server.netty;

import io.netty.handler.ssl.ClientAuth;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;

/**
 * @author tq
 * @version V1.0
 * @Package com.iptv.rtc.server.netty
 * @date 2021-04-01 15:49
 * @Copyright © 2018-2019 *******
 */
public class SslUtil {

    private static final File keyFile = new File("/home/iptv/Documents/csr/server.key");
    private static final File rootFile = new File("/home/iptv/Documents/csr/server.crt");

    public static SslContext createSSLContext() throws Exception {
        SslContext sslCtx = SslContextBuilder.forServer(rootFile, keyFile).clientAuth(ClientAuth.NONE).build();
        return sslCtx;
    }
 }

3添加到流程中的第一位

package com.iptv.rtc.server.netty;

import com.iptv.rtc.server.handler.ChatHandler;
import com.iptv.rtc.server.handler.HeartBeatHandler;
import com.iptv.rtc.server.handler.RTCHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
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.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

public class ServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline=socketChannel.pipeline();


        SslContext sslCtx =SslUtil.createSSLContext();
        pipeline.addLast(sslCtx.newHandler(socketChannel.alloc()));
        
        pipeline.addLast(new HttpServerCodec());
        //对大数据流支持
        pipeline.addLast(new ChunkedWriteHandler());
        //添加对http request和response的支持
        pipeline.addLast(new HttpObjectAggregator(1024*64));

        //添加ws路由 以及对websocket的 握手 心跳等动作的支持
        pipeline.addLast(new WebSocketServerProtocolHandler("/im"));


        //自定义handler

        pipeline.addLast(new RTCHandler());

        //处理心跳断开
       // pipeline.addLast(new HeartBeatHandler());
    }
}

有什么问题请大家提出,谢谢
参考:
JKS
https://blog.csdn.net/invadersf/article/details/80337380
https://blog.csdn.net/tiandao321/article/details/91373952
SSL双向
https://segmentfault.com/a/1190000010040134

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值