我一直在这个问题上花费数小时,但无济于事。
我正在Symfony2
构build一个项目,这个项目需要一个上传大文件的模块。 我select了Node.js
和Socket.IO
(我必须从头学习,所以我可能会缺less一些基本的东西)。 我将它们与HTML5 File和FileReader API结合起来,将切片中的文件从客户端发送到服务器。 初步testing表明,这种方法作为一个独立的应用程序运行良好,一切都由Node.js
处理和服务,但与Apache
和Symfony2
集成似乎有问题。
该应用程序有一个不安全和安全的部分。 我的目标是在端口80
和443
上使用Apache
来为Symfony2
构build的应用程序提供大量服务,在端口8080
上使用带有Socket.io
Node.js
来上传文件。 连接到套接字的客户端页面将由Apache
,但套接字将通过Node.js
运行。 上传模块必须通过HTTPS运行,因为页面驻留在具有经过身份validation的用户的安全环境中。
问题是事件使用socket.emit
或socket.send
似乎没有工作。 客户端到服务器,或服务器到客户端,它没有任何区别。 没有任何反应 ,也没有错误。
显示的代码是我的代码的简化版本,没有混乱和敏感的数据。
var httpsModule = require('https'), fs = require('fs'), io = require('socket.io'); var httpsOptions = { key: fs.readFileSync('path/to/key'), cert: fs.readFileSync('/path/to/cert'), passphrase: "1234lol" } var httpsServer = httpsModule.createServer(httpsOptions); var ioServer = io.listen(httpsServer); httpsServer.listen(8080); ioServer.sockets.on('connection', function(socket) { // This event gets bound, but never fires socket.on('NewFile', function(data) { // To make sure something is happening console.log(data); // Process the new file... }); // Oddly, this one does fire socket.on('disconnect', function() { console.log("Disconnected"); }); });
// This is a Twig template, so I'll give an excerpt {% block javascripts %} {{ parent() }} <script type="text/javascript" src="https://my.server:8080/socket.io/socket.io.js"></script> <script type="text/javascript"> var socket = io.connect("my.server:8080", { secure: true, port: 8080 }); // Imagine this is the function initiating the file upload // File is an object containing metadata about the file like, filename, size, etc. function uploadNewFile(file) { socket.emit("NewFile", item); } </script> {% endblock %}
当然,还有更多的应用程序比这个,但这是我卡住的地方。 页面加载完美没有错误,但排放事件永远不会触发或到达服务器(断开事件除外)。 我已经尝试了客户端和服务器上的消息事件,以检查是否只有自定义事件的问题,但也没有工作。 我猜测什么是阻止客户端 – 服务器通信(这不是防火墙,我已经检查)。
我完全不知所措,请帮忙。
经过一番苦心的调试,我发现我的设置有问题。 不妨分享我的发现,虽然他们(我认为)与Node.js,Socket.IO或Apache无关。
正如我所提到的,我的问题已经简化了代码,向您展示我的设置没有混乱。 不过,我通过一个对象来设置客户端,使用属性来配置套接字连接。 像这样:
var MyProject = {}; MyProject.Uploader = { location: 'my.server:8080', socket: io.connect(location, { secure: true, port: 8080, query: "token=blabla" }), // ...lots of extra properties and methods }
问题在于使用location
作为属性名称。 这是Javascript中的一个保留字,在这种情况下会造成一些奇怪的行为。 我发现奇怪的是,一个对象的属性名称不能是保留字,所以我决定测试。 我也注意到我正在引用属性不正确,我忘记连接到套接字时使用this.location
。 所以我把它改成了这个,只是作为一个测试。
var MyProject = {}; MyProject.Uploader = { location: 'my.server:8080', socket: io.connect(this.location, { secure: true, port: 8080, query: "token=blabla" }), // ...lots of extra properties and methods }
但无济于事。 我仍然没有通过套接字获取数据。 所以下一步似乎是合乎逻辑的,这是我受挫的调试风暴。 改变属性名称固定一切!
var MyProject = {}; MyProject.Uploader = { socketLocation: 'my.server:8080', socket: io.connect(this.socketLocation, { secure: true, port: 8080, query: "token=blabla" }), // ...lots of extra properties and methods }
这种方法完美运行,我得到了大量的调试消息。 成功!! 不管是Javascript中的预期行为,还是重写(或者这里发生的任何事情,“滥用”,现在都觉得是一种更好的方式)对象属性,如果你碰巧使用了保留字,我不知道。 我只知道我从现在开始避开他们!
希望它能帮助那里的任何人!