We built a cameras application that worked on both Chrome and Firefox but not Safari. We recently got around to investigating the issue in Safari and we found that it was due to the websocket connection. We noticed in the library that there is the ability to `toggleWebSocket(false)` which fixed the problem as we expected for Safari. But we noticed that with the websocket toggled off, calling `destroy` on the VideoConnection would throw an error in the console:
```
VideoConnection.js:328 Uncaught ReferenceError: VideoConnection is not defined
at XPMobileSDK.library.VideoConnection.destroy (VideoConnection.js:328)
```
For context, we perform this destruction when attempting to reestablish the VideoConnection at a higher resolution, so the new stream never plays due to this error being thrown.
I noticed in `VideoConnection.js` where the error occurs that it attempts `VideoConnection.indexOf(this)` but I can’t seem to find where `VideoConnection` is defined in general or as an array and I was wondering if some insight could be provided regarding that because when I attempt to console log `VideoConnection` elsewhere in the file, the error is thrown just the same.
For the time being I poked around the file and found the existence of `XPMobileSDK.library.VideoConnection.instances` where `this` is pushed to earlier in the code so I have replaced the `VideoConnection.indexOf` reference with that but I would like to know if that change would be proper or doing something outside of my understanding.
Any help and understanding is appreciated, thank you!
Thank you @Hunter Adams for the detail description of the case. I have created a work item about this case and I will investigate it as soon as possible.
Congratulations @Hunter Adams you just found a bug in the our Mobile SDK. The fix you did is the same that I will apply to our SDK. Thanks again that you share this findings. This is the code that I changed from:
if (VideoConnection.indexOf(this) != -1) {
VideoConnection.splice(VideoConnection.indexOf(this), 1);
}
to
if (XPMobileSDK.library.VideoConnection.indexOf(this) != -1) {
XPMobileSDK.library.VideoConnection.splice(XPMobileSDK.library.VideoConnection.indexOf(this), 1);
}
I am just wondering that was the problem with WebSockets. Going to Ajax will reduce the FPS of the video. Did you run the samples in the SDK (on the mobile server location http://localhost:8081/XPMobileSDK/Samples/Video/videoSample.html)? They are using WebSockets and they run well.
Yea, we noticed the FPS difference too when switched to AJAX. Websockets were working great for Chrome and Firefox but we were experiencing issues on Safari with the websocket connection, so we decided we can detect the browser and toggle the websocket accordingly.
Which the `toggleWebSockets` solution might not be the final/desired fix we go with but it works for us for the time being. The actual error on Safari is the following:
`Websocket connection to ‘url’ failed: Invalid UTF-8 sequence in header value`
From what I read on the internet Safari have this problem and in order to fix it you need to supply some headers. I can suggest to open the code of the WebClient from a file explorer then go to XPMobileSDK\Samples\Video then rename videoSample.html.download to videoSample.html.download_tmp. This will tell the MobileServer to serve the file and not to download it. Then load in the Safari http://krum-internal.krum.io:20003/XPMobileSDK/Samples/Video/videoSample.html and test the samples there. If they work (they should) then you will have a base to compare both solutions and find more easy where the problem is.
Hi @Teodor Hadjistoyanov ,
We dug a little bit deeper in this one, and it seems the issue may lie in a known bug with Safari, where the websocket upgrade fails if any header has an empty value. We were able to get the socket working by adding values for those empty headers in the VideoOS.MobileServer.Service.exe.config file for the mobile server. Example values here (for developers), to correspond with the headers that were empty, are:
<add key="X-Frame-Options" value="allow-from *" />
<add key="Content-Security-Policy" value="connect-src *;" />
<add key="Strict-Transport-Security" value="none" />
<add key="X-XSS-Protection" value="0" />
That makes our full (development server) HttpHeaders config:
<HttpHeaders><!-- Keep in mind that if you have to use any XML special characters in the X-Frame-Options header they MUST be replaced with their equivellent ones
(<) -> < , (&) -> & , (>) -> > , (") -> " , and (') -> ' --><!--values should be separated with comma --><!--add key ="Access-Control-Allow-Methods" value ="POST, GET, OPTIONS"/><add key ="Access-Control-Allow-Headers" value ="Access-Control-Allow-Origin, Content-Type"/--><add key="Access-Control-Allow-Origin" value="*" /><add key="X-Frame-Options" value="allow-from *" /><add key="Content-Security-Policy" value="connect-src *;" /><add key="Strict-Transport-Security" value="none" /><add key="X-XSS-Protection" value="0" /></HttpHeaders>
Once those headers were added, the socket connections began working for the default milestone client, as well as the demo samples and our application.
We tracked this down through other websocket server applications with the same issue, and it seems the solution was to add default values in the http server. So perhaps the mobile server could use default values unless they are overwritten in the config?
I hope this helps!
-Colin
Hello @Colin Griffin. I just wanted to update you that today a fix was made in the Mobile Server and from next release it will not send empty headers anymore. No one needs an empty header so we decided to cut them from the HTTP headers section in this case. This way we both created a better product and prevent the other users to hit this Safari problem.
Awesome! Thanks for the help!
Yes I remember that @Colin Griffin now when you wrote that. Six years ago we faced the same problem and we fix it the way you did that. I don’t remember if we have this information about the headers on Safari in our knowledge base but I will make sure it is included in the next release of the documentation.