發佈日期:

Prometheus Exporter: json-exporter

甚麼是JSON Exporter

JSON Exporter是一個Prometheus的exporter(指標收集器),它能夠從提供JSON格式的API中收集指標數據,並將這些數據轉換為Prometheus所支持的格式,以便Prometheus進行分析和視覺化。

JSON Exporter的運行方式是通過設置JSON配置文件,其中包括API端點和相關的指標數據,然後使用Prometheus的配置文件將JSON Exporter添加到Prometheus的targets列表中。

JSON Exporter可以收集各種不同類型的指標數據,例如計數器(counters)、量規(gauges)和直方圖(histograms)等,並可以根據需要對數據進行轉換和聚合。

如何設置Exporter

在官方的Writing exporters文件中,有下面這一段

Each exporter should monitor exactly one instance application, preferably sitting right beside it on the same machine. That means for every HAProxy you run, you run a haproxy_exporter process. For every machine with a Mesos worker, you run the Mesos exporter on it, and another one for the master, if a machine has both.

The theory behind this is that for direct instrumentation this is what you’d be doing, and we’re trying to get as close to that as we can in other layouts. This means that all service discovery is done in Prometheus, not in exporters. This also has the benefit that Prometheus has the target information it needs to allow users probe your service with the blackbox exporter.

這段的意思是說,Exporter盡量和主要的Container放在同一個POD裡面,如下圖:

這樣做主要的原因是可以避免單點失敗,且更符合微服務架構的理念。

實作概要

下面是輸出的JSON檔案的範例

{
  "code": 0,
  "server": "vid-69t27o3",
  "streams": [
    {
      "id": "vid-0diw412",
      "name": "livestream",
      "vhost": "vid-y000397",
      "app": "live",
      "tcUrl": "rtmp://172.16.46.86:1935/live",
      "url": "/live/livestream",
      "live_ms": 1681903514993,
      "clients": 4,
      "frames": 0,
      "send_bytes": 45370,
      "recv_bytes": 34930,
      "kbps": {
        "recv_30s": 0,
        "send_30s": 0
      },
      "publish": {
        "active": false
      },
      "video": null,
      "audio": null
    }
  ]
}

下面是json-exporter的config.yml

modules:
  default:
    metrics:
    - name: server
      path: "{ .server}"

    - name: stream_clients
      type: object
      help: Example of sub-level value scrapes from a json
      path: '{.streams[?(@.name!="")]}'
      labels:
        name: '{.name}' 
      values:
        clients: '{.clients}' 
        send_bytes: '{.send_bytes}'
        recv_bytes: '{.recv_bytes}'
        frames: '{.frames}'
        publish: '{.publish.active}'

    headers:
      X-Dummy: my-test-header

設定要監控的POD的YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/instance: srs-core1
  name: srs-core1
  namespace: stu-srs
spec:
  template:
    metadata:
	  creationTimestamp: null
      labels:
        app.kubernetes.io/instance: srs-core1
	containers:
      ....Other container here
      - image: dev-registry.xycloud.org/ldr/streaming/json-exporter
        imagePullPolicy: IfNotPresent
        name: json-exporter
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
		args: ["--config.file", "/config.yml"]
        volumeMounts:
        - mountPath: /config.yml
          name: json-exporter
          subPath: config.yml
	volumes:  
      - configMap:
          defaultMode: 420
          name: json-exporter
        name: json-exporter

進入該POD的SHELL裡面查看Json-exporter所吐的資料

curl "http://localhost:7979/probe?target=http://127.0.0.1:1985/api/v1/streams/"

可以把資料串到Prometheus了

請參考以下文章

  1. 查看普羅米修斯某的pod內所有的值
  2. 查看普羅米修斯監控目標的exporter資訊
發佈日期:

在AWS的EC2裡加上SSL/TSL

SSL/TSL是甚麼

SSL/TLS是一種網絡協議,用於在客戶端和服務器之間提供安全的數據傳輸。 SSL代表“安全套接字層”,TLS代表“傳輸層安全性”,兩者是相似的協議,TLS是SSL的升級版。

SSL/TLS通過加密數據流來保護通信的隱私和完整性,以防止數據在傳輸過程中被竊聽或篡改。它使用數字證書來驗證服務器身份,以確保連接到的服務器是預期的服務器,而不是惡意者偽裝的服務器。

SSL/TLS廣泛用於保護網站,電子郵件,即時通訊,虛擬專用網絡(VPN)等應用程序中的數據傳輸。通過使用SSL/TLS,這些應用程序能夠提供更安全的通信,確保用戶的數據受到保護。

我的伺服器環境

這邊所說的是自架的Linux服務器的狀況,一般若是在網域託管的服務商買網站空間,使用cPanel等管理網站的狀況下,一般都會在空間購買裡面附設有免費的SSL/TSL證書,除非我們的網站需要額外的附加資訊才需要自行購買。

這篇文章所講的主要是當我們要在Linux裡面自行設定SSL/TSL,或使用AWS、Azure等服務的虛擬機器架設網站時,會需要自行於Linux中建立SSL/TSL並匯入所需的SSL/TSL認證。

在AWS中使用免費的ACM證書

這邊有很詳細的指導: 教學課程: 在 Amazon Linux 2 上設定 SSL/TLS

但是這邊的教程在後面匯入SSL證書的部分,是要我們自己去購買自己網域專屬的證書,那個很貴而且不太能夠免費,一般免費的SSL/TSL其組織等資訊並不會附在上面,如下圖為AWS所提供的免費證書。

要使用免費證書一個重要的前提就是要將我們所購買的網域給AWS的Route 53來託管,這個動作會產生微量的費用,一個月為0.51美金。

在AWS裡面,有一些服務本身就可以直接和Route53,若是沒辦法,則要另外建立 Elastic Load Balancing,這個是免費的,它可以用來連結我們的EC2和Route53,這樣就可以利用ACM來設定憑證了。

發佈日期:

在CentOS 7的Xampp中使用Certbot

Certbot介紹

Certbot是一個由EFF(Electronic Frontier Foundation)開發的免費開源工具,用於自動化在Web服務器上部署SSL/TLS證書。它是一個自動化的客戶端,可以讓您輕鬆獲得免費的SSL/TLS證書,以保護您的網站通信,避免了手動創建證書的複雜過程。

Certbot支持多種服務器軟件,包括Apache、Nginx、HAProxy、Amazon Web Services等,它使用ACME(自動化證書管理環境)協議從Let’s Encrypt證書頒發機構獲取SSL/TLS證書。使用Certbot,您可以輕鬆地為您的網站啟用HTTPS協議,提高網站的安全性和可靠性。

如何安裝

CerBot的安裝很貼心,在官方網站就可以選擇你所使用的環境,然後他就會有很詳細的安裝教學了

官方網站: https://certbot.eff.org/

使用XAMPP的認證指令

若是要認證XAMPP的APACHE,不能直接使用–apache,而是要使用apache-ctl,如下:

sudo certbot certonly --webroot --apache-ctl /opt/lampp/bin/apachectl

錯誤訊息除錯 – Could not find configuration root

下面這個錯誤訊息代表這個認證機器人不知道你的網站的本地端http files靜態路徑的位置

packages/certbot_apache/_internal/parser.py", line 924, in _find_config_root
    raise errors.NoInstallationError("Could not find configuration root")
certbot.errors.NoInstallationError: Could not find configuration root

解決方法: 在執行指令的時候告知http files靜態路徑的位置

sudo certbot certonly --webroot --apache-ctl /opt/lampp/bin/apachectl

或者

sudo certbot renew --webroot -w /var/www/html/

錯誤訊息除錯 – Please add a virtual host for port 80

ERROR:certbot._internal.log:Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.

這個錯誤提示表明Certbot無法在端口80上找到正在偵聽的虛擬主機,以便證明您控制域名。這是因為Certbot需要在域名的80端口上創建一個臨時HTTP服務器來進行驗證,以證明您控制該域名。

要解決這個問題,您需要在Apache服務器上為端口80添加虛擬主機配置。

/opt/lampp/apache2/conf/httpd.conf添加以下內容

<VirtualHost *:80>
    ServerAdmin your-email@example.com
    ServerName your-domain.com
    DocumentRoot /var/www/html
</VirtualHost>

接著重啟XAMPP

sudo /opt/lampp/lampp stop
sudo /opt/lampp/lampp start

或者

sudo service apache2 restart

其他除錯方向

  1. 防火牆沒有開:可以在本機中用curl去打IP,和從外面打,若是裡面可以外面不行,代表防火牆沒有開
  2. httpd設定只有localhost可存取: 應要把權限設定為”require all granted”。可用下面指令去搜尋電腦的httpd.conf的位置,並且尋找是不是你的網站被設定為”Require local”
sudo find / -name httpd.conf

成功拿到Certbot的SSL/TSL憑證

會可以看到下面的訊息,或許我們會懷疑為什麼都是pem,而不是.crt和.key,這是因為SSL/TLS憑證的格式可以有很多種,其中PEM格式是其中一種常見的格式,而.crt和.key則是PEM格式的一種變體。

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/bliss-angel.org/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/bliss-angel.org/privkey.pem

PEM格式是一種基於Base64編碼的標準格式,可以將數字證書和私鑰等敏感信息以文本格式表示出來,同時保持數據的可讀性。PEM格式的憑證通常以”.pem”為文件擴展名,可以包含公鑰、私鑰、憑證鏈等信息。

而.crt和.key則是PEM格式的一種變體,.crt檔案包含數字證書,.key檔案包含私鑰。這兩種檔案格式同樣是基於Base64編碼的PEM格式,只是文件名和內容有所不同。

為什麼有時候會看到PEM格式的憑證而不是.crt和.key檔案呢?這是因為PEM格式憑證可以包含多種類型的數字證書和私鑰,而且可以被用於多種網絡應用程序。例如,在OpenSSL等工具中,PEM格式憑證可以用於SSL/TLS加密、S/MIME郵件加密、SSH服務器驗證等方面。

因此,當你拿到一個PEM格式的憑證時,可以通過文件內容判斷它所包含的數字證書或私鑰類型。如果你需要將PEM格式憑證轉換成.crt和.key檔案,你可以使用OpenSSL等工具進行轉換。

但是這不影響的,仍然可以在/opt/lampp/etc/extra/httpd-ssl.conf設定,然後重啟Apache後SSL證書就生效囉!

SSLCertificateFile "/etc/letsencrypt/live/bliss-angel.org/fullchain.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/bliss-angel.org/privkey.pem"
發佈日期:

Publish HEVC live streaming by OBS to SRS via RTMP

After OBS Studio 29.1, they added support for Enhanced RTMP, it is now possible to push HEVC streaming via RTMP, and SRS also support HEVC over RTMP and HTTP-FLV v6.0.2+.

Here is a simple tutorial on how to use OBS to push HEVC streams to SRS.

OBS support H.265 over RTMP v29.1+

The original RTMP protocol cannot support high-compression video formats such as HEVC or AV1. But from OBS Studio 29.1 Beta, OBS adds support for the updated: Enhanced RTMP. For more detail, please refer to: Enable AV1, HEVC via RTMP to YouTube.

Therefore, the first step to push an HEVC stream via RTMP from OBS is to download the latest version of OBS. (Download here: OBS Studio 29.1 Beta Release Page).

SRS support H.265 over RTMP v6.0.42+

  • RTMP: Support enhanced RTMP specification for HEVC, v6.0.42.
  • Player: Upgrade mpegts.js to support it.

Enhanced RTMP specification: https://github.com/veovera/enhanced-rtmp

First, start SRS v6.0.42+ with HTTP-TS support:

./objs/srs -c conf/http.ts.live.conf

Pulish HEVC via RTMP from OBS

  1. Your OBS version should be greater than v29.1, than open File -> Setting
  2. Select Stream -> Service to Custom…
  3. Select Output -> Output Mode to Advanced, than choice Encoder to HEVC
  4. Click Start Streaming
  5. Check your streaming from SRS console
  6. Preview your streaming by SRS Player
發佈日期:

HorizontalPodAutoscalers by customize metric

設定擴充的行為,sacle down及up的時候所做的行為,這邊的設定是假如維持300秒都穩定相同狀況,則做HPA縮放,最少維持這種狀態60秒,一次增加1個Pod​

這邊則設定要參考的數值,若是要使用自訂義資料,則describedObject這邊要設定的與我們在Rules裡面設定的一致,target部分則設定每一個pods的目標值為多少​

下面scaleTargetRef的部分則是設定要做HPA的目標是甚麼,有可能是Services,這邊做HPA的目標則為Pod​

apiVersion: autoscaling/v2beta2​
kind: HorizontalPodAutoscaler​
metadata:​
  name: srs-edge​
  namespace: srs3​
spec:​
  behavior:​
    scaleDown:​
      policies:​
      - periodSeconds: 60​
        type: Pods​
        value: 1​
      selectPolicy: Max​
      stabilizationWindowSeconds: 300​
    scaleUp:​
      policies:​
      - periodSeconds: 60​
        type: Pods​
        value: 1​
      selectPolicy: Max​
      stabilizationWindowSeconds: 300​
  maxReplicas: 2​
  metrics:​
  - object:​
      describedObject:​
        apiVersion: v1​
        kind: Service​
        name: eventqueue​
      metric:​
        name: stream_total_clients_by_pod​
      target:​
        type: Value​
        value: 1k​
    type: Object​
  minReplicas: 1​
  scaleTargetRef:​
    apiVersion: apps/v1​
    kind: Deployment​
    name: srs-edge​

stream_total_clients_by_pod是我們的客製化變數,這個變數是來自於普羅米修斯,要把普羅米修斯的變數給k8s使用,請參見
http://claire-chang.com/2022/12/16/prometheus-rule-for-alert/
這邊很重要的是可以看到label裡面有name: eventqueue,在Prometheus Rule裡一定也要加上labels: service: eventqueue
這樣這個值才會可以被輸出給普羅米修斯使用

如下圖:

其他更多的設定值請見: https://docs.openshift.com/container-platform/4.9/nodes/pods/nodes-pods-autoscaling.html​

發佈日期:

查看普羅米修斯某的POD內所有的值

Prometheus 指令

使用的指令如下:

sum by(__name__)({namespace="default",pod="pod_name", __name__=~".*"})

解釋如下:

  • sum by(__name__) 是一個 Prometheus 查詢語句,用於計算符合指定條件的指標值之和,並根據指標名稱進行分組。
  • {namespace="default",pod_name="my-pod"} 是一個標籤選擇器 (label selector),用來選擇符合條件的 POD。其中,namespace 表示命名空間 (namespace),pod_name 表示 POD 名稱。
  • __name__=~"MEERIC.*" 是一個正則表達式選擇器 (regular expression selector),用於選擇符合特定模式的指標名稱。在本例中,我們使用 ~ 運算符將正則表達式 "MEERIC.*" 用於指標名稱,以找到符合條件的指標。這個正則表達式的意思是:以 MEERIC 開頭的所有指標名稱。
  • __name__ 是一個特殊的標籤 (label),代表指標名稱。使用 sum by 子句時,我們將其作為分組條件之一,以根據指標名稱對指標值進行分組。

設定ServiceMonitor

在可以看到所有的值之後,就可以確認你的ServiceMonitor是否正確,可以來設定ServiceMonitor讓普羅米修斯監控正確的對象

以下為一個簡單的範例

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app.kubernetes.io/instance: srs-json-exporter
  name: json-exporter
  namespace: stu-dashboard
spec:
  endpoints:
  - interval: 30s
    params:
      module:
      - default
      target:
      - http://127.0.0.1:1985/api/v1/streams/
    path: probe
    port: json-exporter
  jobLabel: jobLabel
  namespaceSelector:
    matchNames:
    - stu-srs
  selector:
    matchLabels:
      app: json-exporter

更多關於ServiceMonitor可用的設定值請見:
https://docs.openshift.com/container-platform/4.9/rest_api/monitoring_apis/servicemonitor-monitoring-coreos-com-v1.html

發佈日期:

使用kubectl進入某個pod裡的某個container的指令

使用kubectl進入container

若要使用 kubectl 進入某個 pod 裡的某個 container,您可以使用 kubectl exec 命令。以下是一個範例指令:
kubectl exec -it -n –container — /bin/sh
在這裡,請將 <pod_name> 替換為您想要進入的 pod 的名稱,將 <container_name> 替換為您想要進入的 container 的名稱。這個指令會使用 /bin/bash shell 進入 container,如果該 container 沒有 /bin/bash,您可以嘗試使用 /bin/sh 作為替代:

kubectl exec -it -n <namespace> <pod_name> -c <container_name> -- /bin/sh

請注意,這些指令假設您已經成功地安裝並設置了 kubectl,並能夠與 Kubernetes 集群通信。

設定kubectl的方法

要配置 kubectl,您需要一個包含集群連接信息的 kubeconfig 文件。通常,當您使用雲服務提供商(如 GKE、EKS 或 AKS)或 Kubernetes 配置工具(如 kopskubeadm)建立集群時,它們會自動為您生成一個 kubeconfig 文件。

kubeconfig 文件通常位於 ~/.kube/config。您可以使用環境變量 KUBECONFIG 來指定 kubeconfig 文件的位置,例如:
export KUBECONFIG=~/.kube/my-kubeconfig.yaml
Kubeconfig file將內容複製到 ~/.kube/config 位置即可​裡面

下載kubectl 或者Lens

即可於本機​ 對K8S下指令

發佈日期:

查看普羅米修斯監控目標的exporter資訊

Prometheus Target

普羅米修斯 (Prometheus) 是一套開源的監控系統,其中一個重要的功能就是監控 Service (服務) 的運作狀態,這個功能被稱為 Service Monitoring。

Service Monitoring 可以藉由 exporter,透過定義 HTTP endpoints 的方式,監控這些服務的運作狀態。普羅米修斯會定期呼叫這些 endpoints ,並且收集回應的 metrics 以了解服務是否正常運作、服務的吞吐量、延遲、錯誤率等相關資訊。

Service Monitoring 可以提供以下的監控能力:

  • 監控服務的可用性,例如偵測服務是否還在運作、是否正常回應等等。
  • 監控服務的效能,例如服務的吞吐量、延遲等等。
  • 記錄服務的執行狀態,例如錯誤率、請求數量、處理時間等等。
  • 透過 Service Monitoring,可以提升系統的可用性、效能及穩定性,讓系統管理者能夠更快速地偵測到問題、快速修復問題,降低系統的 downtime,提高系統的可靠度。

如何瀏覽exporter的內容

先到普羅米修斯的網頁的Target的地方,會可以看到現在的監控目標,如果設定的目標沒有正確出現,則可以去Service Discovery的頁籤去確認原因。

內容長這樣

無法存取rancher-monitoring-kubelet的exporter吐出的內容


serviceMonitor/kube-system/rancher-monitoring-kubelet/1 (7/7 up)
普羅米修斯在取得Pod的相關狀態是利用rancher-monitoring-kubelet這個POD來取得相關資訊,但是我們會沒有辦法直接去讀取https://127.0.0.1:10250/metrics/cadvisor這個網址,這是因為要讀取需要先透過K8S的認證
# 取得該namespace的所有密鑰​
kubectl get secret -n cattle-monitoring-system​

# 取得密鑰的內容​
kubectl -n cattle-monitoring-system get secret rancher-monitoring-prometheus-token-hvlqt -o jsonpath={.data.token} | base64 –d​

# 將pod-exporter的網址後面加上-H並帶入密鑰​
curl https://127.0.0.1:10250/metrics/cadvisor -k -H “Authorization: Bearer token_content_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”​

Service Monitor抓不到監控目標的可能原因

以下為一個簡單範例

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  generation: 4
  labels:
    app.kubernetes.io/instance: srs-json-exporter
    manager: agent
    operation: Update
  name: json-exporter
  namespace: stu-srs
spec:
  endpoints:
  - interval: 30s
    params:
      module:
      - default
      target:
      - http://127.0.0.1:1985/api/v1/streams/
    port: json-exporter
  jobLabel: jobLabel
  namespaceSelector:
    matchNames:
    - stu-srs
  selector:
    matchLabels:
      app.kubernetes.io/instance: srs-json-exporter

在selector 字段指定要監控的 Service 的標籤選擇器,而不是 Pod 的標籤選擇器。

在這個 YAML 配置文件中,ServiceMonitor 的 selector 字段設置為 matchLabels: app: json-exporter,這代表 ServiceMonitor 將監控符合 app: json-exporter 標籤的 Service。
如果這個 Service 沒有符合 app: json-exporter 標籤,那麼 ServiceMonitor 就無法監控這個 Service。

如果您確認了 Service 的標籤設置是正確的,那麼可能是因為 ServiceMonitor 與 Service 所在的命名空間不匹配,導致 ServiceMonitor 無法監控 Service。
您可以檢查 ServiceMonitor 的 namespaceSelector 設置是否正確。namespaceSelector 字段指定要監控的命名空間。如果這個 Service 所在的命名空間不在 matchNames 列表中,那麼 ServiceMonitor 就無法監控這個 Service。

發佈日期:

什麼是WebRTC

文章轉載

這篇文章翻譯自: What is WebRTC and how does it work? Real-time communication with WebRTC

什麼是WebRTC

WebRTC代表網路實時通訊。 它是一種非常令人興奮、強大且具有高度破壞性的尖端技術和流媒體協議。

WebRTC與HTML5相容,您可以使用它直接在瀏覽器和裝置之間新增實時媒體通訊。 最好的部分之一是,您無需在瀏覽器中安裝外掛的任何先決條件即可做到這一點。 Webrtc正逐漸得到所有主要現代瀏覽器供應商的支援,包括Safari、Google Chrome、Firefox、Opera等。

多虧了WebRTC影片流技術,您可以將實時影片直接嵌入到基於瀏覽器的解決方案中,為您的觀眾創造引人入勝的互動式流媒體體驗,而不必擔心延遲。

現在,影片,特別是直播,是我們快速變化的通訊需求不可或缺的一部分。 隨著社交距離的增加,WebRTC幫助我們滿足這些通訊需求,並增加我們與實時通訊的互動。

WebRTC元件

我們將使用客戶端-A和客戶端-B作為示例來解釋WebRTC的以下元件。

SDP(會話描述協議)

SDP是一個簡單的基於字串的協議,它在瀏覽器之間共享支援的程式碼器。

在我們的例子中,

  • 客戶端 A 創建其 SDP(稱為報價)並將其保存為本地 SDP,然後與客戶端 B 共享。
  • Client-B收到Client-A的SDP,保存為遠程SDP。
  • 客戶端 B 創建其 SDP(稱為答案)並將其保存為本地 SDP,然後與客戶端 A 共享。
  • Client-A收到Client-B的SDP,保存為遠程SDP。

信令伺服器(Signaling Server)負責等體之間的這些SDP傳輸。

讓我們假設客戶端A可能支援H264、VP8和VP9編解碼器用於影片、Opus和PCM編解碼器用於音訊。 客戶端-B可能只支援H264用於影片,只支援Opus編碼器用於音訊。

在這種情況下,客戶端-A和客戶端-B將使用H264和Opus作為編解碼器。 如果對等體之間沒有共同的程式碼器,則無法建立對等通訊。

ICE(交互連接建立)

Interactive Connectivity Establishment (ICE) 用於 Internet 上的兩個節點必須盡可能直接通信的問題,但是 NAT 和防火牆的存在使得節點之間難以相互通信。

它是一種網絡技術,利用 STUN(NAT 會話遍歷實用程序)和 TURN(在 NAT 周圍使用中繼遍歷)在兩個節點之間建立盡可能直接的連接。

WebRTC STUN 服務器NAT 的會話遍歷實用程序) 

STUN Server負責獲取一台機器的所有地址。例如,我們的計算機通常在 192.168.0.0 網絡中有一個本地地址,當我們連接到www.whatismyip.com時,我們會看到第二個地址,這個 IP 地址實際上是我們互聯網網關(調製解調器,調製解調器,路由器等),所以讓我們定義 STUN 服務器:STUN 服務器讓對等方知道他們的公共和本地 IP 地址。

順便說一下,Google 還提供了一個免費的 STUN 服務器 (stun.l.google.com:19302)。

 

WebRTC TURN  Server  (繞過NAT使用中繼遍歷)

TURN(Traversal Using Relays around NAT)是一種協議,可幫助 WebRTC 應用程序穿越網絡地址轉換器 (NAT) 或防火牆。TURN Server 允許客戶端通過中間服務器發送和接收數據。

TURN 協議是 STUN 的擴展。 有時,由於 NAT/Firewall,從STUN服務器 獲取的地址不能用於建立對等點之間的對等連接。在這種情況下,數據通過TURN服務器中繼

在我們的例子中,

  • Client-A通過STUN服務器找到自己的本地地址和公網地址,並通過Signaling Server將這些地址發送給Client-B。從 STUN 服務器收到的每個地址都是 ICE 候選地址。
  • Client-B 做同樣的事情,從 STUN 服務器獲取本地和公共 IP 地址,並將這些地址通過 Signaling Server 發送給 Client-A。
  • Client-A 收到 Client-B 的地址並通過發送特殊的 ping 來嘗試每個 IP 地址以創建與 Client-B 的連接。如果客戶端 A 收到來自任何 IP 地址的響應,它會將該地址及其響應時間和其他性能憑證放入列表中。最後,Client-A 根據其性能選擇最佳地址。
  • Client-B 做同樣的事情以連接到 Client-A

RTP(實時協議)

RTP 是在UDP之上傳輸實時數據的成熟協議。在 WebRTC 中,音頻和視頻通過 RTP 傳輸。RTP 有一個姊妹協議,名為 RTCP(實時控制協議),它在 RTP 通信中提供 QoS。RTSP  (實時流協議)在數據通信中也使用 RTP 協議。

WebRTC 信令服務器

最後一部分是Signaling Server,WebRTC 中沒有定義。如上所述,Signaling Server 用於在 Client-A 和 Client-B 之間發送 SDP 字符串和 ICE Candidates。信令服務器還決定哪些對等點相互連接。WebSocket 技術是與信令服務器進行通信的首選方式。

發佈日期:

用OPENCV繪製垂直線

繪製出穿過這兩個點(10,20)和(50,30)的中心點,並與和這兩點相連的直線垂直的線。

import cv2
import numpy as np

# 創建一個空的圖像,並設置其大小為 100x100 像素,並設置其通道數為 3 (RGB)
img = np.zeros((100, 100, 3), np.uint8)

# 定義點的座標
point1 = (10, 20)
point2 = (50, 30)

# 計算兩個點的中心點座標
center_point = ((point1[0] + point2[0]) // 2, (point1[1] + point2[1]) // 2)

# 繪製出兩個點以及中心點
cv2.circle(img, point1, 2, (0, 0, 255), -1)
cv2.circle(img, point2, 2, (0, 0, 255), -1)
cv2.circle(img, center_point, 2, (0, 255, 0), -1)

# 計算與這兩點相連的直線垂直的線的端點座標
if point1[0] == point2[0]:
    # 如果這兩個點的 x 座標相等,則直接在中心點上下各畫一個點,這兩個點就是線的端點
    line_point1 = (center_point[0], 0)
    line_point2 = (center_point[0], 100)
else:
    # 否則,計算這兩個點之間的斜率
    k = (point2[1] - point1[1]) / (point2[0] - point1[0])
    # 計算垂直於這條線的斜率
    vk = -1 / k
    # 計算線的端點座標
    line_point1 = (center_point[0] - 50, int(center_point[1] - vk * 50))
    line_point2 = (center_point[0] + 50, int(center_point[1] + vk * 50))

# 繪製出垂直線
cv2.line(img, line_point1, line_point2, (255, 0, 0), 1)

# 顯示圖像
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()