mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Split status listener handling into class
This commit is contained in:
80
app/src/StatusListener.ts
Normal file
80
app/src/StatusListener.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
"use strict";
|
||||
|
||||
import { Channel, Client } from "castv2";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
const NS_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
|
||||
const NS_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
|
||||
const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver";
|
||||
|
||||
|
||||
/**
|
||||
* Creates a connection to a receiver device and forwards
|
||||
* RECEIVER_STATUS updates to the extension.
|
||||
*/
|
||||
export default class StatusListener extends EventEmitter {
|
||||
private client: Client;
|
||||
private clientReceiver: Channel;
|
||||
private clientHeartbeatIntervalId: number;
|
||||
|
||||
constructor (
|
||||
private host: string
|
||||
, private port: number) {
|
||||
|
||||
super();
|
||||
|
||||
this.client = new Client();
|
||||
this.client.connect({ host, port }, this.onConnect.bind(this));
|
||||
|
||||
this.client.on("close", () => {
|
||||
clearInterval(this.clientHeartbeatIntervalId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes status listener connection.
|
||||
*/
|
||||
public deregister (): void {
|
||||
this.clientReceiver.send({ type: "CLOSE" });
|
||||
this.client.close();
|
||||
}
|
||||
|
||||
|
||||
private onConnect (): void {
|
||||
const sourceId = "sender-0";
|
||||
const destinationId = "receiver-0";
|
||||
|
||||
const clientConnection = this.client.createChannel(
|
||||
sourceId, destinationId, NS_CONNECTION, "JSON");
|
||||
const clientHeartbeat = this.client.createChannel(
|
||||
sourceId, destinationId, NS_HEARTBEAT, "JSON");
|
||||
const clientReceiver = this.client.createChannel(
|
||||
sourceId, destinationId, NS_RECEIVER, "JSON");
|
||||
|
||||
clientReceiver.on("message", data => {
|
||||
switch (data.type) {
|
||||
case "CLOSE": {
|
||||
this.client.close();
|
||||
break;
|
||||
}
|
||||
|
||||
case "RECEIVER_STATUS": {
|
||||
// Send update message
|
||||
this.emit("statusUpdate", data.status);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clientConnection.send({ type: "CONNECT" });
|
||||
clientHeartbeat.send({ type: "PING" });
|
||||
clientReceiver.send({ type: "GET_STATUS", requestId: 1 });
|
||||
|
||||
this.clientReceiver = clientReceiver;
|
||||
|
||||
this.clientHeartbeatIntervalId = setInterval(() => {
|
||||
clientHeartbeat.send({ type: "PING" });
|
||||
});
|
||||
}
|
||||
}
|
||||
115
app/src/main.ts
115
app/src/main.ts
@@ -8,21 +8,15 @@ import path from "path";
|
||||
|
||||
import Media from "./Media";
|
||||
import Session from "./Session";
|
||||
import StatusListener from "./StatusListener";
|
||||
import * as transforms from "./transforms";
|
||||
|
||||
import { Channel, Client } from "castv2";
|
||||
|
||||
import { Message } from "./types";
|
||||
|
||||
import { __applicationName
|
||||
, __applicationVersion } from "../package.json";
|
||||
|
||||
|
||||
const NS_CONNECTION = "urn:x-cast:com.google.cast.tp.connection";
|
||||
const NS_HEARTBEAT = "urn:x-cast:com.google.cast.tp.heartbeat";
|
||||
const NS_RECEIVER = "urn:x-cast:com.google.cast.receiver";
|
||||
|
||||
|
||||
// Increase listener limit
|
||||
events.EventEmitter.defaultMaxListeners = 50;
|
||||
|
||||
@@ -188,13 +182,24 @@ async function handleMessage (message: Message) {
|
||||
}
|
||||
|
||||
function initialize (options: InitializeOptions) {
|
||||
const statusListeners = new Map<string, StatusListener>();
|
||||
|
||||
browser.on("serviceUp", (service: dnssd.Service) => {
|
||||
const address = service.addresses[0];
|
||||
const port = service.port;
|
||||
const id = service.txt.id;
|
||||
|
||||
if (options.shouldWatchStatus) {
|
||||
registerStatusListener(address, port, id);
|
||||
const listener = new StatusListener(address, port);
|
||||
|
||||
listener.on("statusUpdate", (status: any) => {
|
||||
sendMessage({
|
||||
subject: "main:/receiverStatusUpdate"
|
||||
, data: { id, status }
|
||||
});
|
||||
});
|
||||
|
||||
statusListeners.set(id, listener);
|
||||
}
|
||||
|
||||
transforms.encode.write({
|
||||
@@ -210,8 +215,8 @@ function initialize (options: InitializeOptions) {
|
||||
browser.on("serviceDown", (service: dnssd.Service) => {
|
||||
const id = service.txt.id;
|
||||
|
||||
if (options.shouldWatchStatus) {
|
||||
deregisterStatusListener(id);
|
||||
if (options.shouldWatchStatus && statusListeners.has(id)) {
|
||||
statusListeners.get(id).deregister();
|
||||
}
|
||||
|
||||
transforms.encode.write({
|
||||
@@ -222,93 +227,3 @@ function initialize (options: InitializeOptions) {
|
||||
|
||||
browser.start();
|
||||
}
|
||||
|
||||
|
||||
interface StatusListener {
|
||||
client: Client;
|
||||
clientReceiver: Channel;
|
||||
}
|
||||
|
||||
// Map of client connections
|
||||
const statusListeners = new Map<string, StatusListener>();
|
||||
|
||||
/**
|
||||
* Creates a connection to a receiver device and forwards
|
||||
* RECEIVER_STATUS updates to the extension.
|
||||
*/
|
||||
function registerStatusListener (
|
||||
host: string
|
||||
, port: number
|
||||
, id: string) {
|
||||
|
||||
const client = new Client();
|
||||
|
||||
const sourceId = "sender-0";
|
||||
const destinationId = "receiver-0";
|
||||
|
||||
let heartbeatIntervalId: number;
|
||||
|
||||
client.connect({ host, port }, () => {
|
||||
const clientConnection = client.createChannel(
|
||||
sourceId, destinationId, NS_CONNECTION, "JSON");
|
||||
const clientHeartbeat = client.createChannel(
|
||||
sourceId, destinationId, NS_HEARTBEAT, "JSON");
|
||||
const clientReceiver = client.createChannel(
|
||||
sourceId, destinationId, NS_RECEIVER, "JSON");
|
||||
|
||||
|
||||
clientReceiver.on("message", data => {
|
||||
switch (data.type) {
|
||||
case "CLOSE": {
|
||||
client.close();
|
||||
break;
|
||||
}
|
||||
|
||||
case "RECEIVER_STATUS": {
|
||||
// Send update message
|
||||
transforms.encode.write({
|
||||
subject: "main:/receiverStatusUpdate"
|
||||
, data: {
|
||||
id
|
||||
, status: data.status
|
||||
}
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clientConnection.send({ type: "CONNECT" });
|
||||
clientHeartbeat.send({ type: "PING" });
|
||||
clientReceiver.send({ type: "GET_STATUS", requestId: 1 });
|
||||
|
||||
heartbeatIntervalId = setInterval(() => {
|
||||
clientHeartbeat.send({ type: "PING" });
|
||||
});
|
||||
|
||||
statusListeners.set(id, {
|
||||
client
|
||||
, clientReceiver
|
||||
});
|
||||
});
|
||||
|
||||
client.on("close", () => {
|
||||
clearInterval(heartbeatIntervalId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes status listener connection for a given receiver
|
||||
* device.
|
||||
*/
|
||||
function deregisterStatusListener (id: string) {
|
||||
const { client, clientReceiver } = statusListeners.get(id);
|
||||
|
||||
// Cleanup
|
||||
clientReceiver.send({ type: "CLOSE" });
|
||||
client.close();
|
||||
|
||||
// Remove from map
|
||||
statusListeners.delete(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user