如何将Socket.IO-Client连接到Sails.js服务器? [英] How to connect Socket.IO-Client to Sails.js server?

查看:127
本文介绍了如何将Socket.IO-Client连接到Sails.js服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了很长时间尝试将Socket.IO-Client连接到运行在Sails.js框架上的服务器。客户端基本上是一个在Raspberry Pi上运行Node.js的简单JavaScript应用程序。

I've spent quite a while trying to connect Socket.IO-Client to a server running on Sails.js framework. The client is basically a simple JavaScript application running with Node.js on Raspberry Pi.

想法是一个简单的设备连接到服务器,然后服务器注册设备并为消息订阅它。设备从服务器接收消息并执行某些操作。我不希望客户端依赖于任何框架,因此,我试图避免使用Sailsjs-socket.io-client。目前,服务器和客户端都在我的本地计算机上运行。以下是代码:

The idea is that a simple device connects to a server, the server then registers the device and subscribes it for messages. The device receives a message from the server and performs some actions. I don't want the client to be dependant on any framework and, for that reason, I am trying to avoid using Sailsjs-socket.io-client. At the moment both server and the client are running on my local machine. Here is the code:

// 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()),我可以看到,当客户端尝试连接到服务器时,总是会创建一个新房间。

So, I get the error 'Invalid namespace' on the client side and, if I'm right, it means that the server doesn't have '/devices/handshake' open. However, on the server side if I list existing room ids (sails.sockets.rooms()), I can see that a new room is always created, when the client tries to connect to the server.

我尝试使用下面的javascript从浏览器连接到'/ devices / handshake',显然它有效。它显然与Sailsjs-socket.io-client一起运行。

I tried to connect to '/devices/handshake' from a browser with the javascript below and apparently it worked. It obviously runs with Sailsjs-socket.io-client though.

io.socket.get('/devices/handshake', function (data, jwres) {
  console.log(jwres);
});
io.socket.on('devices', function (data, jwres) {
  console.log(data);
});

任何想法我做错了什么?

Any ideas what am I doing wrong?

推荐答案

这里看起来很混乱:Socket.io名称空间,Socket.io路径和Sails路由。通过查看 Socket.io docs ,您可以了解前两个方面的更多信息。就Sails而言,要记住的主要事情是侦听默认 / 命名空间中的连接;因此,您应始终连接客户端套接字:

It seems that you're confusing a few concepts here: namely Socket.io namespaces, Socket.io paths and Sails routes. You can learn a bit more about the first two by looking through the Socket.io docs. The main thing to keep in mind as far as Sails is concerned is that it only listens for connections on the default / namespace; therefore, you should always connect client-side sockets with:

var socket = require('socket.io-client')('http://localhost:1337');

/ devices / handshake 添加到end不会更改套接字尝试连接的URL;它总是会尝试连接到 http:// localhost:1337 / socket.io 。相反,它意味着它将尝试使用 / devices / handshake 命名空间注册套接字,Sails没有提供。

Adding the /devices/handshake onto the end doesn't change the URL that the socket is attempting to connect to; it will always try to connect to http://localhost:1337/socket.io. Instead, it means that it will try to register the socket with the /devices/handshake namespace, which Sails isn't providing.

另一方面,当你调用 io.socket.get('/ devices / handshake')时,你正在使用Sails套接字客户端库来在您的应用中向该路径发出虚拟请求,就像您使用了AJAX一样(例如 $。get('/ devices / handshake')在jQuery中)。这正是创建 sails.io.js 的原因 - 它使这种事情变得非常简单!它也没有真正把你绑在前端;所有 sails.io.js 确实提供了一些包装器,以便通过套接字轻松与Sails后端进行通信。在封面下, io.socket.get 只是使用Socket.io-client .emit()方法向服务器发送 get 事件,其中有效负载描述要运行的Sails操作的URL和参数。所以,这个:

On the other hand, when you call io.socket.get('/devices/handshake'), you're using the Sails socket client library to make a virtual request to that route in your app, just as if you'd used AJAX (e.g. $.get('/devices/handshake') in jQuery). This is precisely why sails.io.js was created--it makes this sort of thing very easy! It's also not really tying you down on the front-end; all sails.io.js does is provide some wrappers to make it easy to communicate with Sails backends via sockets. Under the covers, io.socket.get is simply using the Socket.io-client .emit() method to send a get event to the server, with a payload describing the URL and parameters of the Sails action to run. So, this:

io.socket.get('/devices/handshake', function(body, res){...})

相当于连接自己的套接字并执行此操作:

is equivalent to connecting your own socket and doing this:

socket.emit('get', {url: '/devices/handshake'}, function(res){...})

首次连接时为套接字运行逻辑的推荐方法是允许套接字在客户端上完全连接,然后从客户端向服务器发出请求(正是您在第二个代码块中正在执行的操作)。要了解有关此背后原因的更多信息,请参阅本说明在Sails 0.11.x迁移指南中。该说明还解释了如果必须在服务器连接时由于某种原因立即运行逻辑,则可以执行

The recommended approach for running logic for a socket when it first connects is to allow the socket to connect fully on the client, and then make a request from the client to the server (exactly what you're doing in your second code block). To read more about the reasoning behind this, see this note in the Sails 0.11.x migration guide. That note also explains that if you must run the logic immediately upon server connection for some reason, you can do

sails.io.on('connect', function (newlyConnectedSocket){}) 

in你的引导函数( config / bootstrap.js )。

in your bootstrap function (config/bootstrap.js) .

这篇关于如何将Socket.IO-Client连接到Sails.js服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆