littlelines / littlechat

A peer-to-peer video chat application made using Phoenix, LiveView, and WebRTC. Want to know how it's made? Read the blog post: https://littlelines.com/blog/2020/07/06/building-a-video-chat-app-in-phoenix-liveview
https://littlechat.app
MIT License
188 stars 20 forks source link

Only works when clients are on same network #13

Open drl123 opened 4 years ago

drl123 commented 4 years ago

Have you tried with the clients on different networks? I have been able to connect several computers and my phone when on my home wifi with video and audio. However anyone outside of my home network can join the room, but cannot get video or audio. I can see the ICE candidates/requests fly by in the console under WS, but the video never connects. I can also see the waiting for user to join box, but we're unable to get connected. So it looks as though the LiveView 'room' is connected, but the webRTC connection fails to negotiate.

Test it by connecting with your phone from cellular network...you'll see the colored box waiting for the other user to join, but they cannot. I'm not familiar enough with webRTC or STUN to troubleshoot. I also don't know if/when a TURN server would be expected/needed, but it looks as though the Erlang package supplies both.

(I should clarify that this was using littlechat production STUN server and demo site...haven't gone through the tutorial yet, but plan to this weekend)

daya commented 4 years ago

@drl123 I think this has been answered here #12

drl123 commented 4 years ago

@daya Thank you. I did read that issue, but was not aware that a TURN server would be required when clients are on two different networks. If that is in fact the case, this issue can be closed.

JesseHerrick commented 4 years ago

@drl123 of course! The app wouldn't be particularly useful if it only worked on the same network 😄. A TURN server is not required when peers are on two different networks, but it may be. It depends on the internal complexity of each peer's network. I'd say try loading up the app with a friend or coworker with a less complex internal network and see if you still have the same issues. In some cases, it may be that you'll need a TURN server to be able to connect.

I have had calls where I'm able to connect easily with others on the other coast of the US without a TURN server, but it really depends on each peer's network.

As I mention in #12, since there is interest in adding a TURN server to the application, I have added that to the backlog. To start with, I will begin adding documentation on a TURN server when I have the chance.

drl123 commented 4 years ago

Thanks for the reply Jesse. I did try with two different remote coworkers and no luck unless we were connected to the office VPN. Perhaps my connection was the issue (since it was the common thing there). I'd be very interested in how to set up the TURN server for situations like these. Can the Elixir server act as both STUN and TURN at the same time? Also, given the bandwidth required, I'm guessing it would be recommended to have the TURN server be a separate node from the chat server in Production (or behind a load balancer). If this idea works, I may have a use for the mechanism in a Production app that might wind up deployed to AWS Fargate or Heroku. It would be a limited number of connected users per room, but it would have to work regardless of the network topology as the users are not very tech savvy.

JesseHerrick commented 4 years ago

@drl123 I will try to get out some documentation and code on running a TURN server alongside the application when I have some time. It will be a little more complex than running the STUN server, but I am hopeful that we will be able to wrap the whole thing up in the same Phoenix app without having to run a separate TURN server on the deployed server.

If you'd like to give it a go yourself, the place to start would be here: https://github.com/processone/stun/blob/master/src/turn.erl.

I would not recommend deploying on Heroku (I can't speak for Fargate), as they don't allow you to open arbitrary ports. If your intention is to keep the whole app self-contained (as it is now - starting the STUN server on launch), your best bet is deploying on a regular server. If you're looking for something fancier, you should be able to deploy this via Docker and Kubernetes as well with a little work.

drl123 commented 4 years ago

Thanks Jesse. I'll check out the linked doc and see if I can make sense of it. I'm definitely a NOOB there. Fargate is sort of 'serverless for servers' in AWS. It allows you to deploy a docker image under an Application Load Balancer and you only get charged for the resources consumed (dynamically)...sort of the way Lambda does for functions. But you can open whatever ports you need. Heroku prevents so much of Elixir/Phoenix horizontal scaling with the walled off dynos (and daily restarts) unless you pay for private spaces, and then you're buying dedicated server resources, so the price of those goes up. I've been eyeing up Fargate as a possible solution here without needing to get into the weeds of K8's since I'm no Dev-Ops expert either.

If I do get time to play with it and get something working, I'll open PR to share what I learn!

jhosteny commented 4 years ago

@drl123 you ought to be able to do this. I deployed Concourse CI on AWS using this terraform module (which includes an ALB for layer 7 routing), coupled with an NLB for layer 4 load balancing, using this module. I used Fargate instead of EC2 for the containers. It's been very reliable.

There's a fairly recent article floating around on how to deploy an Elixir app on ECS, so you could probably mix and match that with the above web app module, which is quite nice. It will allow you deploy automatically using CodePipeline from merges to master of PRs on GH.