Apache Node.js Socket.io

由于系统是WAMP,由外包过渡过来的。在Apache设置反向代理比较不友善;且自chrome4.7以后,大部分socket请求必须基于SSL协议传输。


前提:给项目加个长连接,做个进度条。

困境:请求协议为HTTP, 如果加入SSL协议,这不仅增加一笔费用;对旧项目并不友好,php项目全是基于http的,而已Apache设置SSL估计又是折磨人。

解决:使用Apache设置反向代理,解决浏览器无法连接websocket的问题;使用localhost之前请求来解决安全性问题。


本文内容

  • 项目环境技术栈
  • 后端Socket服务设计
  • 试错过程
  • 提交方案
  • 运行项目
  • 参考网站

1.项目环境技术栈

  • 构架时,后端代理前端压缩包文件。
  • 长连接使用socket.io。

2.后端Socket服务设计

后端对外不开放,不需要使用反向代理。内容如下所示(不全):

const express = require('express');
const http = require('http');
const socketio = require('socket.io');

const app = express();
const server = http.Server(app);
const io = socketio(server);
//加载前端页面
app.use(express.static(path.join(__dirname, 'build')));

io.on('connection', (sock) => {
  console.log('Client connected');

  sock.on('heartbeat', (payload) => {
    payload.nodeName = name;
    sock.emit('heartbeat', payload);
  });

  sock.on('disconnect', () => {
    console.log('Socket Disconnected');
  });
});

server.listen(+port, '0.0.0.0', (err) => {
  console.log(`Node [${name}] listens on http://127.0.0.1:${port}.`);
});

3.试错过程

由于之前没做过,好尴尬了。看了几个小时socket.io文档直接使用了,所以踩的坑会比较多。

  • 由于chrome4.7后,对安全策略进行变化 。先了解浏览器对websocket的长连接的策略。

node代理
使用node http-proxy-middleware代理socket过程,在本地(都是基本localhost)完美运行。然后上传运行代理,并开放外网端口,运行结果如下所示:

[HPM] Proxy created: /  ->  http://localhost:8787
[HPM] Subscribed to http-proxy events:  [ 'error', 'close' ]
[HPM] Proxy created: /  ->  http://localhost:8787
[HPM] Subscribed to http-proxy events:  [ 'error', 'close' ]
  • 显示代理成功,在服务器测试socket连接正常。但使用外网访问时,如下的错误
Uncaught (in promise) DOMException: Only secure origins are allowed. http://goo.gl/lq4gCo
  • 分析过程:
  1. 在服务器端测试时,可以通过是因为:它们之间是localhost请求,能过浏览器安全策略。
  2. 服务器外网地址跟localhost在服务器在有网卡代理,localhost与外网交互,没安全策略的,它也相当于一个本地请求。
  3. 当在外网访问网页端时,网页在"/"链接中,地址是外网地址。外网与localhost将无法通过浏览器安全策略。

使用Apache代理过程

  • 先实现一个小目标,实现一个简单的Http反向代理。
#不给别人get到你的代理
ProxyRequests off 
    <Location />
        ProxyPass http://127.0.0.1:30003/
        ProxyPassReverse /
    </Location>

  • 那么接下去代理,想下Apache代理比较全的帖子,我擦,完全没有提到Socket,就加入个mod_proxy_connect,说不定以后能使用SSL呢。
  • 那只有去官网找,意淫术,socket的请求协议为WS,去httpd.conf搜下(找下)proxy-ws*,果然找到mod_proxy_wstunnel,就是这货了。
  • 接下去的看,只能在2.4.5以上版本使用。呸,然后查下2.4.3才发行。直接用别管它。
    Compatibility: |Available in httpd 2.4.5 and later
  • 在httpd.conf文件中,加载这模块
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

WAMP

  • 有时,没什么毛病,它就是不给你运行。这个迷之原因,炸了没。别扯什么底层代理实现过程。
  • 使用颜色分析过程,一般是:红色->橙色->绿色。不行的话,红色那状态会比较快,然后停到橙色。
  • 使用重复启动法,重复重启。当红色停留比较久时,那就可能成功了。

4.提交方案

下面将使用Apache反向代理,使网页端与API接口变成localhost间的请求,原理图如下所示,网页端服务跟API服务将在内部服务器中:


1. 将网页端服务使用反向代理出来

//httpd.conf
Listen 30003
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule proxy_http_module modules/mod_proxy_http.so

//httpd-vhosts.conf

<VirtualHost *:30003>
    RewriteEngine On
    RewriteCond %{HTTP:Connection} Upgrade [NC]
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteRule /(.*) ws://127.0.0.1:3030/$1 [P,L]

    ProxyRequests off
    <Location />
        ProxyPass http://127.0.0.1:3030/
        ProxyPassReverse /
    </Location>
</VirtualHost>

2.前后端分离,前端使用socket.io-client,代码如下所示:

import openSocket from 'socket.io-client';
const socket = openSocket(); //不用设置任意参数

 socket.on('heartbeat', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });

5.运行项目

  • 访问服务器端口30003地址,其实是反向访问localhost:3000。localhost地址之间socket长连接无fuck。
  • 不安全是Http协议的长连接。



6.参考网站

如果socket请求跨源,一定要有SSL设置?,不太清楚

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容