#!/usr/bin/env perl # 20260219 ChatGPT # $Id$ # $HeadURL$ use strict; use warnings; use Mojolicious::Lite -signatures; use Mojo::IOLoop; use IO::Socket::INET; my $udp_port = 1777; # Track websocket clients my %clients; websocket '/stream' => sub ($c) { my $id = sprintf("%x", rand(0xffffffff)); $clients{$id} = $c->tx; $c->on(finish => sub ($c, $code, $reason) { delete $clients{$id}; }); }; # UDP socket (non-blocking) my $udp = IO::Socket::INET->new( LocalPort => $udp_port, Proto => 'udp', ) or die "udp bind $udp_port: $!\n"; $udp->blocking(0); # Register UDP fd with Mojo reactor my $loop = Mojo::IOLoop->singleton; #Mojo::IOLoop->reactor->io($udp => sub ($reactor, $writable) { $loop->reactor->io($udp => sub ($reactor, $writable) { my $datagram = ''; my $peer = $udp->recv($datagram, 2048); return unless defined $peer && length $datagram; $datagram =~ s/\r?\n$//; for my $id (keys %clients) { my $tx = $clients{$id}; next unless $tx && !$tx->is_finished; $tx->send($datagram); } }); #Mojo::IOLoop->reactor->watch($udp, 1, 0); $loop->reactor->watch($udp, 1, 0); get '/' => sub ($c) { $c->render(text => "udp2ws up (udp:$udp_port ws:/stream)\n"); }; app->start;