wss连接的一些坑
<p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">转自:<a href="https://blog.csdn.net/qq_28804275/article/details/80891921" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">https://blog.csdn.net/qq_28804275/article/details/80891921</a></p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 过去的这一个多月里,我的工(开)作(发)任务转战回了游戏。短短的一个月里,催着输出两款h5游戏,再加上对接、联调,想想真是够辛(ku)苦(bi)的。本人负责后端,也就是服务端这块的游戏主流程输出。去年下半年,在前任大佬的带领下,做过一两款棋牌类的手游,虽然目前的运营状况不太乐观。不过好在,过去学的那点皮毛也还没丢光,所以这次写h5后端总体还算顺畅。至于怎么用Java来写游戏,下来如果有时间会整理下这块的思路和知识。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">关于WebSocket,<a href="https://www.baidu.com/s?wd=%E7%BB%B4%E5%9F%BA%E7%99%BE%E7%A7%91&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">维基百科</a>是这样介绍的:</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 以前,很多网站为了实现实时推送技术,所用的技术都是轮询。轮询是在特定的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端。这种传统的模式带来的缺点很明显,即浏览器需要不断的向服务器发出请求,然而HTTP请求包含较多的请求头信息,而其中真正有效的数据只是很小的一部分,显然这样会浪费很多的带宽等资源。在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。<br style="box-sizing: border-box; outline: 0px;"> WebSocket是一种在单个TCP连接上进行全双工通讯的协议,使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> WebSocket 协议在2008年诞生,2011年成为国际标准,现在几乎所有浏览器都已经支持了。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">WebSocket</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 简单来说,WebSocket减少了客户端与服务器端建立连接的次数,减轻了服务器资源的开销,只需要完成一次HTTP握手。整个通讯过程是建立在一次连接/状态中,也就避免了HTTP的非状态性,服务端会一直与客户端保持连接,直到双方发起关闭请求,同时由原本的客户端主动询问,转换为服务器有信息的时候推送。所以,它能做实时通信(聊天室、直播间等),其他特点还包括:</p><ul style="box-sizing: border-box; outline: 0px; margin-bottom: 24px; list-style: none; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(51, 51, 51);"><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">建立在 TCP 协议之上,服务器端的实现比较容易</li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器</li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">数据格式比较轻量,性能开销小,通信高效</li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">可以发送文本,也可以发送二进制数据</li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">没有同源限制,客户端可以与任意服务器通信</li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 32px;">协议标识符是ws(如果加密,则为wss),服务器网址就是 URL</li></ul><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">HTTP、HTTPS、WS、WSS</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 差点就跑题了。这不,由于业务需求,上头要求新出的h5游戏要配上Https。无奈,公司小,没有专业的运维人员,所以只能由我们这些开发“猿”顶上了,以为会很顺畅,但一连串的问题没想到也才刚刚开始。因此本文,就是用来记录这些踩过的“坑”,希望可以让后人少走点弯路。</p><h3 style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-bottom: 16px; font-size: 22px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 30px;"><a name="t0" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a><a name="t0" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a>1. 申领证书</h3><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 公有云服务器上,一般大家都习惯使用Nginx来做反向代理。首先,配置Https,需要我们到专业的CA机构去申领证书,这个证书大多数情况下都是要钱的,但其实也有免费的(有效期1年),例如利用国内的阿里云或者腾讯云就可以很方便的申请这证书。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> - <a href="https://link.jianshu.com/?t=https%3A%2F%2Fcommon-buy.aliyun.com%2F%3Fspm%3D5176.7968328.911106.btn1.40594ebfQd767s%26commodityCode%3Dcas%23%2Fbuy" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">阿里云 - Https证书申请</a><br style="box-sizing: border-box; outline: 0px;"> - <a href="https://link.jianshu.com/?t=https%3A%2F%2Fbuy.cloud.tencent.com%2Fssl%3FfromSource%3Dssl%26from%3DqcloudHpHeaderSsl" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">腾讯云 - Https证书申请</a></p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">阿里云Https证书申请</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">阿里云 - SSL证书申领</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> <span style="box-sizing: border-box; outline: 0px; font-weight: 700;">PS:</span> 通过阿里云申领免费版SSL证书有点套路,藏得有点深。点击以上链接进入后,如果在“证书类型”一栏中没找到“免费型DV SSL”,那么请依次点击第三栏的“选择品牌”中的“Symantec”,然后回到第一栏的“证书类型”,点击出现的第三个选项“增强型OV SSL”,之后就会在“证书类型”中出现我们需要的第二项:“免费型DV SSL”。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">阿里云免费型SSL证书申领过程</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">腾讯云Https证书申请</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">腾讯云 - SSL证书申领</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 确认申领、购买之后,下来还需要绑定我们的域名(注意:免费型的SSL证书一般仅支持绑定一个一级域名或者子域名,通配符的证书一般是需要花钱的),以及进行域名身份验证等操作。等这两步都完成之后,只需要等待CA机构扫描认证之后,我们就可以拿到真正的证书了。</p><h3 style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-bottom: 16px; font-size: 22px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 30px;"><a name="t1" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a><a name="t1" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a>2. 配置Https</h3><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 下载好证书压缩包并解压之后,一般里面有IIS、Apache和Nginx三款主流服务器的ssl证书,这里我们也仅需要Nginx的证书。首先,将证书里Nginx文件夹下的1_{域名}<em style="box-sizing: border-box; outline: 0px;">bundle.crt 和2</em>{域名}.key复制到我们服务器上的指定位置(假设在/root/ssl/下面)。基于Nginx的Https配置还是比较简单的,参考如下。</p><pre style="box-sizing: border-box; outline: 0px; padding: 8px; margin-bottom: 24px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-x: auto; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0);"> </pre><ol style="box-sizing: border-box; outline: 0px; margin-bottom: 24px; list-style: none; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(51, 51, 51);"><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">server {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">#listen 80; #如果需要同时支持http和https</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">listen 443 ssl http2;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">listen [::]:443 ssl http2;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_certificate "/root/ssl/1_{域名}_bundle.crt";</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_certificate_key "/root/ssl/2_{域名}.key";</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_session_cache shared:SSL:1m;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_session_timeout 10m;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_ciphers HIGH:!aNULL:!MD5;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">ssl_prefer_server_ciphers on;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"> </li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">server_name {域名};</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">location / {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">proxy_pass http://localhost:{代理端口};</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li></ol><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 附:下面是开启Nginx的Gzip压缩的配置,有需要的也可以参考。</p><pre style="box-sizing: border-box; outline: 0px; padding: 8px; margin-bottom: 24px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-x: auto; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0);"> </pre><ol style="box-sizing: border-box; outline: 0px; margin-bottom: 24px; list-style: none; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(51, 51, 51);"><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">http {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip on;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_disable "msie6";</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_min_length 1k;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_vary on;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_proxied any;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_comp_level 6;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_buffers 16 8k;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_http_version 1.1;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">gzip_types application/font-woff text/plain application/javascript application/json text/css application/xml text/javascript image/jpg image/jpeg image/png image/gif image/x-icon;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"> </li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">server {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;"># 这里是server相关的配置</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li></ol><h3 style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-bottom: 16px; font-size: 22px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 30px;"><a name="t2" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a><a name="t2" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a>3. 事故现场</h3><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 完成以上步骤后,按道理来说,h5游戏确实可以通过https的形式来打开了,简单测试后的确没啥问题,然后大家也就这样愉快的下班了。不过正如“墨菲定律”所说的:“凡事只要有可能出错,那就一定会出错”。<a href="https://www.baidu.com/s?wd=%E6%9E%9C%E4%B8%8D%E5%85%B6%E7%84%B6&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">果不其然</a>,一段时间后,测试就在群里反馈,某段时间后h5游戏就无法加载正常进行下去了,一看时间,正是配完Https之后开始出现的问题。没办法,于是连忙打开电脑,开始排查解决问题,直觉告诉我要先打开浏览器的控制面板,果不其然,立刻发现了问题。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">浏览器控制面板异常信息</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">Mixed Content: The page at ‘https://{域名}.com/‘ was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ‘ws://{ip}:{port}/‘. This request has been blocked; this endpoint must be available over WSS.<br style="box-sizing: border-box; outline: 0px;">Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 好家伙,这种情况,毫无疑问我们就需要使用 wss:// 安全协议了,于是立即联系h5客户端,把连接服务端webscoket的形式由ws:// 改为 wss:// 。本以为这样就解决了,没想到一段时间后下一个问题又来了。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">扩展:关于 ws 和 wss</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">WebSocket可以使用 ws 或 wss 来作为统一资源标志符,类似于 HTTP 或 HTTPS。其中 ,wss 表示在 TLS 之上的 WebSocket,相当于 HTTPS。默认情况下,WebSocket的 ws 协议基于Http的 80 端口;当运行在TLS之上时,wss 协议默认是基于Http的 443 端口。说白了,wss 就是 ws 基于 SSL 的安全传输,与 HTTPS 一样样的道理。所以,如果你的网站是 HTTPS 协议的,那你就不能使用 ws:// 了,浏览器会 block 掉连接,和 HTTPS 下不允许 HTTP 请求一样。</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> h5客户端改成wss连接后,测试发现还是无法正常游戏。无奈,再次打开浏览器面板,果然,又看到一个新的问题。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">浏览器控制面板异常信息</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">WebSocket connection to ‘wss://{ip}:{port}/‘ failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 之前在Http的情况下,客户端一直是用ip+port的形式来连接服务端,当然了也不会出现什么问题。很明显,在更改成Https后,若还是以这种方式连接服务端,浏览器就会报 SSL 协议错误,这很明显就是证书的问题。如果这时候还用 IP + 端口号 的方式连接 WebSocket ,是根本就没有证书存在的(即使我们在Nginx配置了SSL证书,但这种方式其实是不会走Nginx代理的),所以在生成环境下,更推荐大家用域名的方式来连接。于是,立刻又联系前端,再一次做更改,修改为 wss://{域名}/ 进行连接。我以为这样就真的解决了,没想到还是too young too simple,没一会下个问题又来了,测试反馈的结果还是不可以,第三次打开浏览器控制面板,果然又是一个新的错误信息。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">浏览器控制面板异常信息</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">WebSocket connection to ‘wss://{域名}/‘ failed: Error during WebSocket handshake: Unexpected response code: 400</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 看到这个错误信息后,确定这是服务端返回的400响应。既然可以请求到服务端,就说明客户端这边是没有问题的,那么问题最可能出在客户端和服务端之间。由于中间层使用了Nginx做转发,所以导致服务端无法知道这是一个合法的WebSocket请求。于是立刻查找了网上资料,在Nginx配置文件加入了以下配置,成功解决了这个问题。</p><pre style="box-sizing: border-box; outline: 0px; padding: 8px; margin-bottom: 24px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-x: auto; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0);"> </pre><ol style="box-sizing: border-box; outline: 0px; margin-bottom: 24px; list-style: none; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(51, 51, 51);"><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">server {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">location / {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">proxy_pass http://localhost:{port};</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">proxy_http_version 1.1;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">proxy_set_header Upgrade $http_upgrade;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">proxy_set_header Connection "upgrade";</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li></ol><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 接着,连忙拿域名进行再次连接测试,终于看到了101 Switching Protocols的响应Status Code。就这样,也算是终于解决完在 HTTPS 下以 wss://{域名}/ 的方式连接 WebSocket的一系列问题。不过,最后这其中还有一个小问(插)题(曲)。</p><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;">关于Nginx中的WebSocket配置</p><blockquote style="box-sizing: border-box; outline: 0px; padding-top: 16px; padding-right: 16px; padding-left: 16px; margin-bottom: 24px; border-left: 8px solid rgb(221, 223, 228); background: rgb(238, 240, 244); overflow: auto; word-break: normal; color: rgb(51, 51, 51); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif, SimHei, SimSun; font-size: 14px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; font-size: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 自1.3 版本开始,Nginx就支持 WebSocket,并且可以为 WebSocket 应用程序做反向代理和负载均衡。WebSocket 和 HTTP 是两种不同的协议,但是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 协议头将连接从 HTTP 升级到 WebSocket,当客户端发过来一个 Connection: Upgrade请求头时,其实Nginx是不知道的。所以,当 Nginx 代理服务器拦截到一个客户端发来的 Upgrade 请求时,需要我们显式的配置Connection、Upgrade头信息,并使用 101(交换协议)返回响应,在客户端、代理服务器和后端应用服务之间建立隧道来支持 WebSocket。<br style="box-sizing: border-box; outline: 0px;"> 当然,还需要注意一点,此时WebSocket 仍然受到 Nginx 缺省为60秒的 proxy_read_timeout 配置影响。这意味着,如果你有一个程序使用了 WebSocket,但又可能超过60秒不发送任何数据的话,那么需要增大超时时间(配置proxy_read_timeout),要么实现一个Ping、Pong的心跳消息以保持客户端和服务端的联系。使用Ping、Pong的解决方法有额外的好处,如:可以发现连接是否被意外关闭等。</p></blockquote><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 关于最后的这个小问题,主要是在对Nginx配置的时候将location=/的请求都进行了proxy_pass(转发)。由于h5客户端的文件打包成静态文件后,存放在服务器的指定目录下(这里假设在/root/html/static/路径下),这也就导致这种配置的情况下Nginx无法正常代理指定目录下的客户端文件。于是再一次修改配置文件,添加location配置,最终完美解决所有问题。</p><pre style="box-sizing: border-box; outline: 0px; padding: 8px; margin-bottom: 24px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; overflow-x: auto; font-size: 14px; line-height: 22px; color: rgb(0, 0, 0);"> </pre><ol style="box-sizing: border-box; outline: 0px; margin-bottom: 24px; list-style: none; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(51, 51, 51);"><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">location /static/ {</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">root /root/html;</code></p></li><li style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-left: 40px;"><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"><code style="box-sizing: border-box; outline: 0px; font-family: "Source Code Pro", "DejaVu Sans Mono", "Ubuntu Mono", "Anonymous Pro", "Droid Sans Mono"; border-radius: 4px;">}</code></p></li></ol><h3 style="box-sizing: border-box; outline: 0px; margin-top: 8px; margin-bottom: 16px; font-size: 22px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 30px;"><a name="t3" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a><a name="t3" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(78, 161, 219); cursor: pointer;"></a>4. 写在最后</h3><p style="box-sizing: border-box; outline: 0px; margin-bottom: 16px; font-family: "Microsoft YaHei", "SF Pro Display", Roboto, Noto, Arial, "PingFang SC", sans-serif; color: rgb(79, 79, 79); line-height: 26px; overflow-x: auto;"> 事故<a href="https://www.baidu.com/s?wd=%E4%B8%80%E6%B3%A2%E4%B8%89%E6%8A%98&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd" target="_blank" style="box-sizing: border-box; outline: 0px; color: rgb(103, 149, 181); text-decoration-line: none; cursor: pointer;">一波三折</a>,现在回想起当时,也是一把辛酸史,一把辛酸泪(累)啊。所以仅以此文,记录下我的填“坑”过程。</p><p></p>
页:
[1]