如何将 Socket.IO 客户端连接到 Sails.js 服务器
How to connect Socket.IO-Client to Sails.js server?
我花了相当长的时间尝试将 Socket.IO 客户端连接到运行在Sails.js框架上的服务器。客户端基本上是一个简单的JavaScript应用程序,在Raspberry Pi上运行Node.js。
这个想法是一个简单的设备连接到服务器,然后服务器注册设备并订阅消息。设备从服务器接收消息并执行某些操作。我不希望客户端依赖于任何框架,因此,我试图避免使用 Sailsjs-socket.io-client。目前,服务器和客户端都在我的本地计算机上运行。这是代码:
// Server side. Sails.js. DevicesController.js
module.exports = {
handshake: function (req, res) {
if (!req.isSocket) return res.badRequest();
Devices.create({}).exec(function (error, data) {
Devices.subscribe(req.socket, data);
});
return res.ok();
}
};
// Client side
var socket = require('socket.io-client')('http://localhost:1337/devices/handshake');
socket.on('error', function(e) {
console.log(e);
// Here I get 'Invalid namespace'
});
因此,我在客户端收到错误"命名空间无效",如果我是对的,这意味着服务器没有打开"/devices/handshake"。但是,在服务器端,如果我列出现有的房间ID(sails.sockets.rooms(((,我可以看到当客户端尝试连接到服务器时,总是会创建一个新房间。
我尝试使用下面的javascript从浏览器连接到"/devices/handshake",显然它有效。它显然与Sailsjs-socket.io-client一起运行。
io.socket.get('/devices/handshake', function (data, jwres) {
console.log(jwres);
});
io.socket.on('devices', function (data, jwres) {
console.log(data);
});
知道我做错了什么吗?
您似乎在这里混淆了一些概念:即 Socket.io 命名空间、Socket.io 路径和 Sails 路线。 您可以通过浏览 Socket.io 文档来了解有关前两个的更多信息。 就 Sails 而言,要记住的主要事情是它只侦听默认 /
命名空间上的连接;因此,应始终将客户端套接字与以下内容连接:
var socket = require('socket.io-client')('http://localhost:1337');
将/devices/handshake
添加到末尾不会更改套接字尝试连接的 URL;它将始终尝试连接到http://localhost:1337/socket.io
。 相反,这意味着它将尝试使用 Sails 提供的 /devices/handshake
命名空间注册套接字。
另一方面,当您调用 io.socket.get('/devices/handshake')
时,您正在使用 Sails 套接字客户端库在您的应用程序中向该路由发出虚拟请求,就像您使用 AJAX 一样(例如 $.get('/devices/handshake')
在jQuery中(。 这正是创建sails.io.js
的原因 - 它使这种事情变得非常容易! 它也不会真正将您束缚在前端;sails.io.js
所做的只是提供一些包装器,以便通过套接字轻松与 Sails 后端进行通信。 在幕后,io.socket.get
只是使用 Socket.io 客户端.emit()
方法向服务器发送get
事件,其有效负载描述要运行的 Sails 操作的 URL 和参数。 所以,这个:
io.socket.get('/devices/handshake', function(body, res){...})
相当于连接自己的插座并执行此操作:
socket.emit('get', {url: '/devices/handshake'}, function(res){...})
在套接字首次连接时运行套接字逻辑的建议方法是允许套接字在客户端上完全连接,然后从客户端向服务器发出请求(这正是您在第二个代码块中执行的操作(。 要了解有关其背后的原因的更多信息,请参阅 Sails 0.11.x 迁移指南中的此注释。 该说明还解释说,如果由于某种原因必须在服务器连接后立即运行逻辑,则可以
sails.io.on('connect', function (newlyConnectedSocket){})
在你的引导函数(config/bootstrap.js
- Sails.js:同时发布文本输入和一个文件
- Sails.js:我可以将一些服务/模型打包为npm并在Sails.jss应用程序中加载npm吗
- 将对象传递到sails.js中的views/layout.ejs
- sails.js beforeCreate方法只接收required设置为true的模型属性
- 引用单个表的多列 - Sails JS API 模型
- 如何使用javascript访问sails.js模型中的属性
- Sails.js/Waterline.add()和.remove()仅适用于第二次调用
- Sails.js指定要从自动插入中排除的js文件
- 聚合Sails.JS/Waterline中的嵌套模型数据
- Sails.js获得多对多关联计数
- 如何在使用Passport.js和Sails.js注册后重定向到特定位置
- 如何防止sails.js在所有视图中传递req对象
- Sails.js在v1、v2等中分组路由
- sails.js中的模拟/存根全局变量
- 在Sails.js中通过关系填充多对多
- 如何将Sails.js挂钩路由连接到策略
- 使用Sails.JS为静态HTML/JS应用程序提供身份验证
- 跳过Sails.js中的模型验证
- Sails.js日志传输依赖于环境
- 如何观察在 Sails .js 中添加到模型中的新记录