<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WebRTC &#8211; wqh博客</title>
	<atom:link href="https://wangqianhong.com/tag/webrtc/feed/" rel="self" type="application/rss+xml" />
	<link>https://wangqianhong.com</link>
	<description>和而不同</description>
	<lastBuildDate>Wed, 19 Jun 2024 08:49:33 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wangqianhong.com/wp-content/uploads/2020/09/cropped-1-1-1-32x32.png</url>
	<title>WebRTC &#8211; wqh博客</title>
	<link>https://wangqianhong.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WebRTC实时通信 （七）&#124; TURN 部署</title>
		<link>https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/</link>
					<comments>https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Fri, 01 Jul 2022 07:01:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3192</guid>

					<description><![CDATA[<p>https://github.com/coturn/coturn 配置文件 coturn的配置文件t&#8230; <a href="https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （七）&#124; TURN 部署</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/">WebRTC实时通信 （七）| TURN 部署</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p><a rel="noreferrer noopener" href="https://github.com/coturn/coturn" target="_blank">https://github.com/coturn/coturn</a></p>



<h3>配置文件</h3>



<p>coturn的配置文件<code>turnserver.conf</code></p>



<pre class="wp-block-preformatted">#TURN监听IP
listening-ip=127.0.0.1
#TURN为TCP和UDP监听端口
listening-port=3478
#TURN为TLS监听端口
tls-listening-port=5349
#UDP端口范围，如果范围设置太大，docker run可能会卡住
min-port=49160
max-port=49200
#使用长期凭证机制
lt-cred-mech
use-auth-secret
static-auth-secret=north
#访问的域名
realm=example.org
server-name=example.org</pre>



<p>coturn有4种认证机制：</p>



<ol><li><strong>no-auth（允许匿名访问）</strong>，开启这一选项，即使有一个user选项开启了（在配置文件或者命令行或者usersdb文件中），no-auth也会被启用</li><li><strong>lt-cred-mech（长期凭据机制）</strong>，如果no-auth和lt-cred-mech都未开启，但有一个user选项开启了，lt-cred-mech也会被自动开启</li><li><strong>use-auth-secret（时间有限的长期凭据）</strong>，需要实现TURN REST API使用认证，可以在数据库的turn_secret里查询，这是动态认证秘密</li><li><strong>static-auth-secret（静态认证）</strong>，需要实现TURN REST API使用认证</li></ol>



<h3>Docker创建</h3>



<pre class="wp-block-code"><code>docker pull coturn/coturn:4.6.2</code></pre>



<pre class="wp-block-code"><code>docker run -d -p 3478:3478 -p 3478:3478/udp -p 5349:5349 -p 5349:5349/udp -p 49160-49200:49160-49200/udp coturn/coturn:4.6.2 -v $(pwd)/turnserver.conf:/etc/coturn/turnserver.conf -e DETECT_EXTERNAL_IP=yes --external-ip='$(detect-external-ip --ipv6)' --relay-ip='$(detect-external-ip --ipv6)'</code></pre>



<h3>Docker参数</h3>



<p>默认情况下，容器使用CMD Dockerfile中指定的coturn的默认配置；如果我们需要编辑默认配置，我们可以通过在运行docker容器时指定volume命令来完成</p>



<pre class="wp-block-code"><code>-v $(pwd)/custom.conf:/etc/coturn/turnserver.conf</code></pre>



<p>coturn有一个叫做检测外部ip的功能，可以自动检测外部ip，运行docker run命令时，可以通过将“DETECT_EXTERNAL_IP”环境变量设置为yes来启用此功能</p>



<pre class="wp-block-code"><code>-e DETECT_EXTERNAL_IP=yes</code></pre>



<p>默认情况下，它检测IPv4，但如果希望检测IPv6，可以使用以下代码将其设置</p>



<pre class="wp-block-code"><code>--external-ip='$(detect-external-ip --ipv6)' --relay-ip='$(detect-external-ip --ipv6)'</code></pre>



<h3>网络设置</h3>



<p>因为docker容器在机器内部运行，使用服务器url访问TURN服务器。<br>首先，需要知道docker主机的IP地址以及映射到docker容器内coturn服务器的端口。<br>在上面的例子中，docker容器映射到本地机器的端口3478，并在本地主机或127.0.0.1上运行docker容器，所以coturn的url是</p>



<pre class="wp-block-code"><code>turn:IP_Address_Docker_host:3478</code></pre>



<p>如果主机地址是其他一些私人IP地址，如192.1688.1.22或其他一些，可以使用上面的公式轻松地进行映射。<br>但这里存在问题，为了能够在本地机器之外使用Turn服务器，我们需要将其映射到公共IP地址。</p>



<p>如果TURN服务器位于NAT之后，则NAT网关必须具有一个外部的、可公开访问的IP地址：</p>



<pre class="wp-block-code"><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS</code></pre>



<p>可以选择将TURN服务器限制为仅侦听由NAT映射到外部地址的本地地址：</p>



<pre class="wp-block-code"><code>listening-ip=INTERNAL_TURNSERVER_IPv4_ADDRESS</code></pre>



<p>如果NAT网关可以通过IPv4和IPv6访问，可以配置coturn来通告每个可用地址：</p>



<pre class="wp-block-code"><code>external-ip=EXTERNAL_NAT_IPv4_ADDRESS
external-ip=EXTERNAL_NAT_IPv6_ADDRESS</code></pre>



<p></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/">WebRTC实时通信 （七）| TURN 部署</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/07/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%83%ef%bc%89-turn-%e9%83%a8%e7%bd%b2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （六）&#124; TURN服务器</title>
		<link>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/</link>
					<comments>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Thu, 23 Jun 2022 09:27:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2973</guid>

					<description><![CDATA[<p>Turn Server是在不同网络中的2个主机/对等体之间中继流量所需的服务器。这是因为两个对等点之&#8230; <a href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （六）&#124; TURN服务器</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/">WebRTC实时通信 （六）| TURN服务器</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>Turn Server是在不同网络中的2个主机/对等体之间中继流量所需的服务器。这是因为两个对等点之间不可能直接连接，除非它们在同一网络上（这是因为防火墙阻止了流量）</p>



<figure class="wp-block-image"><img src="https://www.metered.ca/tools/openrelay/assets/images/ICE-568b25f961e45b313fa0f403123fb007.png" alt="ICE Candidates"/></figure>



<h3>TURN服务器配置</h3>



<p>可以通过两种方式添加add-turn服务器配置：</p>



<ol><li>在前端或任何需要的地方添加静态url。</li><li>每次使用API获取url。</li></ol>



<p>在前端或任何需要的地方添加url，一旦TURN服务器联机，所需要的只是客户端使用它的正确RTC配置。</p>



<h3>ICE Candidates</h3>



<p>考虑到NAT和防火墙的层层阻塞端口和协议，构建一个有效的NAT穿越解决方案是非常困难的。值得庆幸的是，ICE已被开发为一种有效的穿越NAT的协议。ICE或交互式连接建立协议是一组在参与者之间建立最有效隧道的方法</p>



<ol><li>尽可能直连对等端</li><li>需要时使用STUN协商</li><li>并在需要时回退到TURN</li></ol>



<h3>UDP协议</h3>



<p>UDP也被称为空协议或不可靠的数据报协议——事实上，UDP的RFC可以很容易说明：</p>



<p>一种独立的数据实体，携带足够的信息，从源节点路由到目的节点，而不依赖节点和传输网络之间的早期交换。</p>



<p>虽然数据报和数据包是可互换使用的术语，但也有一些区别。</p>



<p>当数据包指的是格式化的代码块时，数据报指的是通过不可靠网络传输的代码块。UDP协议的定义特征是数据传输的不可靠性质。即：</p>



<ul><li>无交付保证</li><li>没有故障通知</li></ul>



<p>因此，UDP被称为不可靠数据报协议，而不是官方术语“用户数据报协议”，这就是UDP数据包被称为数据报的原因。</p>



<p>UDP虽然在可靠性方面有所损失，但却大大提高了速度和吞吐量。</p>



<p>支持视频呼叫、语音呼叫和各种数据传输的webRTC（Web实时通信）标准运行在UDP协议上。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/">WebRTC实时通信 （六）| TURN服务器</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%85%ad%ef%bc%89-turn%e6%9c%8d%e5%8a%a1%e5%99%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （五）&#124; STUN服务器配置</title>
		<link>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/</link>
					<comments>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sun, 19 Jun 2022 05:15:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2967</guid>

					<description><![CDATA[<p>设置STUN服务器的先决条件 基本理解JavaScript和web开发概念，基本理解NAT遍历以及如&#8230; <a href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （五）&#124; STUN服务器配置</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/">WebRTC实时通信 （五）| STUN服务器配置</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h3>设置STUN服务器的先决条件</h3>



<p>基本理解JavaScript和web开发概念，基本理解NAT遍历以及如何建立对等连接</p>



<h3>选择STUN服务器</h3>



<p>有许多免费和付费的STUN服务器服务。一些流行的是</p>



<ul><li>Metered Global WebRTC STUN和TURN服务器</li><li>谷歌STUN服务器</li><li>也可以设置自己的STUN服务器</li></ul>



<h3>设置WebRTC配置</h3>



<p>需要设置配置对象。此对象包括有关ICE（交互式连接建立）服务器的信息。同时具有STUN和TURN服务器。</p>



<p>STUN服务器基本配置示例</p>



<pre class="wp-block-code"><code>let configuration = {
  'iceServers': &#91;{
    'urls': 'stun:stun.l.google.com:19302'
  }]
};</code></pre>



<p>创建对等连接现在，我们将使用配置创建一个新的RTCPeerConnection对象。此对象表示本地计算机和远程对等计算机之间的WebRTC连接</p>



<pre class="wp-block-code"><code>let peerConnection = new RTCPeerConnection(configuration);</code></pre>



<h3>创建和发送报价</h3>



<p>要启动与远程对等方的连接，我们需要创建一个报价。在该报价中，我们将包括有关媒体轨道、音频和视频以及我们需要打开的任何其他数据通道的信息</p>



<pre class="wp-block-code"><code>peerConnection.createOffer()
  .then(offer => peerConnection.setLocalDescription(offer))
  .then(() => {
    // Send the offer to the remote peer using your signaling server
  });</code></pre>



<h3>ICE candidates</h3>



<p>当RTC对等连接找到ICE candidates时，会触发“icecandidate”事件。</p>



<p>我们需要在客户端处理此事件，并将ICE candidates发送到远程对等方</p>



<pre class="wp-block-code"><code>peerConnection.onicecandidate = event => {
  if (event.candidate) {
    // Send the ICE candidate to the remote peer using your signaling server
  }
};</code></pre>



<h3>接入offers, Answers and ICE candidates</h3>



<p>我们需要使用RTCPeerConnection上的“setRemoteDescription”和“addIceCcandidate”等函数来侦听来自信令服务器的消息</p>



<pre class="wp-block-code"><code>// Listen for messages from your signaling server
signalingServer.onmessage = message => {
  if (message.offer) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer));
    // Create an answer and send it back to the remote peer
    peerConnection.createAnswer()
      .then(answer => peerConnection.setLocalDescription(answer))
      .then(() => {
        // Send the answer back to the remote peer using your signaling server
      });
  } else if (message.answer) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(message.answer));
  } else if (message.iceCandidate) {
    peerConnection.addIceCandidate(new RTCIceCandidate(message.iceCandidate));
  }
};</code></pre>



<p>这就是在客户端设置STUN服务器的方法。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/">WebRTC实时通信 （五）| STUN服务器配置</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%94%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （四）&#124; STUN协议工作详情</title>
		<link>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/</link>
					<comments>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sat, 11 Jun 2022 03:39:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2957</guid>

					<description><![CDATA[<p>STUN消息是如何形成的 STUN代理创建一个STUN消息。STUN消息类必须是“Request”或&#8230; <a href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （四）&#124; STUN协议工作详情</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/">WebRTC实时通信 （四）| STUN协议工作详情</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h3>STUN消息是如何形成的</h3>



<p>STUN代理创建一个STUN消息。STUN消息类必须是“Request”或“Indication”，方法必须是“binding”或一些其他方法。对于没有auth的binding方法，不需要任何属性。</p>



<figure class="wp-block-image"><img src="https://www.metered.ca/tools/openrelay/assets/images/how-turn-server-works-288e97aeab1c87e650ad3f2740d0a41e.png" alt="turn-server"/></figure>



<p>STUN代理发送请求或指示。STUN消息可以通过</p>



<ol><li>UDP</li><li>TCP</li><li>基于TCP的TLS</li></ol>



<h3>STUN消息的发送方式</h3>



<h4>通过UDP协议发送请求</h4>



<p>当通过UDP发送数据包时，数据包可能会被丢弃，因为UDP无法保证到达目的地没有故障通知，STUN请求的可靠性必须通过客户端自身重新传输请求消息来实现。</p>



<p>客户端可以从RTO（重传超时）间隔开始重传请求消息，并在每次重传后加倍。重传可以继续，直到接收到响应或者直到由于默认Rc请求是7而已经显示了总Rc请求。</p>



<h4>通过TCP或TLS over IP协议发送请求</h4>



<p>为了通过TCP传输STUN消息，客户端打开到服务器的TCP连接。</p>



<p>在一些使用情况下，STUN是作为TCP连接上的唯一协议发送的，在这些情况下，可以使用任何附加的成帧或复用来发送STUN。在其他使用情况下，发送STUN，STUN通过TCP连接与其他数据多路复用。</p>



<p>当STUN通过TCP连接与其他数据复用时，需要某种成帧协议，并且STUN在该成帧协议之上运行。该成帧协议允许接收STUN消息。</p>



<p>如果通过TCP运行STUN消息，则必须至少实现RCA密码，但也可以使用其他密码套件。正在接收的STUN消息的可靠性由TCP本身处理，不需要在STUN协议级别进行重传。</p>



<p>对于请求/响应事务，如果客户端无法通过TCP建立连接，或者如果TCP连接重置为失败，则认为请求/响应交易已失败。</p>



<p>客户端可以通过TCP发送多个请求，甚至在接收到响应之前也可以发送多个要求。客户端应保持连接打开，直到所有STUN请求都已通过连接发送。</p>



<p>没有计划使用通过STUN请求或中继地址（TURN）获得的任何其他资源，服务器应保持通信打开，并让客户端终止通信，除非通信超时。</p>



<h3>收到STUN消息时如何处理这些消息</h3>



<h4>当STUN服务器接收到消息时，它会检查以下条件</h4>



<ol><li>前2位是0吗</li><li>Magic cookie字段的值正确吗</li><li>消息长度合理吗</li><li>特定方法是否允许使用消息类</li><li>消息值是支持的方法吗</li><li>如果是成功响应或错误响应，则检查transactionID是否与正在处理的当前事务的transactionID相同</li><li>如果检测到错误，消息将被静默丢弃</li><li>如果使用了fingerprint&nbsp;属性，则代理会检查fingerprint&nbsp;属性是否存在以及是否正确</li><li>如果存在任何身份验证机制，STUN将检查身份验证</li></ol>



<h4>检查完之后开始处理请求</h4>



<ol><li>检查一个或多个未知的理解所需属性，如果存在，则发送带有代码403的错误响应，并在列出未知属性的响应中包括unknown-ATTRIBUTE响应。</li><li>进行该方法所需的任何额外检查，并制定成功响应。</li></ol>



<h4>制定成功或错误响应</h4>



<p>发送成功或错误响应的方法与接收请求的方法相同。</p>



<p>成功响应将数据与成功代码200一起发送。</p>



<p>对于ERROR响应，服务器会在响应中添加一个错误代码属性。还向错误响应中添加了描述错误类型的短语。</p>



<p></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/">WebRTC实时通信 （四）| STUN协议工作详情</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e5%9b%9b%ef%bc%89-stun%e5%8d%8f%e8%ae%ae%e5%b7%a5%e4%bd%9c%e8%af%a6%e6%83%85/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （三）&#124; STUN协议</title>
		<link>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/</link>
					<comments>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Fri, 03 Jun 2022 03:17:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2951</guid>

					<description><![CDATA[<p>STUN协议类型 STUN是一种客户端-服务器协议。IT支持两种类型的事务： 第一个是客户端-服务器&#8230; <a href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （三）&#124; STUN协议</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/">WebRTC实时通信 （三）| STUN协议</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<h3>STUN协议类型</h3>



<p>STUN是一种客户端-服务器协议。IT支持两种类型的事务：</p>



<p>第一个是客户端-服务器请求，客户端向服务器发送请求，服务器进行响应。</p>



<p>第二个被称为指示事务，它可以通过客户端或服务器发送，但不会生成响应。</p>



<p>这两个事务都包括一个transactionID，一个随机选择的96位数字。</p>



<p>对于客户端-服务器事务，transactionID充当验证工具，对于指示事务，它可以充当调试工具。</p>



<h3>STUN协议格式</h3>



<p>所有STUN消息都有一个固定的标头，该标头包含以下内容：</p>



<ol><li>a method</li><li>a class</li><li>a transactionID</li></ol>



<p>唯一的强制方法是指示各种请求的绑定方法。绑定方法用于确定NAT响应已分配给客户端的特定绑定。绑定方法也可以用于保持绑定的有效性。</p>



<p>该类指示包括：</p>



<ol><li>request</li><li>success response</li><li>an error response</li><li>an indication</li></ol>



<p>在绑定请求/响应事务中，绑定请求从客户端发送到服务器。为了到达服务器，绑定请求通过客户端和服务器之间的单个NAT或多个NAT。当绑定请求通过NAT时，NAT修改数据包的源传输地址（即源IP地址和源端口）。</p>



<p>结果，当服务器从NAt接收分组时，它将包含最靠近服务器的NAt的公共IP地址和端口。这被称为反射传输地址。</p>



<p>然后，stun服务器将此地址复制到COR映射的地址中，并在stun绑定响应中将其发送回客户端。当该数据包通过NAT时，NAT将修改IP报头中的目的地传输报头，但XOR MAPPED ADDRESS将保持不变。</p>



<p>在这个过程中，客户端学习其XOR-MAPPED-HEADER。</p>



<h3>STUN协议术语</h3>



<p><strong>STUN Agent：</strong>实现STUN协议的实体。实体可以是客户端或服务器</p>



<p><strong>STUN Client：</strong>发送STUN请求并获得STUN响应的实体是STUN客户端</p>



<p><strong>STUN Server：</strong>接收STUN请求并发送STUN响应的实体是STUN服务器</p>



<p><strong>Transport Address：</strong>Ip地址和端口号的组合称为传输地址。</p>



<p><strong>Reflexive Transport Address</strong>：STUN服务器看到的地址。反射传输地址是分配给NAT另一侧客户端的映射地址。</p>



<p><strong>Mapped Address</strong>：与反射地址含义相同。</p>



<p><strong>Long-Term Credentials</strong>：一个用户名和密码，它是服务器和类之间的共享凭据。长期凭据通常由服务提供商（提供服务的服务提供商）授予客户端</p>



<p><strong>Long-Term Password</strong>：是一种长期凭证</p>



<p><strong>Short-Term Credentials</strong>：在STUN交换之前用于在客户端和服务器之间建立连接的临时用户名和密码。它们是用某种机制交换的。</p>



<p><strong>Short-Term Password</strong>：短期密码</p>



<p><strong>STUN indication</strong>：没有收到响应的STUN消息。</p>



<p><strong>Attribute</strong>：可以添加到STUN消息中的Type length Value对象。有两种类型</p>



<ol><li>comprehension required：如果不理解消息，则无法成功处理消息</li><li>comprehension-optional：STUN代理可以安全地忽略</li></ol>



<p><strong><strong>RTO</strong>&nbsp;Retransmission Timeout</strong>：从请求的初始传输到该请求的另一次重新传输之间的时间</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/">WebRTC实时通信 （三）| STUN协议</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/06/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%89%ef%bc%89-stun%e5%8d%8f%e8%ae%ae/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （二）&#124; STUN服务器</title>
		<link>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/</link>
					<comments>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sat, 28 May 2022 02:37:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2933</guid>

					<description><![CDATA[<p>在许多网络中，尤其是在家庭、办公室和企业网络中，单个公共IP地址后面有多个设备。NAT是将私有IP转&#8230; <a href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （二）&#124; STUN服务器</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/">WebRTC实时通信 （二）| STUN服务器</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>在许多网络中，尤其是在家庭、办公室和企业网络中，单个公共IP地址后面有多个设备。NAT是将私有IP转换为公共IP的过程，反之亦然。<br>为了进行p2p通信，每个设备都需要知道另一个设备的IP地址。但是由于NAT，IP地址被隐藏了。设备本身不知道它的公共IP是什么。公共IP地址只有路由器知道。<br>这使得设备之间的通信变得困难。</p>



<p>STUN是一种协议，允许主机应用程序发现网络上是否存在NAT，如果发现，则获取当前连接的公共IP地址和端口。</p>



<figure class="wp-block-image"><img src="https://www.metered.ca/tools/openrelay/assets/images/stun-server-66d31b216429fa6075c338ffa3eaa39b.png" alt="Stun server"/></figure>



<h3>什么是STUN服务器</h3>



<p>STUN服务器允许客户端设备发现自己的公共IP地址。<br>在客户端设备位于NAT设备后面的情况下，通常是路由器，（NAT设备后面有专用IP地址，并且NAT设备通常是路由器通过单个公共IP地址路由所有数据）。<br>客户端设备不知道其公共IP地址是什么，只知道其私有IP地址，这些设备对STUN服务器进行ping，STUN服务器用正在进行ping的IP地址和端口号进行回复。<br>这首先被中继回NAT设备，然后NAT设备将其转发给客户端，客户端设备然后可以与互联网上的另一个设备共享公共IP和端口，以便建立P2P通信。</p>



<h3>STUN服务器的角色</h3>



<p>这在VoIP、视频通话、在线游戏和其他实时通信中非常有用。</p>



<ol><li><strong>发现公共IP和端口</strong><br>位于互联网上的STUN服务器帮助客户端设备发现其公共IP地址和端口号。当客户端向STUN服务器发送请求，然后用设备公共IP和端口号进行回复时，可以实现这一点。</li><li><strong>NAT确定的类型</strong><br>STUN可以用来确定，客户端在NAT的knd后面是什么。这种信息可以用于在不同类型的NAT背后建立有效的通信策略</li><li><strong>连接建立</strong><br>其中，客户端的外部IP地址和端口号是已知的，然后客户端与其对等clinet共享此信息，并且它们可以使用WebRTC或任何其他协议相互建立直接通信。</li></ol>



<h3>STUN服务器的工作原理</h3>



<p>Session Traversal Utilities for NAT（STUN）是一种允许主机应用程序发现网络上存在NAT的协议。当发现NAT时，STUN还允许发现公共IP和本地设备连接的端口。</p>



<p>为了使该协议发挥作用，必须在公共网络上提供一个众所周知的STUN服务器，假设STUN服务器的IP地址是已知的，因为它在公共网络上（通过UDP的DNS STUN或TCP/TLS服务器资源记录的STUN。或手动写入STUN服务器公共地址）。</p>



<p>客户端应用程序向STUN服务器发送绑定请求，并且服务器通过公共STUN服务器的眼睛看到的客户端的公共IP地址和主机进行响应。通过异或（XOR）映射来混淆结果，以避免在尝试执行替代NAT穿越方法时执行深度分组检查的应用层网关对分组内容的转换。</p>



<p>这解决了我们在通过NAT发送数据时发现的许多问题：</p>



<ol><li>客户端发现其对等端的公共IP和端口，并能够与其对等端通信。</li><li>到STUN服务器的出站请求沿着路径在NAT表中创建一个路由条目。使得入站分组在到达公共IP地址时能够找到它们到本地网络上的主机的路径。</li><li>STUN协议定义了一种简单的机制，用于保持ping的有效性，以防止NAT路由条目超时。</li></ol>



<p>有了STUN服务器，当任何两个对等方想要相互连接时，他们将向STUN服务器发送请求，在双方成功响应后，他们可以建立公共IP和端口来交换数据。</p>



<p>STUN消息是使用UDP协议发送的，UDP不是一个可靠的协议。可靠性必须通过应用程序控制重传来实现。STUN服务器本身不在其内部实现任何可靠性方法。如果可靠性是强制性的，则可以使用TCP，并且为了安全起见，可以使用TLS安全层对STUN数据包进行加密。</p>



<h3>STUN服务器的限制</h3>



<p>然而，在实践中，STUN服务器不足以处理所有NAT拓扑和网络条件有时通常在公司环境中，UDP可能会在防火墙设置中被阻止。为了解决这个问题，每当STUN失败时，我们都可以回退到TURN（在NAT周围使用中继进行遍历），这里的关键词是中继。</p>



<p>并非每次都能工作：STUN服务器并不总是能工作，很多时候存在防火墙规则和对称NAT，以及STUN服务器不工作的许多其他情况。</p>



<p>在这些情况下，必须使用其他TURN服务器。TURN服务器替代STUN服务器在STUN服务器不工作的情况下，使用TURN服务器来建立连接。TURN服务器通过服务器中继加密流量，确保连接。</p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/">WebRTC实时通信 （二）| STUN服务器</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%ba%8c%ef%bc%89-stun%e6%9c%8d%e5%8a%a1%e5%99%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WebRTC实时通信 （一）&#124; NAT问题</title>
		<link>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/</link>
					<comments>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Thu, 19 May 2022 06:44:47 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[WebRTC]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=2944</guid>

					<description><![CDATA[<p>1990年，互联网上的设备出现了爆炸式增长。但IPV4是一个32位的数字，因此世界上只有42.9亿个&#8230; <a href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">WebRTC实时通信 （一）&#124; NAT问题</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/">WebRTC实时通信 （一）| NAT问题</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>1990年，互联网上的设备出现了爆炸式增长。但IPV4是一个32位的数字，因此世界上只有42.9亿个唯一的IPV4地址。</p>



<p>我们不能给每个设备提供自己的IP地址，需要对此采取措施。</p>



<p>互联网提出了一个叫做NAT的临时解决方案，就像生活中的大多数事情一样，它成为了一个永久的解决方案，我们到处都有NAT。</p>



<h3>NAT（Network Address Translation）</h3>



<p>NAT或网络地址转换，是一种在设备没有公共IP地址时通过映射IP地址空间以允许流量到达其目的地的方法。</p>



<p>位于网络边缘的NAT设备，该设备将被映射到公共IP地址，并具有本地IP地址表。NAT后面的设备将使用本地IP地址，NAT的公共IP地址将用于NAT后面的所有设备。</p>



<p>因此，任何需要到达NAT后面的任何设备的流量都将被发送到NAT的公共IP，NAT将有一个带有映射的本地地址的设备表，NAT将把流量发送到它后面的本地设备。</p>



<p>对于互联网上的世界来说，NAT后面的所有设备看起来都像一个单独的设备。本地地址应不为外界所知，因此为本地网络保留了一些IP子网，即<br>10.0.0.0 – 10.255.255.255<br>172.16.0.0 – 172.31.255.255<br>192.168.0.0 – 192.168.255.255</p>



<p>这些地址不应在互联网中路由，而是保留用于本地使用，因此可以重复使用。在这些专用ip地址之前，将有一个NAT设备，该设备将具有可全局路由的公共ip地址，并为其网络进行从公共地址到专用地址的转换，反之亦然。</p>



<p>因此，对多个设备使用一个公共IP。</p>



<figure class="wp-block-image"><img src="https://www.metered.ca/tools/openrelay/assets/images/nat_design-9e1c9e3c2adea0d4ac0a0b1a58a60ef6.png" alt="NAT design"/></figure>



<h3>NAT的问题</h3>



<p>通常在家庭或办公室中，互联网服务提供商提供单个公共IP地址，并且所有设备都在该IP地址后面。</p>



<p>为了从外部世界到达特定设备，外部服务器将数据包发送到公共IP地址，然后NAT将数据传输到本地IP地址上的设备，因为NAT知道本地网络上的哪个设备请求了数据。</p>



<p>如果我们想在两个或多个客户端之间建立直接连接，就会出现问题，因为使用NAT，所有客户端都将位于NAT之后。它只知道自己的内部本地IP地址，NAT设备会重写每个UDP数据包中的源端口和地址，以及IP数据包中始发的IP地址。</p>



<p>客户端无法使用其内部IP地址与外部对等方通信，因为连接将失败。因此，应用程序必须发现其公共IP地址，然后与网络外的对等方共享。</p>



<p>然而，仅仅知道公共IP地址并不能解决问题。到达NAT设备的公共IP的任何数据包也必须具有目的端口和NAT表中的条目，该条目可以将其转换为内部IP到内部目的主机IP和端口。</p>



<p>如果该条目不存在（最有可能的情况是客户端直接与来自外部世界的对等方通信），则NAT丢弃数据包，因为NAT无法知道将该数据包发送到哪里（即该数据包需要发送到哪个设备）。</p>



<h3>解决方案</h3>



<p>为了解决这种不匹配，已经发明了各种Traversal技术，即（STUN、TURN和ICE）。这些用于在网络上的对等点之间建立端到端连接。绕过NAT与NAT后面的设备建立连接的技术称为NAT穿越。</p>



<p>在进行WebRTC通信时，节点间会按照如下顺序获取对方的地址：</p>



<ol><li>如果双端在同一个内网，直接用内网IP通信；</li><li>通过STUN服务器，为双端构造可以直接访问的地址，打造一条可以穿透NAT的通路，俗称“打洞”；</li><li>双端通过TURN服务器（中继服务器）进行通信。此时，通信网络的拓扑结构不再是P2P，因为数据其实是经过TURN服务器转发给双端的。</li></ol>



<p></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/">WebRTC实时通信 （一）| NAT问题</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/05/webrtc%e5%ae%9e%e6%97%b6%e9%80%9a%e4%bf%a1-%ef%bc%88%e4%b8%80%ef%bc%89-nat%e9%97%ae%e9%a2%98/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
