WebRTC video works locally but not remotely - html

There's quite a bit of code involved, so I threw what I had into a temporary github repo:
https://github.com/stevendesu/webrtc-failure
I'm learning WebRTC and long-term want to do some fancy stuff, but for now I'm starting simple: send a video from one computer to another. Unfortunately this failed. Here's what I've set up so far...
On a development server I own I installed coturn to act as a STUN/TURN server
I created two pages: broadcast.html and watch.html. The former creates a media stream and (using Socket.IO) sends the connection details to a signaling server. The latter gets the connection details from the signaling server and attempts to watch the stream
After running npm install you can npm start to run the server and access it at localhost:2017.
So here's what works:
After opening broadcast.html you are prompted for a broadcast ID. You can type anything here, but I usually just do an incrementing number - so I start with "1"
After entering a broadcast ID, and a short delay, you see your webcam feed on the screen. Looking at the console you can see several messages have been exchanged with the Socket.IO server
If you open watch.html in a new tab, you are prompted for a broadcast ID. Enter the same ID as before
After entering the ID, and a short delay, you will see your webcam feed on the new tab. Looking at the console you can see that the earlier ICE candidates and offer details were sent by the Socket.IO server and the watcher responded with an answer
Returning to the broadcast tab, you can verify that the answer was received and processed. A connection has now been established
For bonus points, the pc variable is in the global scope (PeerConnection) so in the console you can establish an RTCDataChannel and send messages between the tabs directly (bypassing the Socket.IO server)
Here's what doesn't work:
For now (and I know why this is, so it's not a concern) only the FIRST person to enter an ID into the watch.html page can actually see the broadcast. It's not "broadcast", it's just peer-to-peer, and once one connection has been established then future connections fail
My issue: if I open watch.html from a different computer or device (either on the same network or a different network) then the video never plays
In the latter case if you look at the console you'll see the offer and ice candidates are delivered to the watcher, the watcher generates an answer, the answer is sent back to the broadcaster, and the watcher sees a media stream added to the PeerConnection. This media stream is converted to a blob URL and assigned as the source of the video element.
I'm at a point where I don't know how to progress. I don't know why the video isn't showing up.

your watch.js does not emit ice candidates. That is one possible cause. If that doesn't help you can use chrome://webrtc-internals to figure out what is going on -- see here for a description of how to interpret what is going on.
You might also want to look into modernizing your code. https://webrtc.github.io/samples/src/content/peerconnection/pc1/ is a fairly simple example of modern WebRTC code using promises and other things like using srcObject instead of the deprecated URL.createObjectURL.

Related

Global Payments Hosted Payment Page Integration - sandbox and prod POSTs back to merchantUrl delays

I'm running our Hosted Payment Page integration the same as the official js lib:
https://github.com/globalpayments/rxp-js/blob/master/examples/hpp/process-a-payment-embedded-autoload-callback.html
All is good except this bit is very slow for the response to come back to our side with the approved/failed transaction:
https://github.com/globalpayments/rxp-js/blob/9909985b96ab5ed945614affad5f3739827f956b/examples/hpp/process-a-payment-embedded-autoload-callback.html#L16
e.g. The form gets presented, you enter your card details and click submit (on HPP) and then the 3D secure shows, does it's thing but around 4 mins later the result come back within the answer line (the above link, line 16). I'm not sure why it's so slow. Sandbox and Production are the same.
I'm opening a support case anyway, but if anyone has any ideas.
Thanks,
Gavin.
Was the firewall on the box blocking https / port 443 from the public. Obviously the libs do something. All was instant when off.

NetSuite SuiteScript 2.0 Integration with external hook

I need to setup EPL2 label printing from Netsuite. Unfortunately the company this is for is very small and they don't have much money to spend, hence they cannot buy a $1000 label printing solution.
The current system uses a linux server that then sends a file to one of the CUPS print server queues using the linux cat command. From there it goes to a Intel NetportExpress 10/100 Print Server and then to the Argox V1000+ label printer. This is via a corporate network ip address.
Instead I started looking at some cheap options:
Popup a browser window with content type text/plain and use a suitelet to populate that browser window with the EPL2 label printer codes. Then open a print dialog window so that the user can print to the label printer driver. This requires installation of the label printer driver for all users. Sadly I could not get this to print a label.
Integration from Netsuite via a Restlet to an external python application (on Linux) that can then perform the linux cat command needed to print the label. The Restlet works nice, but unfortunately there does not seem to be a way to have some sort of hook that fires when a new label custom record arrives. Therefore I have to keep on polling the Restlet from Python every 2 seconds to see if a new label is waiting to be printed. I started running this about an hour ago and so far I have made about 2500 requests without errors. My concurrency limit is 5 and I'm using 2 so that seems ok. The script does very little so I don't think there will be size limit issues. The problem is just that I wonder whether NetSuite will eventually terminate my script for doing so many requests. Not sure whether there is such a governance issue, but can't imagine that they won't eventually stop that sort of thing.
Use the http module to send data in an ajax type manner. This should be able to pickup when new data arrives instead of having to poll (not sure). The problem with this is that I assume I will need a static IP address which is sadly an expensive option.
Use Netsuite SOAP web services which might have a hook instead of polling (not sure). I think this would not be free (like Restlets) either.
So my question is whether there is a better option that I'm missing or what would you recommend. Also would I hit some sort of governance limit if I poll every 2 seconds with option 2?
Update: The polling mysteriously stopped working after 7395 requests and about 3 hours. It did not return an error that I'm aware of. The rejected requests on Integration Governance shows 0.
I used to do the emailing thing quite a bit and it works pretty well. Volume may be an issue.
Another thing to do is just get a static IP address with something like ngrok.
ngrok runs on linux/mac/windows so you'd be able to write an app that listens on a particular port. Netsuite would send an https post to that app at (for instance) https://printing.mycompany.ngrok.io and the app would handle local printing.
I believe ngrok runs about $US60/year.
the app can verify identity with some sort of timestamp and hash so that if someone does get the https address they couldn't easily use all your paper or cause a DoS situation.
We got bamboozled by a printer vender (Zebra) before we found out that we could HTTP post to most printers using PRINTER_IP:9100 and just sending the RAW ZPL/EPL as the body.
Look into: IPP enabled printers. most are these days. saves you 1000's in longrun if you have a large warehouse operation like we do
Instead of polling I would have NetSuite initiate the connection in an afterSubmit User Event script.
I've automated label printing by having NetSuite email attachments to a dedicated mail box which is monitored by a Linux server. My setup is documented here:
https://gist.github.com/michoelchaikin/80af08856144d340b335d69aa383dbe7

NetStream.publish() to AMS ends up with 1kb file

I'm using Adobe Media Server 4.5 and the FLEX 4.6.0 sdk.
I have an .swf application that connects to Adobe Media Server over RMTP, takes audio and video input from the user's webcam and mic, and does a NetStream.publish() to stream the file to the server. The file grows in size as the user records the video. On occasion, the resulting file will end up with a size of 1kb.
What's causing this and how can I prevent it, or otherwise end the session and inform the user that something went wrong?
Edit:
Some additional questions/comments/opinions that might help identify the problem:
This only happens 1% of the time, and I'm not sure what I can use to troubleshoot this. I've never been able to catch when this happens before the log files generated by AMS expire.
My theory is that it happens when the client loses connection somewhere.
As long as the NetStream is publishing correctly, the file will grow in size.
If the file doesn't grow, it should mean that the NetStream lost connection. Seeing as the file is 1kb, the stream must have lost connection immediately after starting to publish.
I also opened the file in Notepad++ and got this:
FLV [SOH][NUL][NUL][NUL][NUL] [NUL][NUL][NUL][NUL]
Another theory is that something has a chance to overwrite my file, but this is unlikely
Have the same problem, but 0.001% of the cases.
The most common problem occurs because of a microphone.
Need to check the microphone before publishing a stream.
Another possible problem:
Client interrupts the flow - NetStream.Record.Stop
Exits the application - onDisconnect
Сlient disables the microphone / camera
"The FLV segment cache is full"
Can warn if called onUnpublish event on the server.
I also use the timer after the publish () method on the client side, if after 3-5 seconds NetStream.Record.Start event is not called, then the client has a problem and it should be prevented.

Flex Security Sandbox Violation just started happening

I have an http handler built and running on my website server. Code in flex generates a http request then navigates to the handler, which generates and streams back file information for the user to download.
Basically the request sends image data and the return result is a pptx stream with the image data in a powerpoint slide.
This worked fantastically this morning until about an hour ago. I have no idea what changed, but every swf I am building which attempts to access this handler is now giving me:
* Security Sandbox Violation *
Connection to https://g1.localhost/Turm/BounceBack.aspx halted - not permitted from https://g1.localhost/Turm/FlashApps/ImageAndExporting.swf?debug=true
I even fully qualified the BounceBack.aspx name (it was a relative url until just now) in case something was confusing the flash player, but as you can see, the url request and the swf are loaded from exactly the same domain (even the same virtual app in the web domain).
I have even added the physical filepath as a 'trusted folder' in my flash player security settings.
What gives? Anyone have any suggestions?
Using the Apache 4.9.1 SDK and latest version of flashplayer.
As mentioned, this worked all day yesterday and this morning. I cannot figure out what has changed, but am having no luck resolving the issue, source code has not changed.
Finally figured out what changed. I move the navigation to my ASPX handler into a seperate method that delays invoation till after a UI update. Becuase I use the same ui components for printing as well as exporting, I tested the updates with the print feature and that worked without error. About an our later, I noticed the handlers were failing. Since the url request is not handled inside a UI interaction event (Like MouseEvent.CLICK) the flash player was preventing the call. Once I moved the navigation back into the event handler, the sandbox violation went away.
If you ask me, not a very good error message due to the actual problem encountered, but ... you learn something every day.

What is the complete process from entering a url to the browser's address bar to get the rendered page in browser?

I'm thinking about this question for a long time. It is a big question, since it almost covers all corners related to web developing.
In my understanding, the process should be like:
enter the url to the address bar
a request will be sent to the DNS server based on your network configuration
DNS will route you to the real IP of the domain name
a request(with complete Http header) will be sent to the server(with 3's IP to identify)'s 80 port(suppose we don't specify another port)
server will search the listening ports and forward the request to the app which is listening to 80 port(let's say nginx here) or to another server(then 3's server will be like a load balancer)
nginx will try to match the url to its configuration and serve as an static page directly, or invoke the corresponding script intepreter(e.g PHP/Python) or other app to get the dynamic content(with DB query, or other logics)
a html will be sent back to browser with a complete Http response header
browser will parse the DOM of html using its parser
external resources(JS/CSS/images/flash/videos..) will be requested in sequence(or not?)
for JS, it will be executed by JS engine
for CSS, it will be rendered by CSS engine and HTML's display will be adjusted based on the CSS(also in sequence or not?)
if there's an iframe in the DOM, then a separate same process will be executed from step 1-12
The above is my understanding, but I don't know whether it's correct or not? How much precise? Did I miss something?
If it's correct(or almost correct), I hope:
Make the step's description more precise in your words, or write your steps if there is a big change
Make a deep explanation for each step which you are most familiar with.
One answer per step. Others can make supplement in each answer's comment.
And I hope this thread can help all web developers to have a better understanding about what we do everyday.
And I will update this question based on the answers.
Thanks.
As you say this is a broad question where it's possible to go into great detail on a number of topics. There's nothing wrong with the sequence you described, but you're leaving out a lot of detail. To mention a few:
The DNS layer can help direct clients to different servers based on geographical location to help with load balancing and latency minimization, and one server can respond to requests from many different DNS names.
A browser can make different types of requests (GET, POST, HEAD, etc), and usually includes several different headers including cookies, browser capabilities, language preferences, etc.
Most browsers usually maintain a cache in order to avoid downloading stuff many times, and use various techniques to determine whether the cached version of a file is valid.
In modern webpages there's often complex interaction between many different kinds of files (HTML, CSS, images, JavaScript, video, Flash, ...), and web developers often need detailed knowledge of differences among browsers in order to keep their pages working for everyone
Each of these topics, and many more, could be discussed at length. Perhaps it's more practical to ask more specific questions about the topics you're interested in?
You type maps.google.com(Uniform Resource Locator) into the address bar of your browser and press enter.
Every URL has a unique IP address associated with it. The mapping is stored in Name Servers and this procedure is called Domain Name System.
The browser checks its cache to find the IP Address for the URL.
If it doesn't find it, it checks its OS to find the IP address (gethostname);
It then Checks the router's cache.
It then checks the ISP's cache. If it is not available there the ISP makes a recursive request to different name servers.
It Checks the com name server (we have many name servers such as 'in', 'mil', 'us' etc) and it will redirect to google.com
google.com name server will find the matching IP address for maps.google.com in its’ DNS records and return it to your DNS recursor which will send it back to your browser.
Browser initiates a TCP connection with the server.It uses a three way handshake
Client machine sends a SYN packet to the server over the internet asking if it is open for new connections.
If the server has open ports that can accept and initiate new connections, it’ll respond with an ACKnowledgment of the SYN packet using a SYN/ACK packet.
The client will receive the SYN/ACK packet from the server and will acknowledge it by sending an ACK packet.
Then a TCP connection is established for data transmission!
The browser will send a GET request asking for maps.google.com web page. If you’re entering credentials or submitting a form this could be a POST request.
The server sends the response.
Once the server supplies the resources (HTML, CSS, JS, images, etc.) to the browser it undergoes the below process:
Parsing - HTML, CSS, JS
Rendering - Construct DOM Tree → Render Tree → Layout of Render Tree → Painting the render tree
The rendering engine starts getting the contents of the requested document from the networking layer. This will usually be done in 8kB chunks.
A DOM tree is built out of the broken response.
New requests are made to the server for each new resource that is found in the HTML source (typically images, style sheets, and JavaScript files).
At this stage the browser marks the document as interactive and starts parsing scripts that are in "deferred" mode: those that should be executed after the document is parsed. The document state is set to "complete" and a "load" event is fired.
Each CSS file is parsed into a StyleSheet object, where each object contains CSS rules with selectors and objects corresponding CSS grammar. The tree built is called CSSCOM.
On top of DOM and CSSOM, a rendering tree is created, which is a set of objects to be rendered. Each of the rendering objects contains its corresponding DOM object (or a text block) plus the calculated styles. In other words, the render tree describes the visual representation of a DOM.
After the construction of the render tree it goes through a "layout" process. This means giving each node the exact coordinates where it should appear on the screen.
The next stage is painting–the render tree will be traversed and each node will be painted using the UI backend layer.
Repaint: When changing element styles which don't affect the element's position on a page (such as background-color, border-color, visibility), the browser just repaints the element again with the new styles applied (that means a "repaint" or "restyle" is happening).
Reflow: When the changes affect document contents or structure, or element position, a reflow (or relayout) happens.
i was also searching for the same thing and found this awesome detailed answer being built collaboratively at github
I can describe one point here -
Determining which file/resource to execute, which language interpreter to load.
Pardon me if I am wrong in using interpreter here. There may be other mistakes in my answer, I will try to correct them later and include proper technical terms for things.
When the web server (e.g. apache) has received the URI it checks if there is any existing rewrite rule matching it. In that case the rewritten URI is taken. In either case, if there is no file name to end the URI, the default file is loaded, which is generally index.html or index.php etc. According to the extension of the file name, the appropriate apache module for server-side programming language support is loaded, e.g. mod_php for PHP, mod_python in case of python. The appropriate server side language interpreter (considering interpreted languages like PHP) then prepares the final HTML or output in some other form for the web server which finally sends it as the HTTP response.
I hope above image help you to understand whole process.
Full article is here