Welcome to Tesla Motors Club
Discuss Tesla's Model S, Model 3, Model X, Model Y, Cybertruck, Roadster and More.
Register

Cross-origin Websockets Disallowed in Tesla Model S Browser?

This site may earn commission on affiliate links.
The car's browser does allow websockets, and I confirmed via https://www.websocket.org/echo.html. I was messing around a bit with the Pushbullet API to try to send notifications to a page loaded in the car's browser. I was able to build a very simple HTML/JavaScript page that connects to the Pushbullet websocket stream via JavaScript, and receive Pushbullet mirror notifications. I didn't have to do anything on a server, and Chrome allows the cross-origin websockets connection with no issue. The page works great on a desktop browser.

When I tried loading the page in the Model S web browser, it doesn't work. As you can imagine, it's a PITA to debug since there's no developer console in the car's browser and you can't see what's going on under the covers. After some "manual" debugging with code, it seems like it's not even ever making the websocket connection. It wouldn't fire any of the websocket events, except for the onclose event, and it fires with a readyState of 2.

At this point, my only guess as to why it doesn't work is because the car's browser won't allow cross-origin websocket connections. Has anyone experimented with websockets on the Model S browser? If so, have you encountered similar issues?
 
I haven't tried cross-origin websockets but Tesla's Webkit is very limited because it prevents any possibility of video being displayed. I understand that they will replace it with Chrome at some point, but I wouldn't be surprised if it also doesn't work for many items.
 
Next thing I would try is to setup an nginx server on an EC2 instance as a reverse websocket proxy, and serve your page from the same domain.

Not sure what kind of traffic you're pushing through the proxy, but as long as it isn't massive, the cost of the EC2 instance should be pretty reasonable.
 
I haven't tried cross-origin websockets but Tesla's Webkit is very limited because it prevents any possibility of video being displayed. I understand that they will replace it with Chrome at some point, but I wouldn't be surprised if it also doesn't work for many items.

Whether or not they replace it with Chrome, why do you think they would implement all the functionality? The Webkit version is limited because of Tesla's implementation choices, not because of amy Webkit limitations (maybe I didn't understand what "I wouldn't be surprised if it also doesn't work for many items." applied to...).
 
Whether or not they replace it with Chrome, why do you think they would implement all the functionality? The Webkit version is limited because of Tesla's implementation choices, not because of amy Webkit limitations (maybe I didn't understand what "I wouldn't be surprised if it also doesn't work for many items." applied to...).

The "I wouldn't be surprised if it also doesn't work for many items." means just what you said. There will likely be the same limitations because Tesla needs to ensure that there will be no video visible by the driver. (It would be nice if it knew about "park" so you could watch when not driving, but I suspect that it would be very hard to ensure no video when not in park from web based content. The cars that do this are talking about DVD only, which is easy to program.)
 
The "I wouldn't be surprised if it also doesn't work for many items." means just what you said. There will likely be the same limitations because Tesla needs to ensure that there will be no video visible by the driver. (It would be nice if it knew about "park" so you could watch when not driving, but I suspect that it would be very hard to ensure no video when not in park from web based content. The cars that do this are talking about DVD only, which is easy to program.)

Speculation from a software and firmware engineer:

Shouldn't be any harder than doing it with a DVD in other cars. It's likely just not a priority for the dev teams.
I'm hoping that part of the v7 UI overhaul will entail is a refactoring of the existing underlying architecture. It's a pretty common pattern that you write the first version and it's "good", but you learn a lot during the process.
Second versions tend to lean more toward "overly" architected component systems that can communicate things over a bus, etc.

In any case, they've already modified the browser, they already have access to other parts of the car from the browser, and they can make the video work while parked and turn it off when in drive. They've just chosen not to.
 
Shouldn't be any harder than doing it with a DVD in other cars. It's likely just not a priority for the dev teams.
I'm hoping that part of the v7 UI overhaul will entail is a refactoring of the existing underlying architecture.

I certainly hope they add this functionality. Currently the browser is completely disabled on Australian Model Ss, even though by law it only needs to be disabled while driving.
 
Next thing I would try is to setup an nginx server on an EC2 instance as a reverse websocket proxy, and serve your page from the same domain.

Not sure what kind of traffic you're pushing through the proxy, but as long as it isn't massive, the cost of the EC2 instance should be pretty reasonable.

Yeah, no traffic yet, I was just throwing something together as a proof of concept. I could even just try it on my desktop for now and pull the page up from the car via the LAN or do some port forwards outside the LAN for further testing. I'm a PHP guy, do you know if there are any good reverse websocket proxies for PHP? If not PHP, what other suggestions might you have for reverse websocket proxies?
 
Yeah, no traffic yet, I was just throwing something together as a proof of concept. I could even just try it on my desktop for now and pull the page up from the car via the LAN or do some port forwards outside the LAN for further testing. I'm a PHP guy, do you know if there are any good reverse websocket proxies for PHP? If not PHP, what other suggestions might you have for reverse websocket proxies?

You don't actually need to write any code for the reverse proxy. You basically just tell the web server that's serving up your PHP to accept requests on a certain path (e.g. /webproxy) and send those to a different host (e.g. http://pushbullet.com/websocketApi).

This way the web browser gets server your php from "yourdomain.com", and it makes the websocket calls to "yourdomain.com/webproxy", so it's happy. Same domain.
Your web server takes care of forwarding that to pushbullet.com (i.e. proxy), and also forwarding the replies from pushbullet.com back to the browser (i.e. reverse proxy).

Most "real" web servers have configurations for reverse websocket proxies.
Here's an example for Nginx: NGINX as a WebSocket Proxy - NGINX
For Apache, check out: mod_proxy_wstunnel
 
You don't actually need to write any code for the reverse proxy. You basically just tell the web server that's serving up your PHP to accept requests on a certain path (e.g. /webproxy) and send those to a different host (e.g. http://pushbullet.com/websocketApi).

This way the web browser gets server your php from "yourdomain.com", and it makes the websocket calls to "yourdomain.com/webproxy", so it's happy. Same domain.
Your web server takes care of forwarding that to pushbullet.com (i.e. proxy), and also forwarding the replies from pushbullet.com back to the browser (i.e. reverse proxy).

Most "real" web servers have configurations for reverse websocket proxies.
Here's an example for Nginx: NGINX as a WebSocket Proxy - NGINX
For Apache, check out: mod_proxy_wstunnel

I didn't realize it was as simple as that. I guess even if the target is SSL and my server/path is regular HTTP, it still shouldn't be a problem. However, I think keeping the connection open for any significant amount of time may be an issue, because a lot of hosts will terminate any long-running connections. I think Google App Engine will kill processes that run longer than a few seconds, but I may still experiment with it a bit there.
 
I would just spin up an EC2 instance and put the web server on it. Then you're in control of the box and it won't terminate the connections. One or two web servers is probably more than enough at any reasonable volume you'd generate.

Also, you need to match protocols for same origin policy. You can't have https on the base page and http on the websocket, or vice-versa. Since it seems the Tesla browser isn't 100% compliant, it's worth trying, though.
 
Also, you need to match protocols for same origin policy. You can't have https on the base page and http on the websocket, or vice-versa. Since it seems the Tesla browser isn't 100% compliant, it's worth trying, though.

I could connect to the remote wss://stream.pushbullet.com/websocket page via the server, but the serve up the page and websocket to the client via http. For instance, I serve up http://foo.bar/page.html that makes an unsecure websocket connection to ws://foo.bar/pushbullet (same origin). The server side code for ws://foo.bar/pushbullet proxies the connection to wss://stream.pushbullet.com/websocket.

In the end, it'll be best to get an SSL certificate and go secure across the board. I'll probably go the route you recommended, with a small EC2 server. However, for testing I should be able to use a webhost I currently have where I don't have SSL, and use the setup described, correct?
 
Reading this thread makes me feel like Ginger.

image.jpg
 
Reading this thread makes me feel like Ginger.

View attachment 88809

Prepare for more blah blah blah blah :biggrin:

Dealing with websockets in PHP seemed like it was going to be quite the hassle. A lot of info I was coming across about websockets seemed to be node.js implentations, so I figured I'd try it out. I've never tried node.js until now. It seems like a pretty cool platform for web development, I will probably tinker with it further.

I set up an EC2 instance, installed node.js, and was able to set up the reverse websocket proxy without too much trouble. The page worked like a charm in the Model S browser, so it would indeed seem that the browser disallows cross-origin websockets.
 
Prepare for more blah blah blah blah :biggrin:

Dealing with websockets in PHP seemed like it was going to be quite the hassle. A lot of info I was coming across about websockets seemed to be node.js implentations, so I figured I'd try it out. I've never tried node.js until now. It seems like a pretty cool platform for web development, I will probably tinker with it further.

I set up an EC2 instance, installed node.js, and was able to set up the reverse websocket proxy without too much trouble. The page worked like a charm in the Model S browser, so it would indeed seem that the browser disallows cross-origin websockets.

Node is awesome. Do yourself a favor and learn Promises while you're learning node. It'll save you from callback hell and easier to learn the "right" way to handle callbacks early, rather than writing a bunch of callback code and refactoring it later to Promises.

Also, use pm2 to manage the running node server. And Loggly for your logs. :)
 
Thought you guys might be interested to hear that I have a Pushbullet integration up and running for my Tesla. It allows me to get all phone notifications displayed in the browser screen. It even allows me to respond to text messages and such. I've set up a few buttons with canned phrases. Works great!

Technical details: A Google AppEngine server that monitors the Pushbullet stream via WebSocket and keeps notifications in a database until they are dismissed (on any device attached to Pushbullet). Then, a GWT interface that polls the database on the AppEngine server and displays the notification list in the browser. Dismiss or Reply events are sent to the AppEngine server and from there to the Pushbullet API. Use of the intermediate database allows me to capture notifications from the stream even when the webpage is not active.
 
Thought you guys might be interested to hear that I have a Pushbullet integration up and running for my Tesla. It allows me to get all phone notifications displayed in the browser screen. It even allows me to respond to text messages and such. I've set up a few buttons with canned phrases. Works great!

Technical details: A Google AppEngine server that monitors the Pushbullet stream via WebSocket and keeps notifications in a database until they are dismissed (on any device attached to Pushbullet). Then, a GWT interface that polls the database on the AppEngine server and displays the notification list in the browser. Dismiss or Reply events are sent to the AppEngine server and from there to the Pushbullet API. Use of the intermediate database allows me to capture notifications from the stream even when the webpage is not active.


Share! I would love to see notifications on my Tesla browser.