The mist javascript client provides a simple API for connecting to and communicating with mist. As the client receives messages from mist it parses and formats the data from the message and then fires corresponding events containing that data that can be handled however you wish.
Creating a new client is very easy, and only has a small amount of configurable options:
# NOTE: by default logs are disabled and set to "DEBUG"
options = {
logging: {
enabled: true
level: "INFO" # 'DEBUG', 'INFO', 'WARN', 'ALERT', 'ERROR', 'SILENT'
}
}
#
mist = new Mist(options)
Once the client is created you simply need to connect it to a running mist server:
mist.connect("ws://127.0.0.1:8888")
If authentication is enabled on the server you must pass an authentication token to connect:
mist.connect("ws://127.0.0.1:8888?X-AUTH-TOKEN=TOKEN")
NOTE: By default mist starts a web socket server running at 127.0.0.1:8888 (as in the example above), which probably wont be the same IP you'll connect to.
To receive messages after you've connected to mist, simply subscribe to tags and then handle the message events the client fires:
tags = mist.subscribe(['hello'])
#
mist.on "mist:data", (e) => # do stuff
The mist client comes with the same basic commands that mist provides, but also has some web socket specific commands, and event specific commands:
Basic commands are what make up the clients mist API:
Command | Description | Example |
---|---|---|
ping |
ping the server to test for an active connection | mist.ping() |
subscribe |
subscribe to messages for all tags in a group |
mist.subscribe(["tag"]) |
unsubscribe |
unsubscribe tags |
mist.unsubscribe(["tag"]) |
list |
list all active subscriptions for client | mist.list() |
Client specific commands deal specifically with the web socket connection to the mist server:
Command | Description | Example |
---|---|---|
connect |
attempt to connect to a running mist server | mist.connect("ws://127.0.0.1:1445") |
reconnect |
attempt to re-connect to the server (fires a special event) | mist.reconnect() |
disconnect |
disconnects from mist | mist.disconnect() |
state |
returns the state of the socket (not connected, open, closing, closed, unknown) | mist.state() |
is_connected |
returns whether or not the connection is open | mist.is_connected() |
The mist client also comes with its own built in event system. These commands allow you to leverage the system to create any types of events you want based on what data you get back from mist:
Command | Description | Example |
---|---|---|
on |
handle event | mist.on(key, handler) |
once |
handle event once | mist.once(key, handler) |
off |
stop handling event | mist.off(key, handler) |
fire |
fire event | mist.fire(key, data, args...) |
events |
list events | mist.events(key) |
# handle an event
mist.once "mist:event", (data) => # do this only once
mist.on "mist:event", (data) => # do this every fire
# fire an event
mist.fire "mist:event", data
Below is a list of all of the events that the mist client will fire:
Command | Fired when |
---|---|
mist:_socket.onopen |
the socket connects |
mist:_socket.reconnect |
the socket reconnects |
mist:_socket.onmessage |
a mist message is received (raw) |
mist:_socket.onerror |
the socket errors |
mist:_socket.onclose |
the socket disconnects |
mist:command.ping |
mist is pinged |
mist:command.subscribe |
deprecated |
mist:command.unsubscribe |
deprecated |
mist:command.publish |
tags are published |
mist:command.publish:[tag,tag,tag] |
specific tags are published |
mist:command.publish:tag |
for each specific tag |
mist:command.list |
subscriptions are listed |
mist:data |
a mist message is received (parses data) |
mist:data.error |
parsed data is/has an error |
mist:metadata.action:create |
metadata is created |
mist:metadata.action:update |
metadata is updated |
mist:metadata.action:destroy |
metadata is destroyed |
NOTE: if the client needs to know when tags are subscribed or unsubscribed they can get a list of all current tags after either of those commands and check to make sure the tags are/aren't there
Most messages that mist publishes will have data. This data can be anything since it is just a string:
"data":"hello world!"
You may want your data to be published in JSON format:
"data":"{\"greeting\":\"hello world!\"}"
Metadata is simply JSON data that contains nested data specifically formatted to appear as RESTful actions to a database record:
"data":"{\"data\":{\"model\":\"Greeting\",\"action\":\"update\", \"document\":{\"greeting\":\"hello mist!\", ...}}}"
A mist "adapter" is nothing more than a grouping of mist event handlers that tailor mist messages to a specific framework or library (Angular, React, ect...).
You can have one adapter that does it all, or perhaps multiple adapters, or even no adapter and just handle specific events as needed. It all really depends on the size/scale and architecture of you application.
#
class exampleMistAdapter
# all an adapter REQUIRES is an instance of mist.
constructor : ( mist, @options={} ) ->
return console.error "A new mist adapter requires an instance of mist" unless mist
# create custom events to handle custom data
mist.on "mist:data", (key, data) =>
if (keys = data?.keys) && (data = JSON.parse(data.data))
# fire an event and handle it somewhere else
if data.log then mist.fire "mist:data.log", data
# or handle an event right here
if data.alert then console.log 'alert!'
# create custom events to handle specific models
mist.on "mist:data.action:create", (key, data) =>
if (keys = data?.keys) && (data = JSON.parse(data.data))
switch data.model
# fire an event and handle it somewhere else
when 'Post' then mist.fire "mist:data.action:create.post"
# or handle the event right here
when 'Comment'
# you may want to subscribe to something only after another condition
# is met. This is a good way to reduce bandwidth
tags = mist.subscribe([ 'like' ])
#
mist.on "mist:data.action:update", (e) =>
# handle events
#
mist.on "mist:data.action:destroy", (e) =>
if (keys = data?.keys) && (data = JSON.parse(data.data))
switch data.model
# fire an event and handle it somewhere else
when 'Post' then mist.fire "mist:data.action:create.post"
# or handle the event right here
when 'Comment'
# its a good idea to unsubscribe to a channel once you're done with it
mist.unsubscribe( like_sub )
Contributions to the mist js client are welcome and encouraged. This is a Nanobox project and contributions should follow the Nanobox Contribution Process & Guidelines.