sails.io.js
)This section of the docs is about the Sails socket client SDK for the browser. It is written in JavaScript and is also usable on the server.
There are also a handful of community projects implementing Sails/Socket.io clients for native iOS, Android, and Windows Phone.
The Sails socket client (sails.io.js
) is a tiny browser library that is bundled by default in new Sails apps. It is a lightweight wrapper that sits on top of the Socket.IO client whose purpose is to make sending and receiving messages from your Sails backend as simple as possible.
The main responsibility of sails.io.js
is to provide a familiar ajax-like interface for communicating with your Sails app using WebSockets/Socket.io. That basically means providing .get()
, .post()
, .put()
, and .delete()
methods that let you take advantage of realtime features while still reusing the same backend routes you're using for the rest of your app. In other words, running io.socket.post('/user')
in your browser will be routed within your Sails app exactly the same as an HTTP POST request to the same route.
In the browser, all that is required to use sails.io.js
is to include the library in a <SCRIPT>
tag. Sails adds the library to the assets/js/dependencies
folder of all new apps, so you can do:
<!--
This will import the sails.io.js library bundled in your Sails app by default.
The bundled version embeds minified code for the Socket.io client as well.
One tick of the event loop after importing this script, a new "eager" socket
will automatically be created begin connecting unless you configure it not to.
-->
<script type="text/javascript" src="/js/dependencies/sails.io.js"></script>
and then use io.socket
as a global variable in subsequent inline or external scripts. For detailed instructions and examples of everyday usage, see io.socket
.
To use the Sails socket client SDK in a Node.js script, you will need to install and require both the sails.io.js
and socket.io-client
libraries:
// Initialize the sails.io.js library with the socket.io-client module,
// which will automatically create and connect a new socket as io.socket
// unless you configure it not to.
var io = require('sails.io.js')( require('socket.io-client') );
See the sails.io.js GitHub repo for more information on using the Sails socket client from Node.js.
sails.io.js
libraryThis section focuses on the most common runtime environment for the JavaScript socket client: the browser. See the
sails.io.js
GitHub repository for help configuring the socket client for use in a Node.js script.
There are two ways to configure Sails' socket client in the browser: using HTML attributes on the <script>
tag or by programmatically modifying the io.sails
object.
The easiest way to configure the four most common settings for the socket client (autoConnect
, environment
, headers
, and url
) is by sticking one or more HTML attributes on the script tag:
<script src="/js/dependencies/sails.io.js"
autoConnect="false"
environment="production"
headers='{ "x-csrf-token": "<%= typeof _csrf !== 'undefined' ? _csrf : '' %>" }'
></script>
This example will disable the eager socket connection, force the client environment to "production" (which disables logs), and set an x-csrf-token
header that will be sent in every socket request (unless overridden). Note that comoposite values like the headers
dictionary are wrapped in a pair of single-quotes. That's because composite values specified this way must be JSON-encoded-- meaning they must use double-quotes around string values and around key names.
Any configuration which may be provided as an HTML attribute may alternately be provided prefixed with data-
(e.g. data-autoConnect
, data-environment
, data-headers
, data-url
). This is for folks who need to support browsers that have issues with nonstandard HTML attributes (or if the idea of using nonstandard HTML attributes just creeps you out). If both the standard HTML attribute and the data-
prefixed HTML attribute are provided, the latter takes precendence.
Note: In order to use this approach for configuring the socket client, if you are using the default Grunt asset pipeline (i.e. which automatically injects script tags), you will need to remove
sails.io.js
from yourpipeline.js
file, and instead include an explicit<script>
tag which imports it.
io.sails
As of Sails v0.12.x, only the most basic configuration options may be set using HTML attributes. If you want to configure any of the other options not mentioned above, you will need to interact with io.sails
programmatically. Fortunately, the approach described above is really just a convenient shortcut for doing just that! Heres how it works:
When you load it on the page in a <script>
tag, the sails.io.js
library waits for one cycle of the event loop before automatically connecting a socket (if io.sails.autoConnect
is enabled; see below). This is to allow any properties that you specify on io.sails
to be set before the socket begins connecting. However, in order to ensure that the io.sails
properties are read before connection, you should put the code setting those properties immediately after the <script>
tag that includes sails.io.js
:
<script src="/js/dependencies/sails.io.js"></script>
<script type="text/javascript">
io.sails.url = 'https://myapp.com';
</script>
<!-- ...other scripts... -->
Normally, the socket client always connects to the server where the script is being served. The example above will cause the eager (auto-connecting) socket to attempt a (cross-domain) socket connection to the Sails server running at https://myapp.com
instead.
Note: If you are using the default Grunt asset pipeline (i.e. which automatically injects script tags), it is a good idea to exclude
sails.io.js
from yourpipeline.js
file, and instead explicitly add a<script>
tag for it. This ensures that your configuration will be applied before the "eager" auto-connecting socket begins connecting-- since it means the inline<script>
tag you are using for programmatic configuration (e.g. which setsio.sails.url = 'https://myapp.com';
) is executed immediately after the socket client.
You can also create and connect client sockets manually using io.sails.connect
. This returns an instance of the SailsSocket
. For more information about rarer / more advanced use cases such as connecting multiple sockets, see SailsSocket.
The sails.io.js
library and its individual client sockets have a handful of configuration options. Global configuration lives in io.sails
. This includes the ability to disable the "eager" socket and default settings for new sockets. Individual sockets can also be configured when they are manually connected-- see io.sails.connect()
for more information on that.
Yes. The Sails socket client can be used to great effect with any front-end framework-- no matter whether it's angular, react, ember, backbone, knockout, jQuery, FishBerry, etc.
No. The Sails socket client is extremely helpful when building realtime/chat features in a browser-based UI, but like the rest of the assets/
directory, it is probably not particularly useful if you are building a native Android app, or an API with no user interface at all.
Fortunately, like every other boilerplate file and folder in Sails, the socket client is completely optional. To remove it, just delete assets/js/dependencies/sails.io.js
.
Under the covers, the socket client (sails.io.js
) emits Socket.io messages with reserved names that, when interpreted by Sails, are routed to the appropriate policies/controllers/etc. according to your app's routes and blueprint configuration.
It is possible to bypass the request interpreter in your Sails app and communicate with Socket.io directly. However, it is not reccommended, since it breaks the convention over configuration philosophy used elsewhere in the framework. The Sails socket client (sails.io.js
) is unobtrusive: it works by wrapping the native socket.io client and exposing a higher level API that takes advantage of the virtual request interpreter in Sails to send simulated HTTP requests. This makes your backend code more reusable, reduces the barrier to entry for developers new to using WebSockets/Socket.io, and keeps your app easier to reason about.
Note: Under very rare circumstances (e.g. compatibility with an existing/legacy frontend using socket.io directly), bypassing the request interpreter is a requirement. If you find yourself in this position, you can use the socket.io client SDK, and then use
sails.io
on the backend to access the raw Socket.io instance. Please embark down this road only if you have extensive experience working directly with Socket.io; and only if you have first reviewed the internals of thesockets
hook (particularly the "admin bus" implementation, a Redis integration that sits on top of socket.io-redis and powers Sails' multi-server support for joining/leaving rooms.)