Fliplet.Socket
Open a real-time, bidirectional connection to the Fliplet API via the fliplet-socket package. The package exposes a single global, Fliplet.Socket, which returns a Socket.IO v2 client wired up to the correct API server, with the user’s auth token already plumbed through and the right transport selected for the current environment.
Use Fliplet.Socket whenever an app needs real-time updates: live dashboards, presence, chat, push-style notifications, or any cross-client event broadcast.
Install
Add the fliplet-socket dependency to your screen or app resources. The package provides the Fliplet.Socket global and bundles its own socket.io-client (no extra dependencies needed).
Why use Fliplet.Socket vs. raw WebSocket
It’s tempting to reach for new WebSocket(...) or import a fresh socket.io-client build. Don’t — Fliplet.Socket solves three problems you’d otherwise have to solve yourself, and it solves them correctly for every Fliplet environment (dev, staging, EU, US, on-prem):
- Server URL discovery. The Fliplet API host changes per region and per environment.
Fliplet.SocketreadsFliplet.Env.get('apiUrl')so the same code runs unmodified againstapi.fliplet.test,api.fliplet.com, and any regional API. A hand-rollednew WebSocket('wss://api.fliplet.com/...')will break the moment the app is shipped to a different region. - Auto-authentication. Pass
{ login: true }and the socket callsFliplet.User.getAuthToken()and emits theloginhandshake on every connect. The user is automatically joined to a privateuser-${id}room on the server, so server-side code can target a single user withio.to('user-' + userId).emit(...)without any client-side wiring. - Dev/prod transport selection. In development Fliplet sits behind a Classic Load Balancer that does not support WebSocket frames.
Fliplet.Socketdetects this viaFliplet.Env.get('environment')and falls back to long-polling automatically; in production it useswebsocket. A raw WebSocket would silently fail to connect on local dev environments.
A single shared connection is also reused across the page — calling Fliplet.Socket() multiple times returns the same socket, so two widgets on the same screen don’t open two physical connections.
Fliplet.Socket(options)
(Returns a Socket.IO Socket)
Get (and lazily create) the shared socket connection.
Usage
// Anonymous connection — no login handshake
var socket = Fliplet.Socket();
// Authenticated connection — joins user-${id} room on the server
var socket = Fliplet.Socket({ login: true });
- options (Object) Optional configuration map.
- login (Boolean) When
true, emits theloginevent with the current user’s auth token after everyconnect. The server responds withloginSuccess(andsocket.loggedInbecomestrue) orloginError. Defaultfalse. - transports (Array<String>) Override the transports list. Provide
['websocket']to force WebSocket,['polling']to force long-polling, or['polling', 'websocket']to allow upgrade. Default['polling']in development,['websocket']in all other environments.
- login (Boolean) When
The socket is a singleton: the first call creates it, subsequent calls return the same instance regardless of the options passed.
Fliplet.Socket.disconnect()
Disconnect the shared socket and clear the cached instance. The next call to Fliplet.Socket() will open a new connection.
Fliplet.Socket.disconnect();
Fliplet.Socket automatically calls disconnect() on the window’s unload event, so most apps never need to call this directly. Call it manually when you want to forcibly drop a connection — for example, after the user logs out of an embedded app.
socket.to(room).emit(event, data)
Send an event to every client in a named room via the server. This is a thin wrapper that emits a forward event the server then re-broadcasts.
var socket = Fliplet.Socket({ login: true });
socket.to('project-42').emit('comment-added', {
text: 'Looks good!',
author: 'Alice'
});
- room (String, required) The room to broadcast to. Throws if missing.
- event (String) The event name remote clients will listen for.
- data (any) JSON-serialisable payload.
To put a client into a room so it receives forwarded events, emit the built-in join event:
socket.emit('join', 'project-42');
socket.on('comment-added', function(payload) {
// Triggered when any client in the room calls socket.to('project-42').emit('comment-added', ...)
});
Built-in events
The Fliplet API socket server understands the following events.
Outbound (client → server)
| Event | Payload | Description |
|---|---|---|
login |
authToken (String) |
Authenticate the connection. Emitted automatically when the socket is created with { login: true }. |
logout |
— | Leave the authenticated user’s rooms. Connection stays open. |
join |
room (String) |
Add this socket to a named room. |
forward |
{ room, event, data } |
Broadcast an event to every socket in room. Use socket.to(room).emit(event, data) instead — it’s the supported shape. |
Inbound (server → client)
| Event | Payload | Description |
|---|---|---|
connect |
— | The socket has connected. If { login: true } was passed, the auth handshake is sent immediately after this event. |
loginSuccess |
— | Auth handshake succeeded. The server has joined this socket to user-${userId} and to a room named after the auth token. socket.loggedIn is now true. |
loginError |
{ status, message } |
Auth handshake failed (missing token, unknown region, or no matching session). |
forwardError |
{ status, message } |
A forward was emitted without a room. |
disconnect |
reason (String) | The socket has disconnected. Socket.IO will attempt to reconnect automatically. |
Beyond these, you can listen for any custom event your server-side or app-action code emits.
Vue 3 example: live presence indicator
Subscribe in onMounted, unsubscribe in onUnmounted so the screen doesn’t accumulate handlers across navigations.
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const onlineUsers = ref([]);
let socket;
function handlePresence(payload) {
onlineUsers.value = payload.users;
}
onMounted(() => {
socket = Fliplet.Socket({ login: true });
socket.emit('join', 'office-floor-3');
socket.on('presence:update', handlePresence);
});
onUnmounted(() => {
if (!socket) return;
socket.off('presence:update', handlePresence);
// Don't call socket.disconnect() — other widgets on the screen may share the connection.
});
</script>
<template>
<ul>
<li v-for="user in onlineUsers" :key="user.id"></li>
</ul>
</template>
A few rules worth highlighting:
- Always remove your listener in
onUnmountedwithsocket.off(event, handler). Forgetting this is the #1 cause of “the same toast fires three times after I navigate back”. - Don’t call
Fliplet.Socket.disconnect()on screen unmount. The socket is shared. Disconnect only when the user is really leaving the app or logging out. - Check
socket.connectedbefore emitting if your code can run before the firstconnectresolves. Socket.IO buffers emits while disconnected, so this is rarely needed — but it’s the safe option for high-rate emits.
Vue 3 example: send and receive chat messages
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const messages = ref([]);
const draft = ref('');
const room = 'chat-room-7';
let socket;
function onMessage(msg) {
messages.value.push(msg);
}
function send() {
if (!draft.value.trim()) return;
socket.to(room).emit('chat:message', {
text: draft.value,
sentAt: Date.now()
});
draft.value = '';
}
onMounted(() => {
socket = Fliplet.Socket({ login: true });
socket.emit('join', room);
socket.on('chat:message', onMessage);
});
onUnmounted(() => {
socket.off('chat:message', onMessage);
});
</script>
<template>
<div>
<ul><li v-for="(m, i) in messages" :key="i"></li></ul>
<input v-model="draft" @keyup.enter="send" />
</div>
</template>
Vue 3 example: connection state
Fliplet.Socket is a Socket.IO socket, so the standard connect / disconnect / reconnect events are available for surfacing online/offline state to the user.
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const status = ref('connecting');
let socket;
const onConnect = () => { status.value = 'online'; };
const onDisconnect = () => { status.value = 'offline'; };
const onReconnect = () => { status.value = 'online'; };
onMounted(() => {
socket = Fliplet.Socket({ login: true });
socket.on('connect', onConnect);
socket.on('disconnect', onDisconnect);
socket.on('reconnect', onReconnect);
if (socket.connected) status.value = 'online';
});
onUnmounted(() => {
socket.off('connect', onConnect);
socket.off('disconnect', onDisconnect);
socket.off('reconnect', onReconnect);
});
</script>
<template>
<span :class="`status status--${status}`"></span>
</template>
Common patterns
- Targeting one user from a server-side App Action. When a client connects with
{ login: true }, the server places it in a room nameduser-${userId}. Server-side code can push to that user withio.to('user-' + userId).emit('notification', payload)— no client-sidejoinrequired. - Targeting one device/session. The server also joins the socket to a room named after the auth token, so a server emit to
io.to(authToken).emit(...)reaches that single device even if the user is logged in elsewhere. - Broadcasting between two clients. Have both clients
socket.emit('join', 'shared-room'), then either side cansocket.to('shared-room').emit('event', data)to reach the other. - Cleaning up after logout. Emit
socket.emit('logout')to leave the user’s rooms without dropping the socket. Follow withFliplet.Socket.disconnect()if you also want to close the underlying connection.
Notes
- Built on Socket.IO v2.1.1. The full client API is documented at socket.io/docs/v2/client-api — anything that works on a standard Socket.IO socket works here.
- The connection is lazy: importing
fliplet-socketdoes not open a connection. The first call toFliplet.Socket()does. socket.upgradeis disabled, so the socket will not silently switch transport mid-session. Choose your transport at construction.