运维相关(一) - Vue项目配置WebSocket连接{ws、wss 连接方式}

这篇具有很好参考价值的文章主要介绍了运维相关(一) - Vue项目配置WebSocket连接{ws、wss 连接方式}。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 写作背景

  • 项目使用的是ruoyi的前后端分离框架
  • 项目需要使用到 websocket , 在本地使用 ws 连接方式是没问题 , 但是服务器上边使用的是nginx + ssl 证书 https域名访问的方式部署的 使用普通的 ws 连接是不可以成功的 需要使用 wss的方式

2. 晒出代码

2.1 前端 vue.config.js 的代码

  • 这里target: 里边指向的都是后端server的地址 16000是我后端服务的端口 , 我这里websocket服务和普通的业务项目用的都是一个项目 所以都是16000端口

  devServer: {
    host: '0.0.0.0',
    port: port,
    open: true,
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      // 正常的 http 请求代理
      [process.env.VUE_APP_BASE_API]: {
        target: `http://localhost:16000`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      },
      // websocket ws 的代理路由配置
      [process.env.VUE_APP_WEBSOCKET_API]: {
        target: `ws://localhost:16000`,
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_WEBSOCKET_API]: ''
        }
      },
      // websocket wss 的代理路由配置
      [process.env.VUE_APP_WSS_WEBSOCKET_API]: {
        target: `wss://域名:16000`,
        changeOrigin: true,
        ws: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_WSS_WEBSOCKET_API]: ''
        }
      }
    },
    disableHostCheck: true
  },

2.2 Vue项目路由配置代码

  • 为什么要配置两个地址呢? , 因为在本次测试的时候使用的是普通的ws方式连接 所以为了方便切换就写了两个websocket代理路由

  • .env.development 文件和 .env.production 文件都加上这两行代码即可
//  WebSocket地址
VUE_APP_WEBSOCKET_API = '/websocket-api'
// WebSocket wss 地址
VUE_APP_WSS_WEBSOCKET_API = '/wss-websocket-api'

3.3 服务器Nginx配置

server {
		add_header X-Frame-Options ALLOWALL;
        listen       8681 ssl;
		server_name 域名; #需要将yourdomain.com替换成证书绑定的域名。
		root ..\html;
		index index.html index.htm;
		ssl_certificate pem文件地址;  #需要将cert-file-name.pem替换成已上传的证书文件的名称。
		ssl_certificate_key文件地址; #需要将cert-file-name.key替换成已上传的证书私钥文件的名称。
		ssl_session_timeout 6m;
		ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
		ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
		ssl_prefer_server_ciphers on;
        #charset koi8-r;

        access_log  logs/host.access.log  main;

		#默认目录
		location / {
            root   C:/xxx/dist;
            index  index.html;
			try_files $uri $uri/ @router;
        }
		location @router {
            rewrite ^.*$ /index.html last;
        }

		#vue二级目录代理
		location /admin {
            alias /root/www/admin;
			index  index.html;
            try_files $uri $uri/ /index.html last;
        }

		location /prod-api {
		 	rewrite  ^/prod-api/(.*)$ /$1 break;
			proxy_pass http://localhost:16000;
			proxy_set_header Host $host;
			add_header X-Frame-Options ALLOWALL;
			proxy_set_header User-Agent $http_user_agent;
			proxy_set_header X-Real-IP $remote_addr;
			proxy_set_header X-Forwarded-For $remote_addr;
			proxy_set_header authorization $http_authorization;
		}
		# websocket  wss 连接方式的路由代理配置
		location /wss-websocket-api {
			 rewrite  ^/wss-websocket-api/(.*)$ /$1 break;
			 proxy_pass http://localhost:16000;        #通过配置端口指向部署websocker的项目
			 proxy_http_version 1.1;
			 proxy_set_header Upgrade $http_upgrade;    
			 proxy_set_header Connection "Upgrade";    
			 proxy_set_header X-real-ip $remote_addr;
			 proxy_set_header X-Forwarded-For $remote_addr;
		 }
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }

3. 使用方式

3.1 前端代码

// 当前浏览器Location对象
const nowLocation = window.location;
// 协议 => http、https
const protocol = nowLocation.protocol;
// hostName => ip
const hostName = nowLocation.hostname;
// host => ip:port
const host = nowLocation.host;
// websocket api 地址
// 这个判断就是根据当前项目环境 自动确定使用 ws 还是 wss 的路由地址
const websocket_pattern = (hostName == '域名') ? 'wss-websocket-api' : 'websocket-api';

// websocket 请求地址前缀
const webSocketApiUrl =  ((protocol.startsWith('https')) ? 'wss://' : 'ws://') + host + '/' + websocket_pattern;


// 当前WebSocket的请求地址前缀,
// /websocket/template-push/ 就是我后端配置的websocket端点地址
let REQUEST_WEBSOCKET_URL_PREFIX = webSocketApiUrl + '/websocket/template-push/';
// 当前的WwebSocket对象
let CURRENT_SOCKET = null;
// 当前请求WebSocket的指令代码
let CURRENT_INDICATE_CODE = null;


let ENABLE_CONFIG = {

  WEBSOCKET_PUSH_VIDEO_ENABLE: true,
}

/**
 * 1. 初始化WebSocket连接对象
 * @param {*} clientKey 当前客户端Key
 */
function openWebSocket(clientKey) {
	if (CURRENT_SOCKET != null) {
		CURRENT_SOCKET.close();
		CURRENT_SOCKET = null;
	}

	CURRENT_SOCKET = new WebSocket(REQUEST_WEBSOCKET_URL_PREFIX + clientKey);

	CURRENT_SOCKET.onopen = event => {
		console.log('连接Socket');
	};

	// 从服务器接受到信息时的回调函数
	CURRENT_SOCKET.onmessage = event => {
		console.log('收到服务器响应 , 响应数据信息==>' , event.data);
	};

	CURRENT_SOCKET.onclose = event => {
		console.log('关闭Socket连接!');
	};

	//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
	window.onbeforeunload = () => {
		CURRENT_SOCKET.close();
		CURRENT_SOCKET = null;
	};
}

function getWebSocketConnection() {
	return CURRENT_SOCKET;
}
  • 前端websocket向后端发送数据使用方式
let sendData = {};
getWebSocketConnection().send(JSON.stringify(sendData));

3.2 后端代码

package com.ruoyi.web.controller.websocket;

import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.websocket.WebSocketClientIndicate;
import com.ruoyi.websocket.WebSocketRequest;
import com.ruoyi.websocket.WebSocketTemplateSession;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;

/**
 * --->
 *
 * @author xqh , 987072248@qq.com
 * @data 2023-11-02 15:46:51
 */
@Component
@ServerEndpoint("/websocket/template-push/{clientKey}")
@RequiredArgsConstructor
public class WebSocketTemplateInfoPushServer {

    /**
     * 统计在线人数 线程安全的计数器 比原子更新类 效率更高 更专业
     */
    private final static LongAdder ONLINE_ADDER = new LongAdder();
    /**
     * 客户端 连接会话存储Map , 每个客户端对应一个唯一Id , 在当前端点中 唯一Id为Session Id
     */
    private final static Map<String, WebSocketTemplateSession> SESSION_MAP = new ConcurrentHashMap<>();
    /**
     * 通过 clientKey 反查 sessionId , key为clientKey , value 为sessionId
     */
    private final static Map<String, String>  CLIENT_KEY_SESSION_STORE_MAP = new ConcurrentHashMap<>();


    private static final Logger WEBSOCKET_TEMPLATE_PUSH_LOGGER = LoggerFactory.getLogger(WebSocketTemplateInfoPushServer.class);

    /**
     * 1. 有新的连接访问当前 websocket 地址
     *
     * @param session      当前客户端的服务器对象 session
     * @param clientCode   客户端设备唯一code码
     */
    @OnOpen
    public void doConnectionSocket(Session session, @PathParam("clientKey") String clientCode) {

        // 前端异常 通过抓包发送 则直接关闭当前创建的session对象
        if (StringUtils.isEmpty(clientCode)) {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "参数不合法,已关闭当前连接!"));
            } catch (IOException e) {
                WEBSOCKET_TEMPLATE_PUSH_LOGGER.error(e.getMessage());
            }
        }
        // 正常则建立连接 存储数据 并返回连接成功
        else {
            String sessionId = session.getId();

            SESSION_MAP.put(sessionId, new WebSocketTemplateSession(session,clientCode));
            CLIENT_KEY_SESSION_STORE_MAP.put(sessionId,clientCode);

            ONLINE_ADDER.increment();
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.info("WebSocket-连接成功,此刻连接设备码为: [{}] , 此刻在线的连接数为:[{}]", clientCode, ONLINE_ADDER.sum());
        }
    }

    /**
     * 2. 关闭当前websocket连接
     * @param session
     */
    @OnClose
    public void doCloseSocket(Session session) {

        try {
            String sessionId = session.getId();
            WebSocketTemplateSession doCloseSession = SESSION_MAP.get(sessionId);
            doCloseSession.getSession().close();

            // 清除当前关联的Session信息
            SESSION_MAP.remove(sessionId);
            CLIENT_KEY_SESSION_STORE_MAP.remove(sessionId);

            ONLINE_ADDER.decrement();
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.info("WebSocket-连接关闭,此刻在线的连接数为:[{}]", ONLINE_ADDER.sum());
        } catch (IOException e) {
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.error(e.getMessage());
        }
    }

    /**
     * 3. 接收客户端主动发送的消息数据
     * @param session       当前会话
     * @param jsonMessage   客户端发送的JSON数据
     */
    @OnMessage
    public void receiveMessage(Session session , String jsonMessage){

        try {
        	// 收到前端发送的信息
        } catch (JSONException jsonException){
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.error("JSON格式有误,异常信息->[{}]" , jsonException.getMessage());
        } catch (Exception e){
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.error("接收信息接口失败,异常信息->[{}]" , e.getMessage());
        }
    }
}

  • WebSocketTemplateSession
@Data
@AllArgsConstructor
public class WebSocketTemplateSession {

    private Session session;

    private String clientKey;

}

4. 测试使用

  • 本地的 ws 方式
    vue wss,运维相关,运维,vue.js,websocket

  • 服务器的 wss 方式vue wss,运维相关,运维,vue.js,websocket文章来源地址https://www.toymoban.com/news/detail-790443.html

到了这里,关于运维相关(一) - Vue项目配置WebSocket连接{ws、wss 连接方式}的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记录一次nginx+Websocket反向代理时报错504-gateway TimeOut和各种开发遇到的坑(wss链接404、ws链接400 bad Requset等等)

    需要反向代理转发websocket链接。 1、nginx路径未匹配上 2、链接上后,在默认的http链接时长中没有发送心跳包,nginx自动关闭http链接,一般默认为1分钟 3、http链接转发后并没有升级为websockt链接(Bad Request 400错误) 4、websocket长链接1分钟后自动关闭 5、wss链接通过nginx转发时,

    2024年02月15日
    浏览(43)
  • vue项目显示 WebSocketClient.js:13 WebSocket connection to ‘ws://192.168.1.5:8089/ws‘ failed: Invalid fr

    我也不懂,这个可以解决 ws:false const { defineConfig } = require(\\\'@vue/cli-service\\\') module.exports = defineConfig({   transpileDependencies: true,   devServer: {     open: false,     host: \\\'0.0.0.0\\\',     port: 8089,     hot: true,     https: false,     proxy: {       \\\'/\\\': {         target: \\\'http://localhost:7776\\\',        

    2024年02月06日
    浏览(36)
  • vue项目使用websocket时报错: connection to ‘ws://...‘failed: Error in connection establish

     报错如下,意思是连接到\\\'ws://…\\\'failed:连接建立错误;  解决方法: 1、首先报错时先看看请求接口有没有写错; 2、看需不需要(有没有)传递参数; 3、还有可能就是没有传递验证参数 Authorization,也就是我们要传给后端的token验证; 传递方法如下:

    2024年02月11日
    浏览(40)
  • 当vue项目运行时,控制台出现“WebSocketClient.js:13 WebSocket connection to ‘ws://10.10.244.95:8080/ws‘ failed: E”

    当vue项目运行时,在控制台出现这些代码: 不要慌,小场面 是开发环境与生产环境的区别导致出现的问题  如果没使用过webscoket,禁用之后就可以了,就不会出现这个问题了。 devServer: {         webSocketServer:false,         //  其他配置 } 或者输入这些代码解决(代码网上

    2024年02月03日
    浏览(38)
  • websocket配置wss访问

    做一个小程序项目,3d多人聊天室互动,有两台服务器,windows系统和contos7 分别用来写小程序逻辑和部署socket.io 由于小程序里面都是https的请求,所以socket.io请求需要从ws(未加密)改成wws(加密) 下面应该是使用nginx反向代码解决这wss访问问题 两个简单问题解决记录 由于小

    2023年04月27日
    浏览(28)
  • Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息

    Java 构建websocket客户端,构建wss客户端,使用wss连接,并发送数据到服务器端,接收服务器端消息 回调函数处理

    2024年02月13日
    浏览(45)
  • 如何使用宝塔面板配置Nginx反向代理WebSocket(wss)

    本章教程,主要介绍一下在宝塔面板中如何配置websocket wss的具体过程。 目录 一、添加站点 二、申请证书 三、配置代理  1、增加配置内容

    2024年02月21日
    浏览(38)
  • windows下采用 nginx配置websocket支持wss流程

    第一步、安装OpenSSL (1)下载OpenSSL软件包 地址:https://slproweb.com/products/Win32OpenSSL.html OpenSSL版本说明: Win64 OpenSSL v1.1.1wLight,安装Win64 OpenSSL v1.1.1w最常用的软件包 Win64 OpenSSL v1.1.1w,安装Win64 OpenSSL v1.1.1w完整软件包 Win32 OpenSSL v1.1.1w Light,安装Win32 OpenSSL v1.1.1w最常用的软件包

    2024年02月22日
    浏览(30)
  • 【解决】websocket ws连不上或无法连接

    大致报错内容如图: WebSocket 连接失败的原因有很多,主要有以下几点: 服务器端没有正确配置 WebSocket,导致客户端无法连接。 网络问题,如网络不稳定,网络延迟等,导致客户端无法连接。 客户端代码有问题,导致无法正确连接服务器。 服务器端的防火墙设置不当,导致

    2024年02月12日
    浏览(35)
  • 关于Nginx配置SSL证书(Https)和WebSocket的wss

    一. 生成SSL自签证书        自签证书就是自己生成的证书,免费的,不支持部署浏览器的,支持浏览器的就是收费的,需要购买,这里因为是本地测试,所以就用的自签证书,买的证书可以跳过证书生成部分.  安装OpenSSL           OpenSSL是生成SSL的工具,这里是在Win10下安装的,下载的

    2023年04月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包