I've wanted to work with WebSockets
for a while and struggled to find a good project to implement them on. Then, just about the time that I did find 'that' project, I ran into PieSocket.
They are self-described as "WebSockets as a Service."
Here, I was able to implement communications between browsers on separate machines with ease.
Code
Here, I'd like to share my SocketService
...
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
export interface SocketMessage {
type: string;
payload: any;
};
@Injectable()
export class SocketService {
websocket: any;
constructor() {
this.connectWebSocket();
}
connectWebSocket = (): void => {
const CLUSTER_ID: string = 'FROM-PIE-SOCKET--CLUSTER-ID';
const CHANNEL_ID: string = 'FROM-PIE-SOCKET--CHANNEL-ID';
const API_KEY: string = 'FROM-PIE-SOCKET--API-KEY';
try {
this.websocket = new WebSocket(`wss://${ CLUSTER_ID }.piesocket.com/v3/${ CHANNEL_ID }?api_key=${ API_KEY }`);
this.websocket.onopen = () => {
const initMessage: SocketMessage = {
type: 'initial',
payload: ''
};
this.publish(initMessage);
};
} catch (error) {
console.log(error);
}
};
messagesOfType = (type: string): Observable<SocketMessage> => {
return new Observable(observer => {
this.websocket.onmessage = (eventString: MessageEvent) => {
const event: SocketMessage = JSON.parse(eventString.data);
if (event.type === type) {
observer.next(event);
}
};
});
};
errorHandler = (): Observable<Event> => {
return new Observable(observer => {
this.websocket.onerror = (event: Event) => {
observer.next(event);
};
});
};
publish = (message: SocketMessage) => {
try {
this.websocket.send(JSON.stringify(message));
} catch (error) {
console.log(error);
}
};
}
Since I was just testing things, I've got the cluster id, channel, and api key stored within the code. If this were a project for a client, I would have secured these details.
If you read my article Angular Communication Between Tabs, you would realize that the "initialize" (in this case connectWebSocket
) is pulled out to make testing easier. Additionally, I have added a try-catch block to allow for error handling.
The function messagesOfTypes
returns an observable that watches the websocket.onmessages
and returns data, when needed.
There's an errorHandler
function that is used by the initialization try-catch.
The publish
function does just what it says.
Implementation
Here's the code to publish
...
this.socketService.publish({ type: 'student', payload: 'bob fornal'});
And, here's the code to use messagesOfType
...
this.broadcast.messagesOfType('student').subscribe((message: SocketMessage) => {
const student: string = message.payload;
this.publishStudents();
});
Summary
Having wanted to work with WebSockets
for a while, I found one. Additionally, I ran into PieSocket who made the learning process easy.
This code shows how I was able to implement communications between browsers on separate machines with ease.