NAT KEEP ALIVE WILL NOT WORK unless you then relay *EVERYTHING* through dish ...
Google "UDP hole punching" or "peer to peer across NAT." With Dish arbitrating the connection, UPnP and open ports generally should not be required with most router/firewalls.
Some firewalls are too strict for this to work, but it usually works. The technique is used by many products these days. I haven't traced the Dish traffic out, but always assumed Dish was using this technique.
I can say you do not always need UPnP, open ports, or DMZ mode. I have none of that enabled on either of my networks and Sling works fine across both, so Dish is either relaying the the stream or using hole punching.
This is over-simplified but the general flow:
Reciever connects to Dish.
NAT keep alive tells Dish where the reciever is located.
The client connects to Dish and asks to connect to the receiver.
Dish tells receiver to start UDP session.
Dish analyzes UDP packet looking for unusual port randomization, etc.
If all OK, Dish tells receiver to send the client a UDP packet on port XXXX.
Router/firewall sets up UDP session and starts looking for responses from client.
Dish tells the client to send the receiver a "response" with proper port info.
Client send UDP "response" firewall is already looking for it and routes to the receiver.
Two way session between client and receiver is now established across NAT.