mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-12 10:39:57 +00:00
Move app StatusListener to discovery module
This commit is contained in:
@@ -1,86 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
import { Channel, Client } from "castv2";
|
|
||||||
import { EventEmitter } from "events";
|
|
||||||
|
|
||||||
import { NS_CONNECTION
|
|
||||||
, NS_HEARTBEAT
|
|
||||||
, NS_RECEIVER } from "./Session";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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?: NodeJS.Timeout;
|
|
||||||
|
|
||||||
constructor(host: string, port: number) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.client = new Client();
|
|
||||||
this.client.connect({ host, port }, this.onConnect.bind(this));
|
|
||||||
|
|
||||||
this.client.on("close", () => {
|
|
||||||
clearInterval(this.clientHeartbeatIntervalId!);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.client.on("error", () => {
|
|
||||||
clearInterval(this.clientHeartbeatIntervalId!);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes status listener connection.
|
|
||||||
*/
|
|
||||||
public deregister(): void {
|
|
||||||
if (this.clientReceiver) {
|
|
||||||
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": {
|
|
||||||
this.emit("receiverStatus", data.status);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "MEDIA_STATUS": {
|
|
||||||
this.emit("mediaStatus", 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" });
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
import { EventEmitter } from "events";
|
||||||
|
|
||||||
|
import { Channel, Client } from "castv2";
|
||||||
import mdns from "mdns";
|
import mdns from "mdns";
|
||||||
|
|
||||||
import { sendMessage } from "../lib/nativeMessaging";
|
import { sendMessage } from "../lib/nativeMessaging";
|
||||||
@@ -7,7 +10,9 @@ import { sendMessage } from "../lib/nativeMessaging";
|
|||||||
import { ReceiverStatus } from "../types";
|
import { ReceiverStatus } from "../types";
|
||||||
import { Message } from "../messaging";
|
import { Message } from "../messaging";
|
||||||
|
|
||||||
import StatusListener from "./chromecast/StatusListener";
|
import { NS_CONNECTION
|
||||||
|
, NS_HEARTBEAT
|
||||||
|
, NS_RECEIVER } from "./chromecast/Session";
|
||||||
|
|
||||||
|
|
||||||
interface CastTxtRecord {
|
interface CastTxtRecord {
|
||||||
@@ -29,28 +34,36 @@ const browser = mdns.createBrowser(mdns.tcp("googlecast"), {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function onBrowserServiceUp(service: mdns.Service) {
|
function onBrowserServiceUp(service: mdns.Service) {
|
||||||
// Ignore without txt record
|
// Ignore without txt record / name
|
||||||
if (!service.txtRecord) {
|
if (!service.txtRecord || !service.name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const txtRecord = service.txtRecord as CastTxtRecord;
|
const txtRecord = service.txtRecord as CastTxtRecord;
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
subject: "main:receiverDeviceUp"
|
subject: "main:receiverDeviceUp"
|
||||||
, data: {
|
, data: {
|
||||||
receiverDevice: {
|
receiverDevice: {
|
||||||
host: service.addresses[0]
|
host: service.addresses[0]
|
||||||
, port: service.port
|
, port: service.port
|
||||||
, id: txtRecord.id
|
, id: service.name
|
||||||
, friendlyName: txtRecord.fn
|
, friendlyName: txtRecord.fn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBrowserServiceDown(_service: mdns.Service) {
|
function onBrowserServiceDown(service: mdns.Service) {
|
||||||
// TODO: Fix service down detection
|
// Ignore without name
|
||||||
|
if (!service.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const txtRecord = service.txtRecord as CastTxtRecord;
|
||||||
|
sendMessage({
|
||||||
|
subject: "main:receiverDeviceDown"
|
||||||
|
, data: { receiverDeviceId: service.name }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.on("serviceUp", onBrowserServiceUp);
|
browser.on("serviceUp", onBrowserServiceUp);
|
||||||
@@ -73,7 +86,7 @@ export function startDiscovery(options: InitializeOptions) {
|
|||||||
const statusListeners = new Map<string, StatusListener>();
|
const statusListeners = new Map<string, StatusListener>();
|
||||||
|
|
||||||
function onStatusBrowserServiceUp(service: mdns.Service) {
|
function onStatusBrowserServiceUp(service: mdns.Service) {
|
||||||
if (!service.txtRecord) {
|
if (!service.name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,23 +94,110 @@ export function startDiscovery(options: InitializeOptions) {
|
|||||||
service.addresses[0], service.port);
|
service.addresses[0], service.port);
|
||||||
|
|
||||||
listener.on("receiverStatus", (status: ReceiverStatus) => {
|
listener.on("receiverStatus", (status: ReceiverStatus) => {
|
||||||
|
if (!service.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sendMessage({
|
sendMessage({
|
||||||
subject: "main:receiverDeviceUpdated"
|
subject: "main:receiverDeviceUpdated"
|
||||||
, data: {
|
, data: {
|
||||||
receiverDeviceId: service.txtRecord.id
|
receiverDeviceId: service.name
|
||||||
, status
|
, status
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
statusListeners.set(service.txtRecord.id, listener);
|
statusListeners.set(service.name, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStatusBrowserServiceDown(_service: mdns.Service) {
|
function onStatusBrowserServiceDown(service: mdns.Service) {
|
||||||
// TODO: Fix service down detection
|
if (!service.name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const listener = statusListeners.get(service.name);
|
||||||
|
listener?.deregister();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stopDiscovery() {
|
export function stopDiscovery() {
|
||||||
browser.stop();
|
browser.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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?: NodeJS.Timeout;
|
||||||
|
|
||||||
|
constructor(host: string, port: number) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.client = new Client();
|
||||||
|
this.client.connect({ host, port }, this.onConnect.bind(this));
|
||||||
|
|
||||||
|
this.client.on("close", () => {
|
||||||
|
clearInterval(this.clientHeartbeatIntervalId!);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.client.on("error", () => {
|
||||||
|
clearInterval(this.clientHeartbeatIntervalId!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes status listener connection.
|
||||||
|
*/
|
||||||
|
public deregister(): void {
|
||||||
|
if (this.clientReceiver) {
|
||||||
|
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": {
|
||||||
|
this.emit("receiverStatus", data.status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "MEDIA_STATUS": {
|
||||||
|
this.emit("mediaStatus", 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" });
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user