国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

運(yùn)維相關(guān)(一) - Vue項(xiàng)目配置WebSocket連接{ws、wss 連接方式}

這篇具有很好參考價(jià)值的文章主要介紹了運(yùn)維相關(guān)(一) - Vue項(xiàng)目配置WebSocket連接{ws、wss 連接方式}。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 寫作背景

  • 項(xiàng)目使用的是ruoyi的前后端分離框架
  • 項(xiàng)目需要使用到 websocket , 在本地使用 ws 連接方式是沒問題 , 但是服務(wù)器上邊使用的是nginx + ssl 證書 https域名訪問的方式部署的 使用普通的 ws 連接是不可以成功的 需要使用 wss的方式

2. 曬出代碼

2.1 前端 vue.config.js 的代碼

  • 這里target: 里邊指向的都是后端server的地址 16000是我后端服務(wù)的端口 , 我這里websocket服務(wù)和普通的業(yè)務(wù)項(xiàng)目用的都是一個(gè)項(xiàng)目 所以都是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項(xiàng)目路由配置代碼

  • 為什么要配置兩個(gè)地址呢? , 因?yàn)樵诒敬螠y試的時(shí)候使用的是普通的ws方式連接 所以為了方便切換就寫了兩個(gè)websocket代理路由

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

3.3 服務(wù)器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協(xié)議的類型。
		ssl_prefer_server_ciphers on;
        #charset koi8-r;

        access_log  logs/host.access.log  main;

		#默認(rèn)目錄
		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的項(xiàng)目
			 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 前端代碼

// 當(dāng)前瀏覽器Location對象
const nowLocation = window.location;
// 協(xié)議 => http、https
const protocol = nowLocation.protocol;
// hostName => ip
const hostName = nowLocation.hostname;
// host => ip:port
const host = nowLocation.host;
// websocket api 地址
// 這個(gè)判斷就是根據(jù)當(dāng)前項(xiàng)目環(huán)境 自動確定使用 ws 還是 wss 的路由地址
const websocket_pattern = (hostName == '域名') ? 'wss-websocket-api' : 'websocket-api';

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


// 當(dāng)前WebSocket的請求地址前綴,
// /websocket/template-push/ 就是我后端配置的websocket端點(diǎn)地址
let REQUEST_WEBSOCKET_URL_PREFIX = webSocketApiUrl + '/websocket/template-push/';
// 當(dāng)前的WwebSocket對象
let CURRENT_SOCKET = null;
// 當(dāng)前請求WebSocket的指令代碼
let CURRENT_INDICATE_CODE = null;


let ENABLE_CONFIG = {

  WEBSOCKET_PUSH_VIDEO_ENABLE: true,
}

/**
 * 1. 初始化WebSocket連接對象
 * @param {*} clientKey 當(dāng)前客戶端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');
	};

	// 從服務(wù)器接受到信息時(shí)的回調(diào)函數(shù)
	CURRENT_SOCKET.onmessage = event => {
		console.log('收到服務(wù)器響應(yīng) , 響應(yīng)數(shù)據(jù)信息==>' , event.data);
	};

	CURRENT_SOCKET.onclose = event => {
		console.log('關(guān)閉Socket連接!');
	};

	//監(jiān)聽窗口關(guān)閉事件,當(dāng)窗口關(guān)閉時(shí),主動去關(guān)閉websocket連接,防止連接還沒斷開就關(guān)閉窗口,server端會拋異常。
	window.onbeforeunload = () => {
		CURRENT_SOCKET.close();
		CURRENT_SOCKET = null;
	};
}

function getWebSocketConnection() {
	return CURRENT_SOCKET;
}
  • 前端websocket向后端發(fā)送數(shù)據(jù)使用方式
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 {

    /**
     * 統(tǒng)計(jì)在線人數(shù) 線程安全的計(jì)數(shù)器 比原子更新類 效率更高 更專業(yè)
     */
    private final static LongAdder ONLINE_ADDER = new LongAdder();
    /**
     * 客戶端 連接會話存儲Map , 每個(gè)客戶端對應(yīng)一個(gè)唯一Id , 在當(dāng)前端點(diǎn)中 唯一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. 有新的連接訪問當(dāng)前 websocket 地址
     *
     * @param session      當(dāng)前客戶端的服務(wù)器對象 session
     * @param clientCode   客戶端設(shè)備唯一code碼
     */
    @OnOpen
    public void doConnectionSocket(Session session, @PathParam("clientKey") String clientCode) {

        // 前端異常 通過抓包發(fā)送 則直接關(guān)閉當(dāng)前創(chuàng)建的session對象
        if (StringUtils.isEmpty(clientCode)) {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "參數(shù)不合法,已關(guān)閉當(dāng)前連接!"));
            } catch (IOException e) {
                WEBSOCKET_TEMPLATE_PUSH_LOGGER.error(e.getMessage());
            }
        }
        // 正常則建立連接 存儲數(shù)據(jù) 并返回連接成功
        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-連接成功,此刻連接設(shè)備碼為: [{}] , 此刻在線的連接數(shù)為:[{}]", clientCode, ONLINE_ADDER.sum());
        }
    }

    /**
     * 2. 關(guān)閉當(dāng)前websocket連接
     * @param session
     */
    @OnClose
    public void doCloseSocket(Session session) {

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

            // 清除當(dāng)前關(guān)聯(lián)的Session信息
            SESSION_MAP.remove(sessionId);
            CLIENT_KEY_SESSION_STORE_MAP.remove(sessionId);

            ONLINE_ADDER.decrement();
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.info("WebSocket-連接關(guān)閉,此刻在線的連接數(shù)為:[{}]", ONLINE_ADDER.sum());
        } catch (IOException e) {
            WEBSOCKET_TEMPLATE_PUSH_LOGGER.error(e.getMessage());
        }
    }

    /**
     * 3. 接收客戶端主動發(fā)送的消息數(shù)據(jù)
     * @param session       當(dāng)前會話
     * @param jsonMessage   客戶端發(fā)送的JSON數(shù)據(jù)
     */
    @OnMessage
    public void receiveMessage(Session session , String jsonMessage){

        try {
        	// 收到前端發(fā)送的信息
        } 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,運(yùn)維相關(guān),運(yùn)維,vue.js,websocket

  • 服務(wù)器的 wss 方式vue wss,運(yùn)維相關(guān),運(yùn)維,vue.js,websocket文章來源地址http://www.zghlxwxcb.cn/news/detail-790443.html

到了這里,關(guān)于運(yùn)維相關(guān)(一) - Vue項(xiàng)目配置WebSocket連接{ws、wss 連接方式}的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 記錄一次nginx+Websocket反向代理時(shí)報(bào)錯(cuò)504-gateway TimeOut和各種開發(fā)遇到的坑(wss鏈接404、ws鏈接400 bad Requset等等)

    需要反向代理轉(zhuǎn)發(fā)websocket鏈接。 1、nginx路徑未匹配上 2、鏈接上后,在默認(rèn)的http鏈接時(shí)長中沒有發(fā)送心跳包,nginx自動關(guān)閉http鏈接,一般默認(rèn)為1分鐘 3、http鏈接轉(zhuǎn)發(fā)后并沒有升級為websockt鏈接(Bad Request 400錯(cuò)誤) 4、websocket長鏈接1分鐘后自動關(guān)閉 5、wss鏈接通過nginx轉(zhuǎn)發(fā)時(shí),

    2024年02月15日
    瀏覽(27)
  • vue項(xiàng)目顯示 WebSocketClient.js:13 WebSocket connection to ‘ws://192.168.1.5:8089/ws‘ failed: Invalid fr

    我也不懂,這個(gè)可以解決 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日
    瀏覽(26)
  • vue項(xiàng)目使用websocket時(shí)報(bào)錯(cuò): connection to ‘ws://...‘failed: Error in connection establish

    vue項(xiàng)目使用websocket時(shí)報(bào)錯(cuò): connection to ‘ws://...‘failed: Error in connection establish

    ?報(bào)錯(cuò)如下,意思是連接到\\\'ws://…\\\'failed:連接建立錯(cuò)誤; ?解決方法: 1、首先報(bào)錯(cuò)時(shí)先看看請求接口有沒有寫錯(cuò); 2、看需不需要(有沒有)傳遞參數(shù); 3、還有可能就是沒有傳遞驗(yàn)證參數(shù) Authorization,也就是我們要傳給后端的token驗(yàn)證; 傳遞方法如下:

    2024年02月11日
    瀏覽(15)
  • 當(dāng)vue項(xiàng)目運(yùn)行時(shí),控制臺出現(xiàn)“WebSocketClient.js:13 WebSocket connection to ‘ws://10.10.244.95:8080/ws‘ failed: E”

    當(dāng)vue項(xiàng)目運(yùn)行時(shí),控制臺出現(xiàn)“WebSocketClient.js:13 WebSocket connection to ‘ws://10.10.244.95:8080/ws‘ failed: E”

    當(dāng)vue項(xiàng)目運(yùn)行時(shí),在控制臺出現(xiàn)這些代碼: 不要慌,小場面 是開發(fā)環(huán)境與生產(chǎn)環(huán)境的區(qū)別導(dǎo)致出現(xiàn)的問題? 如果沒使用過webscoket,禁用之后就可以了,就不會出現(xiàn)這個(gè)問題了。 devServer: { ????????webSocketServer:false, ? ? ? ? //? 其他配置 } 或者輸入這些代碼解決(代碼網(wǎng)上

    2024年02月03日
    瀏覽(28)
  • websocket配置wss訪問

    做一個(gè)小程序項(xiàng)目,3d多人聊天室互動,有兩臺服務(wù)器,windows系統(tǒng)和contos7 分別用來寫小程序邏輯和部署socket.io 由于小程序里面都是https的請求,所以socket.io請求需要從ws(未加密)改成wws(加密) 下面應(yīng)該是使用nginx反向代碼解決這wss訪問問題 兩個(gè)簡單問題解決記錄 由于小

    2023年04月27日
    瀏覽(18)
  • Java 構(gòu)建websocket客戶端,構(gòu)建wss客戶端,使用wss連接,并發(fā)送數(shù)據(jù)到服務(wù)器端,接收服務(wù)器端消息

    Java 構(gòu)建websocket客戶端,構(gòu)建wss客戶端,使用wss連接,并發(fā)送數(shù)據(jù)到服務(wù)器端,接收服務(wù)器端消息 回調(diào)函數(shù)處理

    2024年02月13日
    瀏覽(33)
  • 如何使用寶塔面板配置Nginx反向代理WebSocket(wss)

    本章教程,主要介紹一下在寶塔面板中如何配置websocket wss的具體過程。 目錄 一、添加站點(diǎn) 二、申請證書 三、配置代理 ?1、增加配置內(nèi)容

    2024年02月21日
    瀏覽(30)
  • windows下采用 nginx配置websocket支持wss流程

    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日
    瀏覽(31)
  • 【解決】websocket ws連不上或無法連接

    【解決】websocket ws連不上或無法連接

    大致報(bào)錯(cuò)內(nèi)容如圖: WebSocket 連接失敗的原因有很多,主要有以下幾點(diǎn): 服務(wù)器端沒有正確配置 WebSocket,導(dǎo)致客戶端無法連接。 網(wǎng)絡(luò)問題,如網(wǎng)絡(luò)不穩(wěn)定,網(wǎng)絡(luò)延遲等,導(dǎo)致客戶端無法連接。 客戶端代碼有問題,導(dǎo)致無法正確連接服務(wù)器。 服務(wù)器端的防火墻設(shè)置不當(dāng),導(dǎo)致

    2024年02月12日
    瀏覽(27)
  • 關(guān)于Nginx配置SSL證書(Https)和WebSocket的wss

    一. 生成SSL自簽證書 ? ? ? ?自簽證書就是自己生成的證書,免費(fèi)的,不支持部署瀏覽器的,支持瀏覽器的就是收費(fèi)的,需要購買,這里因?yàn)槭潜镜販y試,所以就用的自簽證書,買的證書可以跳過證書生成部分. ?安裝OpenSSL ? ? ? ? ? OpenSSL是生成SSL的工具,這里是在Win10下安裝的,下載的

    2023年04月14日
    瀏覽(33)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包