nginx配置https及wss

本文详细介绍了如何在CentOS7环境下使用Nginx1.20.1和SpringBoot2.7.12集成WebSocket功能,包括SpringBootWebSocket配置、Maven依赖管理和Nginx的wss配置,以及处理微信小程序的WebSocket连接和心跳检测。

环境说明

服务器的是centos7

nginx版本nginx/1.20.1

springboot2.7.12

nginx安装教程点击这里

微信小程序wss配置

如果您的业务是开发微信小程序, 请先进行如下配置。

WX20240422-210531@2x.png

boot集成websocket

  • maven
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  • config配置文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

/**
 * @author mark
 * @description websocket配置
 * @date 2024-04-21
 */
@Configuration
public class WebSocketConfig {

    /**
     * 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     *
     * @return
     */

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    /**
     * 通信文本消息和二进制缓存区大小
     * 避免对接 第三方 报文过大时,Websocket 1009 错误
     * @return
     */

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        // 在此处设置bufferSize
        container.setMaxTextMessageBufferSize(10240000);
        container.setMaxBinaryMessageBufferSize(10240000);
        container.setMaxSessionIdleTimeout(15 * 60000L);
        return container;
    }
}
  • websocket业务核心代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author mark
 * ws://127.0.0.1:8768/jeecg-activiti-gateway/ws/playBack
 * wss://doc.zengzhang.vip:8768
 * @description 统计在线人数
 * @date 2024-04-21
 */
@Slf4j
@Component
@ServerEndpoint(value = "/ws/playBack")
public class WebSocketServerPlayBack {


    /**
     * 记录链接在线数量
     **/
    private static final AtomicInteger onlineCount = new AtomicInteger(0);


    /**
     * 存放每个客户端对应的 WebSocketServer 对象
     **/
    private static CopyOnWriteArraySet<WebSocketServerPlayBack> webSocketSet = new CopyOnWriteArraySet<>();


    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     **/
    private Session session;


    /**
     * 心跳报文
     **/
    private static final String HEARTBEAT_PACKETS = "The heartbeat packets";


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        // 加入set中
        webSocketSet.add(this);
        // 在线数加1
        onlineCount.getAndIncrement();

    }


    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        // 从set中删除
        webSocketSet.remove(this);
        // 在线数减1
        onlineCount.getAndDecrement();
    }

    /**
     * 发生错误时调用
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("[历史数据回放] - WS 异常断开", session, error);
    }


    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("--000--" + message);
        if (HEARTBEAT_PACKETS.equals(message)) {
            log.debug("[消息订阅] - 心跳.");
            return;
        }
        // TODO 接收前端入参后的业务处理

    }

    /**
     * 群发自定义消息
     */
    public static void sendInfo(String message) {
        for (WebSocketServerPlayBack item : webSocketSet) {
            try {

                item.sendMessage(message);
            } catch (IOException e) {
                log.error("[NVR 数据对接] - 数据推送异常, 数据: [{}].", message, e);
                continue;
            }
        }
    }


    /**
     * 指定会话推送
     *
     * @param message
     */
    public static void sendInfo(Session session, String message) {
        for (WebSocketServerPlayBack item : webSocketSet) {
            try {
                if (null != session && item.session.equals(session)) {
                    item.sendMessage(message);
                }

            } catch (IOException e) {
                log.error("[数据对接] - 数据推送异常, 数据: [{}].", message, e);
                continue;
            }
        }
    }

    /**
     * 向链接推送消息
     *
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        log.info("sendMessage:{}", message);
        this.session.getBasicRemote().sendText(message);
    }

}
  • SwaggerConfig权限放开
// 授权不需要登录权限的URL
.antMatchers("/swagger*/**",
        "/explain/**",
        "/file/**",
        //这个是webscoket所需的配置
        "/ws/**",
        "/push/**",
        "/v2/api-docs",
        "/webjars*//**").permitAll()

nginx配置

亲测可用,直接贴代码,大家可以直接拿来使用。

注意啦!!!你的域名需要在管理后台下载免费或付费的SSL证书。

upstream doc {
   server 127.0.0.1:8768 weight=1;
}
server {
    listen 443 ssl;
    server_name xxx.com
    listen 80;
    ssl on;
    # 将下载的ssl证书配置在这里
    ssl_certificate  /etc/nginx/conf.d/ssl/doc/doc.zengzhang.vip_bundle.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/doc/doc.zengzhang.vip.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;

    gzip on;
    gzip_min_length 3k;
    gzip_comp_level 9;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
    root /usr/share/nginx/html;


    location / {
        proxy_pass http://doc;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

配置好后,直接重启nginx。

命令是:systemctl restart nginx

接下来,敲黑版,重点来啦!!!

没有配置wss的情况下,我们是这样与服务器端建立连接。

ws://xxx.com:8768/jeecg-activiti-gateway/ws/playBack

配置了wss情况下, 我们建立连接的方式是这样的。

wss://xxx.com:443/jeecg-activiti-gateway/ws/playBack

客户端 由之前的请求地址 ws://www.xxx.com:8768 改为了 wss://www.xxxx.com:443

这个点,需要特别注意啦!!! 本人花费4个小时, 终于找到原因。

如果对您有帮助, 多多点赞啦啦啦…

也可以支持一下作者的网站哦, 点击下方链接。
JeecgFlow

### Nginx 配置 WSS (WebSocket Secure) 为了在 Nginx配置 WSSWebSocket Secure),需要确保 SSL/TLS 已经正确设置并启用。以下是详细的配置方法: #### 1. 启用 SSL 并监听 HTTPS 请求 Nginx 的 `server` 块中应包含 `listen 443 ssl;` 来启动 HTTPSWSS 支持。同时,指定证书文件路径以完成 SSL 配置。 ```nginx server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/cert.pem; # 替换为实际的证书路径 ssl_certificate_key /path/to/key.pem; # 替换为实际的私钥路径 ... } ``` 此部分配置用于加载 SSL 证书和密钥[^2]。 --- #### 2. 设置 WebSocket 协议升级 通过 `proxy_set_header` 指令来传递必要的 HTTP 头部字段,使客户端能够成功协商 WebSocket 握手过程中的协议升级。 ```nginx location /wssapp/ { proxy_pass http://backend_server; # 将请求转发到后端 WebSocket 服务 proxy_http_version 1.1; # 使用 HTTP/1.1 版本支持持久连接 proxy_set_header Upgrade $http_upgrade; # 转发 Upgrade 字段至后端 proxy_set_header Connection "upgrade"; # 修改 Connection 字段为 upgrade proxy_set_header Host $host; # 转发主机名给后端 } ``` 这些头部字段对于 WebSocket 握手至关重要,缺少它们可能导致握手失败[^3]。 --- #### 3. 映射 `$http_upgrade` 参数 为了让 Nginx 正确识别 WebSocket 请求,需定义一个映射变量 `$connection_upgrade`,它会根据 `$http_upgrade` 的值动态决定是否执行协议升级。 ```nginx http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { location /ws/ { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } } } ``` 这段代码片段允许 Nginx 自动检测并适配 WebSocket 请求[^5]。 --- #### 4. 解决常见问题 - **连接立即关闭**:检查 Nginx 和后端服务器之间的超时时间设置,适当增加 `proxy_read_timeout` 或其他相关参数。 - **无法建立连接**:验证 `Upgrade` 和 `Connection` 头部已正确定义,并且后端服务正常工作。 - **性能优化**:调整缓冲区大小 (`proxy_buffer_size`) 和缓存策略以提高效率[^3]。 --- #### 5. 推荐最佳实践 - 对于生产环境,建议始终使用 WSS 而非 WS,从而保障数据传输的安全性。 - 创建独立的 `location` 块专门服务于 WebSocket 流量,减少与其他流量的竞争。 - 实施速率限制或最大并发连接控制,防止资源耗尽。 --- ### 示例完整配置 以下是一个完整的 Nginx 配置实例,适用于 WSS 场景: ```nginx http { map $http_upgrade $connection_upgrade { default upgrade; '' close; } upstream websocket_backend { server backend_server_ip:port; } server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; location /wss/ { proxy_pass http://websocket_backend/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_read_timeout 86400; # 提高读取超时时间 } } } ``` 以上配置展示了如何将前端用户的 WSS 请求安全地转发到后端 WebSocket 服务[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值