欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 服务器中使用wss协议连接websocket(基于netty)

服务器中使用wss协议连接websocket(基于netty)

2024/10/25 1:21:24 来源:https://blog.csdn.net/a1308003218/article/details/142916068  浏览:    关键词:服务器中使用wss协议连接websocket(基于netty)

前置条件:可用的SSL证书

需要两个文件,key格式的还有pem格式的

如果是阿里云证书,下面Nginx类型的就可以

快捷转移——数字证书管理服务管理控制台 (aliyun.com)

在这里插入图片描述

自建证书

以管理员形式打开cmd窗口,如果提示keytool不存在,将目录定位到java安装目录的bin下方。

1、生成证书

keytool -genkey -alias myalias -keyalg RSA -keysize 2048 -keystore mykeystore.jks -validity 365

2、jks证书转化为pem格式

keytool -export -alias myalias -keystore mykeystore.jks -rfc -file certificate.pem

3、导出私钥

keytool -importkeystore -srckeystore mykeystore.jks -destkeystore temp.p12 -srcalias myalias -deststoretype PKCS12 -srcstorepass <keystore_password> -deststorepass <p12_password>

4、提取私钥

openssl pkcs12 -in temp.p12 -nocerts -nodes -out private_key.pem

这种方式得到两个接下来要用到的文件

① certificate.pem

② private_key.pem

阿里云证书的方式直接下载得到的是key和pem,需要将key转化为私钥

执行openssl rsa -in old_server_key.pem -out private_key.pem

这样也得到了上述两个文件

接下来使用netty搭建简易websocket服务器

@Configuration
@Slf4j
public class NettyWebSocketServer {private final static int WEB_SOCKET_PORT = 9090;private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);private final EventLoopGroup workerGroup = new NioEventLoopGroup(NettyRuntime.availableProcessors());@PostConstructpublic void start() throws Exception {run();}@PreDestroypublic void destroy() {Future<?> future = bossGroup.shutdownGracefully();Future<?> future1 = workerGroup.shutdownGracefully();future.syncUninterruptibly();future1.syncUninterruptibly();log.info("关闭 ws server 成功");}public void run() throws Exception {ServerBootstrap serverBootstrap = new ServerBootstrap();SslContext sslContext = SslContextBuilder.forServer(getCertPem(), getCertKey()).build();serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_KEEPALIVE, true).handler(new LoggingHandler(LogLevel.INFO)) // 为 bossGroup 添加 日志处理器.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();// 注意将SSL必须是第一个处理器pipeline.addLast(sslContext.newHandler(socketChannel.alloc()));//30秒客户端没有向服务器发送心跳则关闭连接pipeline.addLast(new IdleStateHandler(30, 0, 0));// 因为使用http协议,所以需要使用http的编码器,解码器pipeline.addLast(new HttpServerCodec());// 以块方式写,添加 chunkedWriter 处理器pipeline.addLast(new ChunkedWriteHandler());/*** 说明:*  1. http数据在传输过程中是分段的,HttpObjectAggregator可以把多个段聚合起来;*  2. 这就是为什么当浏览器发送大量数据时,就会发出多次 http请求的原因*/pipeline.addLast(new HttpObjectAggregator(8192));//保存用户ippipeline.addLast(new HttpHeadersHandler());/*** */pipeline.addLast(new WebSocketServerProtocolHandler("/"));}});// 启动服务器,监听端口,阻塞直到启动成功serverBootstrap.bind(WEB_SOCKET_PORT).sync();log.info("netty在{}启动成功", WEB_SOCKET_PORT);}private InputStream getCertPem() {ClassPathResource classPathResource = new ClassPathResource("certificate.pem");return classPathResource.getStream();}private InputStream getCertKey() {ClassPathResource classPathResource = new ClassPathResource("private_key.pem");return classPathResource.getStream();}}

然后加成jar包放到服务器上启动。

配置nginx反向代理

server{listen 443 ssl;server_name your-server-name; # 填写①ssl_certificate certificate.pem; # 填写路径②ssl_certificate_key private_key.pem; # 填好路径③ssl_session_timeout 5m;root /www/wwwroot; # 自行配置charset utf-8;location /netty{proxy_pass https://your-address-url:9090/; # 填写④ 不能是9090 必须是9090/proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade";rewrite "^/netty/(.*)$" /$1 break;}
}

测试 wss://your-server-name/netty 可以连接成功

常见错误

1、io.netty.handler.ssl.NotSslRecordException: not an SSL/TLS record

错误说明没有使用SSL/TLS

导致的原因可能是:

① 使用了ws协议连接

② nginx转发的时候使用了http,需要使用https

2、wss Received fatal alert: certificate_unknown

错误说明证书未知

导致的原因可能是:

① 证书错误、不被信任

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com