Skip to main content
Version: 7.3.2

WebSocket

API Reference: Net.WebSocket

WebSocket creates a websocket client. It is very simple to use. After you pass url parameter in constructor(this is mandatory) a websocket instance is created and Open event triggers.

Reopen WebSocket

You can't send data after the websocket is closed. If you need, you must create a new web socket instance. Websocket isn't reopened automatically when send method calls if the websocket is closed.

import PgWebSocketDesign from "generated/pages/pgWebSocket";
import { Route, Router } from '@smartface/router';
import WebSocket from "@smartface/native/net/websocket";
import Blob from "@smartface/native/global/blob";

export default class PgWebSocket extends PgWebSocketDesign {
webSocket: WebSocket;
private disposeables: (() => void)[] = [];
constructor(private router?: Router, private route?: Route) {
super({});
}
initWebSocket() {
this.webSocket = new WebSocket({
url: "wss://javascript.info/article/websocket/demo/hello",
});
this.disposables.push(
this.webSocket.on('open', () => {
console.log("Websocket opened.");
console.log("Sending a string...");
this.webSocket.send({ data: "some string" });
}),
this.webSocket.on('close', (params: { code: number; reason?: string }) => {
console.log(`Websocket closed with exit code: `, params.code);
}),
this.webSocket.on('message', (e: { string: string; blob: Blob }) => {
console.log("Message received.");
console.log("Message: ", e.string);
this.webSocket.close({ code: 1000 });
})
);
}
onLoad() {
super.onLoad();
this.initWebSocket();
}
onHide() {
super.onHide();
this.disposeables.forEach((item) => item());
}
}

Mobile Device Optimizations

Since the socket will be opened\&managed in the mobile device, it is crucial to consider memory and battery usage when dealing with socket connections. The checklist:

  • The socket should be closed when the page is exited
  • The socket should be closed when the application is minimized to background
  • The socket should be re-opened when the application is maximized again
  • The events you are using should be disposed when you exit the page. Otherwise they will stay there forever.

More info about power heads-up can be found at Battery Optimization Page:

Battery Optimization

Closing WebSocket server on Page Exit

To handle page exit methods, there are two you can work with:

  • Hide event in the page (onHide)
  • routeDidExit event in the router
import PgWebSocketDesign from "generated/pages/pgWebSocket";
import { Route, Router } from '@smartface/router';
import WebSocket from "@smartface/native/net/websocket";
import Blob from "@smartface/native/global/blob";

export default class PgWebSocket extends PgWebSocketDesign {
webSocket: WebSocket;
private disposeables: (() => void)[] = [];
constructor(private router?: Router, private route?: Route) {
super({});
}
initWebSocket() {
this.webSocket = new WebSocket({
url: "wss://javascript.info/article/websocket/demo/hello",
});

this.disposables.push(
this.webSocket.on('open', () => {
console.log("Websocket opened.");
console.log("Sending a string...");
this.webSocket.send({ data: "some string" });
}),
this.webSocket.on('close', (params: { code: number; reason?: string }) => {
console.log(`Websocket closed with exit code: `, params.code);
}),
this.webSocket.on('message', (e: { string: string; blob: Blob }) => {
console.log("Message received.");
console.log("Message: ", e.string);
this.webSocket.close({ code: 1000 });
})
);
}
onLoad() {
super.onLoad();
this.initWebSocket();
}
onHide() {
super.onHide();
this.websocket.close({code: 1000}); // Or enter a different code for your different close reason.
this.disposeables.forEach((item) => item());
}
}
caution

The initWebSocket method have been moved from onLoad to onShow since we will be closing & reopening the connection now.

  • onLoad method is only triggered once when the stackRouter is set. It will only be called again when the Stack is destroyed completely.
  • onShow method will be called every time the page is entered.

If you have your webSocket instance on a different place like another file(module), using the routeDidExit method will be better for you. webSocket.close will be triggered when the page is exited on the router side.

// routeDidExit method
import { NativeStackRouter, NativeRouter } from '@smartface/router';
import Page1 from 'pages/page1'; //Change this with your page
import WebSocketServer from 'services/websocket';
//Assuming this is the module instance

const router = NativeRouter.of({
path: "/",
isRoot: true,
routes: [
NativeStackRouter.of({
path: "/pages",
routes: [
Route.of({
path: "/pages/page1",
build: (router, route) => new Page1(router, route),
routeDidExit: () => WebSocketServer.close()
});
]
})
]
});
info

Same with onShow-onHide, alternatively you can use routeDidEnter event to create your WebSocket instead.

More info is located at page activities documentation:

Page Life-Cycle

Closing WebSocket Server on Background & Reopen

Just like page events, we also need to consider application state in the mobile device. The newer operating systems on mobile devices will mostly terminate the socket connections on their own, but they won't do it gracefully or the way you want them to be closed.

Therefore, we will be using Minimize and Maximize events on Application.

info

You can listen to Application Events in your page. Do not forget to dispose them afterwards.

To get the current page on another place in the project, you can refer to:

Implement those two events in your page file:

scripts/pages/pgWebSocket.ts
import PgWebSocketDesign from "generated/pages/pgWebSocket";
import { Route, Router } from '@smartface/router';
import WebSocket from "@smartface/native/net/websocket";
import Blob from "@smartface/native/global/blob";

export default class PgWebSocket extends PgWebSocketDesign {
webSocket: WebSocket;
private disposeables: (() => void)[] = [];
constructor(private router?: Router, private route?: Route) {
super({});
}
initWebSocket() {
this.webSocket = new WebSocket({
url: "wss://javascript.info/article/websocket/demo/hello",
});
this.disposables.push(
this.webSocket.on('open', () => {
console.log("Websocket opened.");
console.log("Sending a string...");
this.webSocket.send({ data: "some string" });
}),
this.webSocket.on('close', (params: { code: number; reason?: string }) => {
console.log(`Websocket closed with exit code: `, params.code);
}),
this.webSocket.on('message', (e: { string: string; blob: Blob }) => {
console.log("Message received.");
console.log("Message: ", e.string);
this.webSocket.close({ code: 1000 });
})
);

/* Application events to listen status changes */
this.disposables.push(
Application.on('minimize', () => {
this.webSocket.close();
}),
Application.on('maximize', () => {
this.webSocket = new WebSocket({ url: "wss://yourUrl" });
})
);
/* Application events to listen status changes */
}


onLoad() {
super.onLoad();
this.initWebSocket();
}
onHide() {
super.onHide();
this.disposeables.forEach((item) => item());
}
}