readme
This commit is contained in:
parent
8d2567cb5a
commit
3407774a1a
20
readme.md
Normal file
20
readme.md
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# tcplexer
|
||||||
|
|
||||||
|
`tcplexer` is a tiny Deno app that receives TCP packets from one socket and
|
||||||
|
copies those packets' contents to them all connected clients on another socket.
|
||||||
|
|
||||||
|
# Example Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SOURCE_PORT=7517 CLIENT_PORT=7518 deno run --allow-net --allow-env tcplexer.ts &
|
||||||
|
|
||||||
|
ffmpeg -i 'rtsp://admin:pass@10.0.0.104' -vn \
|
||||||
|
-i 'rtsp://admin:pass@10.0.0.222' -vn \
|
||||||
|
-ac 1 -filter_complex amerge=inputs=2 \
|
||||||
|
-hide_banner -loglevel error -f mp3 - \
|
||||||
|
| netcat localhost 7517
|
||||||
|
|
||||||
|
vlc 'tcp://localhost:7518'
|
||||||
|
```
|
||||||
|
|
||||||
|
> TODO: show client with mpv or cvlc or something
|
40
tcplexer.ts
Normal file → Executable file
40
tcplexer.ts
Normal file → Executable file
|
@ -1,10 +1,21 @@
|
||||||
|
#!/usr/bin/env -S deno run --allow-net --allow-env
|
||||||
|
|
||||||
import { iterateReader } from "https://deno.land/std@0.145.0/streams/conversion.ts";
|
import { iterateReader } from "https://deno.land/std@0.145.0/streams/conversion.ts";
|
||||||
|
|
||||||
const clients: Set<Deno.Conn> = new Set();
|
const clients: Set<Deno.Conn> = new Set();
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const sourceListener = Deno.listen({ port: 8080 });
|
const sourcePort = parseInt(Deno.env.get("SOURCE_PORT") || "") || 0;
|
||||||
|
const sourceSockOpts = {
|
||||||
|
port: sourcePort,
|
||||||
|
};
|
||||||
|
|
||||||
|
const sourceListener = Deno.listen(sourceSockOpts);
|
||||||
|
console.info(
|
||||||
|
"Listening for source connections on port",
|
||||||
|
(sourceListener.addr as Deno.NetAddr).port,
|
||||||
|
);
|
||||||
for await (const source of sourceListener) {
|
for await (const source of sourceListener) {
|
||||||
console.info("Source connected from", source.remoteAddr);
|
console.info("Source connected from", source.remoteAddr);
|
||||||
for await (const packet of iterateReader(source)) {
|
for await (const packet of iterateReader(source)) {
|
||||||
|
@ -18,13 +29,23 @@ const clients: Set<Deno.Conn> = new Set();
|
||||||
console.info(`Source disconnected from`, source.remoteAddr);
|
console.info(`Source disconnected from`, source.remoteAddr);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error listening for TCP connections on port 8080:", err);
|
console.error("Error listening for source TCP connections:", err);
|
||||||
|
Deno.exit(1);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const clientsListener = Deno.listen({ port: 8081 });
|
const clientPort = parseInt(Deno.env.get("CLIENT_PORT") || "") || 0;
|
||||||
|
const clientSockOpts = {
|
||||||
|
port: clientPort,
|
||||||
|
};
|
||||||
|
|
||||||
|
const clientsListener = Deno.listen(clientSockOpts);
|
||||||
|
console.info(
|
||||||
|
"Listening for client connections on port",
|
||||||
|
(clientsListener.addr as Deno.NetAddr).port,
|
||||||
|
);
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
const conn = await clientsListener.accept();
|
const conn = await clientsListener.accept();
|
||||||
|
@ -38,3 +59,16 @@ const clients: Set<Deno.Conn> = new Set();
|
||||||
console.error("Error listening for TCP connections on port 8081:", err);
|
console.error("Error listening for TCP connections on port 8081:", err);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/* stdin
|
||||||
|
(async () => {
|
||||||
|
for await (const packet of iterateReader(Deno.stdin)) {
|
||||||
|
clients.forEach((client, _v2, _set) =>
|
||||||
|
client.write(packet).catch(() => {
|
||||||
|
console.log(`Client disconnected from`, client.remoteAddr);
|
||||||
|
clients.delete(client);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in a new issue