Node.js + Socket.io + Apache
Posted
技术标签:
【中文标题】Node.js + Socket.io + Apache【英文标题】: 【发布时间】:2011-12-02 16:45:32 【问题描述】:我正在寻找一种通过以下方式集成 的方法: 我希望 apache 继续提供 html / JS 文件。 我想让 node.js 监听端口 8080 上的连接。像这样:
var util = require("util"),
app = require('http').createServer(handler),
io = require('/socket.io').listen(app),
fs = require('fs'),
os = require('os'),
url = require('url');
app.listen(8080);
function handler (req, res)
fs.readFile(__dirname + '/index.html',
function (err, data)
if (err)
res.writeHead(500);
return res.end('Error loading index.html');
res.writeHead(200);
res.end(data);
);
io.sockets.on('connection', function (socket)
socket.emit('news', hello: 'world' );
socket.on('my other event', function (data)
socket.emit('ok 1', hello: 'world' );
);
socket.on('clientMSG', function (data)
socket.emit('ok 2', hello: 'world' );
);
);
如果我访问连接到此服务器的 HTML,它可以工作,但我需要访问 mydomian.com:8080/index.html。 我想要的是能够访问 mydomian.com/index.html。并能够打开一个套接字连接:
<script>
var socket = io.connect('http://mydomain.com', port: 8080);
socket.on('news', function (data)
console.log(data);
socket.emit('my other event', my: 'data from the client' );
);
socket.on('connect', function (data)
console.log("connect");
);
socket.on('disconnect', function (data)
console.log("disconnect");
);
//call this function when a button is clicked
function sendMSG()
console.log("sendMSG");
socket.emit('clientMSG', msg: 'non-scheduled message from client' );
</script>
在这个例子中,当我转到 URL 中的 8080 端口时,我不得不使用 fs.readFile 。
有什么建议吗?谢了。
【问题讨论】:
尝试使用 nginx 而不是 apache,特别是如果您只想提供静态文件。 Apache 为每个请求启动一个新线程,这部分违背了使用节点的理念/原因。 【参考方案1】:从 Apache 端口 80 提供静态内容,并通过端口 8080 上的 Socket.IO 服务器提供动态/数据内容。您的 Socket.IO 应用中不需要 app = require('http').createServer(handler)
Apache 80 端口 |-------------|客户|------------| Socket.IO端口8080
var io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket)
io.sockets.emit('this', will: 'be received by everyone');
socket.on('clientMSG', function (from, msg)
console.log('I received a private message by ', from, ' saying ', msg);
);
socket.on('disconnect', function ()
sockets.emit('user disconnected');
);
);
【讨论】:
感谢您的回复。我做了更改,现在看起来客户端没有获取 /socket.io/socket.io.js 文件。这个文件是由 Node 中的 HTTP 服务器提供的吗? 我搞定了。将路径更改为 /socket.io-client/dist/socket.io.js 谢谢! 是的,您需要在端口 80 上从您的 Apache 静态服务器提供 socket.io.js 并执行类似 的操作您的客户端代码 idk 如果这会有所帮助,但如果你在当前目录中 npm install socket.io,在 :8888 运行应用程序,你需要编写脚本 src="mydomain:8888/socket.io/socket.io.js",即使它是在 node_modules/socket.io/lib/socket.io.js 这不会触发“同源策略”违规吗? en.wikipedia.org/wiki/Same_origin_policy【参考方案2】:AWS + APACHE + NODEJS + SOCKET.IO + ANGULARJS
服务器端 这适用于我在端口 80 和 NodeJS 上运行 apache 的生产服务器 在端口 8000 上。通过您想要的选项更改 NodeJS 端口...
-
在 /var/www/html 为 NodeJS 服务器的文件创建一个名为“nodejs”的文件夹
在不同于 80 的端口上运行 Nodejs,例如端口 8000
执行命令:a2enmod proxy_http
执行命令:a2enmod proxy_wstunnel
将接下来的 2 行放在以下文件的末尾:/etc/apache2/apache2.conf
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
将接下来的 12 行放在以下文件的末尾:/sites-available/000-default.conf (如果您创建了其他网站,请将这些行放在那里)
RewriteEngine On
RewriteCond %REQUEST_URI ^socket.io [NC]
RewriteCond %QUERY_STRING transport=websocket [NC]
RewriteRule /.* ws://localhost:8000/$1 [P,L]
RewriteCond %HTTP:Connection Upgrade [NC]
RewriteRule /(.*) ws://localhost:8000/$1 [P,L]
ProxyPass /nodejs http://localhost:8000/
ProxyPassReverse /nodejs http://localhost:8000/
ProxyPass /socket.io http://localhost:8000/socket.io
ProxyPassReverse /socket.io http://loacalhost:8000/socket.io
ProxyPass /socket.io ws://localhost:8000/socket.io
ProxyPassReverse /socket.io ws://localhost:8000/socket.io
sudo service apache2 重启
客户端 我使用以下library 在 AngularJS 中实现 Socket.io,但是 我认为本指南对于 socket.io 技术的基本 javascript 实现也很有用。
调用我的 php 服务器:example.com 调用 NodeJS 服务器:example.com/nodejs 调用 NodeJS Socket:example.com
希望能帮到你!
【讨论】:
谢谢,我能够解决在 apache 服务器上运行 socket.io 的问题。 使用您的出色答案和其他研究,您可以在此处找到带有 certbot、CORS 标头和解释的完整示例(如果没有您的建议,我无法做到!):***.com/questions/9831594/…【参考方案3】:您可以继续从 Apache 提供页面,但您需要在 node.js/socket.io 中启用 CORS:
index.html(由 Apache 提供)
<script src = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.js"></script>
<script>
const socket = io("ws://your.domain.com:8080");
<script>
app.js(在 nodejs 中):(启用 CORS)
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http,
cors:
origin: "*",
methods: ["GET", "POST"]
);
http.listen(8080);
【讨论】:
以上是关于Node.js + Socket.io + Apache的主要内容,如果未能解决你的问题,请参考以下文章
HTTP 状态代码 200 但页面未加载 Node.js Socket.io -- 使用 Socket.io 的 Node.js 教程,Daniel Nill,fs.readFile(),socket
Node.js socket.io.js 未找到或 io 未定义