nginx配置https及wss

环境说明

服务器的是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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/570099.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

APP UI自动化测试,思路全总结在这里了

首先想要说明一下&#xff0c;APP自动化测试可能很多公司不用&#xff0c;但也是大部分自动化测试工程师、高级测试工程师岗位招聘信息上要求的&#xff0c;所以为了更好的待遇&#xff0c;我们还是需要花时间去掌握的&#xff0c;毕竟谁也不会跟钱过不去。 接下来&#xff0c…

Microsoft Edge:探索你可能未充分利用的8个实用功能

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

实时数据同步工具的真正作用和对应应用场景

在当今商业环境中&#xff0c;企业规模的不断扩大带来了对数据同步的更高要求。实时数据同步解决方案对于确保数据的一致性、提升业务灵活性以及增强决策的精准度具有关键作用。 本文将深入分析实时数据同步技术的关键优势&#xff0c;并探讨其在不同行业场景下的应用价值&…

复习python函数

复习python函数 1.对函数的理解函数的传递方式返回值 return可通过help()函数查看函数说明作用域 2.不定长参数3.递归4.高阶函数将函数作为参数传递将函数作为返回值返回 5.匿名函数6.装饰器 1.对函数的理解 函数可以用来保存一些可执行的代码&#xff0c;并且可以在需要时&am…

前端Vue中async/await、promise 和setTimeout工作原理和执行顺序

前端Vue中async/await、Promise 和 setTimeout 在 JavaScript 中都是处理异步操作的方法&#xff0c;但它们的工作原理和执行顺序有所不同。以下是它们的执行顺序和关系的简要说明&#xff1a; 同步代码执行&#xff1a;在任何异步操作开始之前&#xff0c;首先会执行所有的同步…

vr太阳光参数怎么设置,vr快速渲染方法

VR场景中实现逼真的光照效果&#xff0c;太阳光参数的设置尤为关键。真实的太阳光可提升效果图的质感&#xff0c;论VR太阳光参数的设置技巧&#xff0c;包括光源类型选择、光照强度调整、阴影效果优化等多个方面&#xff0c;喜爱一起来看看vr太阳光真实感设置参数吧。 vr太阳光…

大数据信用风险竟然是这样形成的!查询方法也很简单

在大数据时代背景下&#xff0c;大数据信用风险成为了众多机构关注的焦点。这类风险涵盖了多头借贷、履约行为、联系人以及司法等多个方面。本文将深入解析大数据信用风险的形成原因及其查询方法&#xff0c;让我们一起来探索一下。 大数据信用风险主要表现在以下几个方面&…

Python-GEE遥感云大数据分析、管理与可视化

原文链接&#xff1a;Python-GEE遥感云大数据分析、管理与可视化https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601238&idx2&sn6b0557cf61451eaff65f025d648da869&chksmfa820db1cdf584a76de953b96519704177e6206d4ecd47a2f2fabbcac2f7ea619b0bce184…

Ubuntu镜像下载与安装2024.4版本(超适合新手)

前言&#xff1a; 在VMware中安装Ubuntu镜像&#xff0c;首先需要去下载镜像&#xff0c;但是由于服务器在国外&#xff0c;下载速度相对较慢&#xff0c;国内也有镜像&#xff0c;较推荐在国内镜像站下载&#xff0c;例如阿里镜像和清华镜像。 官网&#xff1a;Ubuntu系统下…

华为 2024 届实习校园招聘-硬件通⽤/单板开发——第八套

华为 2024 届实习校园招聘-硬件通⽤/单板开发——第八套 部分题目分享&#xff0c;完整版带答案(有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&#xff09;&#xff08;共十套&#xff09;获取&#xff08;WX:didadidadidida313&#xff0c…

hover显示播放遮罩层效果

我们都知道视频列表其实是一个封面列表,鼠标放上去时,有反馈:即hover时显示播放遮罩层,点击,跳转到对应的视频播放页。这是目前主流视频网站的一个通用效果。 我们在实现时应该理清思路: 1、每个视频位置处放的是封面图片 2、播放按钮遮罩层需完全覆盖封面图片,并且正…

vLLM-prefix浅析(System Prompt,大模型推理加速)

原文&#xff1a;vLLM-prefix浅析&#xff08;System Prompt&#xff0c;大模型推理加速&#xff09; 简介 本文浅析了在大模型推理加速方面一个非常优秀的项目 vLLM 的一个新特性 Prefix。在 Prompt 中有相同前缀时可以提高吞吐量降低延迟&#xff0c;换句话说可以省去这部分…

【做算法学数据结构】二叉树的层序遍历【二叉树】

文章目录 题目二叉树二叉树描述二叉树的java描述和前序遍历、后序遍历、中序遍历 题解总结以及二叉树应用场景 题目 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历…

德思特GNSS模拟器为物流行业保驾护航

作者介绍 一、前言 德思特GNSS模拟器能够在最短的时间内高效、准确的协助完成虹科MSR运输数据记录仪的定位准确性以及抗干扰能力测试&#xff0c;确保在运输或存储过程中&#xff0c;让用户知道何时何地发生了超出预设公差范围的事件&#xff0c;快速、准确的记录定位数据&…

【UE 材质】水波纹效果

效果 模拟雨水打落在水面上的效果 步骤 1. 下载所需纹理和纹理 纹理2. 新建一个材质&#xff0c;这里命名为“M_WaterRipples” 打开“M_WaterRipples”&#xff0c;添加一个纹理采样节点&#xff0c;纹理使用第一步下载的纹理 将纹理采样节点的R通道连接到基础颜色&#x…

李沐57_长短期记忆网络LSTM——自学笔记

LSTM 1.忘记门&#xff1a;将值朝着0减少 2.输入门&#xff1a;决定不是忽略掉输入数据 3.输出门&#xff1a;决定是不是使用隐状态 !pip install --upgrade d2l0.17.5 #d2l需要更新首先加载时光机器数据集。 import torch from torch import nn from d2l import torch a…

Ajax和axios基础

AJAX Asynchronous JavaScript And XML 异步的JavaScript和XML 作用 数据交换: 通过Ajax可以给服务器发送请求,服务器将数据直接响应回给浏览器. 异步交互: 可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术. 同步和异步 同步发送请求: 浏览器发…

阿斯达年代记账号注册教程 阿斯达年代记苹果id注册教程

阿斯达年代记账号注册教程 阿斯达年代记苹果id注册教程 即将开服的新款大型多人角色扮演类游戏阿斯达年代记三强争霸将于4月24号上线&#xff0c;小伙伴们可以在本次开服之后进行游戏&#xff0c;这款游戏除了常规的职业分化之外&#xff0c;目前开放了四种角色供玩家选择&…

getopt, getopt_long使用笔记

An element of argv that starts with - (and is not exactly "-" or "--") is an option element. The characters of this element (aside from the initial -) are option characters. 以-’开头的字符(注意!不是字符串!!)就是命令行参数选项 通…

C++中的程序流程结构

一、选择结构 1.1 if语句 作用&#xff1a;执行满足条件的语句 if语句的三种形式 单行格式if语句多行格式if语句多条件的if语句 #include <iostream> using namespace std;int main(){//选择结构 单行if语句//用户输入分数&#xff0c;如果分数>600,视为考上一本大…
最新文章