Firefox does not allow initiating unreliable WebRTC dataChannels? - firefox

In this example I'm using simple-peer, although I have tested with other implementations as well as my own. This seems to be an issue with creating the data channels.
The example from the github page of simple-peer has been slightly modified and used: https://github.com/feross/simple-peer
var init = location.hash === '#1';
var config = {reliable:true, maxRetransmits:0, ordered:false};
var p = new SimplePeer({ initiator: init, trickle: false, channelConfig: config })
console.log(p);
p.on('error', function (err) { console.log('error', err) })
p.on('signal', function (data) {
console.log('SIGNAL', JSON.stringify(data))
document.querySelector('#outgoing').textContent = JSON.stringify(data)
})
document.querySelector('form').addEventListener('submit', function (ev) {
ev.preventDefault()
p.signal(JSON.parse(document.querySelector('#incoming').value))
})
p.on('connect', function () {
console.log('CONNECT')
console.log(p);
console.log(p._channel);
if(init){
for(let i=0;i<100;i++){
p.send(JSON.stringify(i));
}
}
})
var rec = 0;
p.on('data', function (data) {
rec++;
console.log('data: ' + JSON.parse(data));
if(!init){
p.send(data);
}
if(rec >= 100){
console.log("got all");
}
})
When initiating the connection using Firefox(61.0.2 x64), the connection is forced to reliable, even when trying to set it to unreliable using unreliable:false, ordered:false and maxRetransmits:0. Only the ordered property is properly used.
When checking the connection object, the maxRetransmits and maxRetransmitTime settings are not exposed. If you connect to the Firefox connection using Chrome, both maxRetransmits and maxRetransmitTime will be set to 65535 in Chrome.
If you initiate the connection using Chrome, and connect using Firefox, the connection will be opened as unordered and unreliable in both Chrome and Firefox as well as having 0 maxRetransmits in Chrome.
Is this a bug, or am I missing something in setting up the connection to support unreliable data channels when initiating the connection using a Firefox browser?

Yes, this is a very unfortunate bug in Firefox tracked here that leads to 0 values being ignored for both maxRetransmits and maxPacketLifeTime. It has been fixed in Firefox 62. If you have to support Firefox < 62, you can work around this by setting maxPacketLifeTime to 1. But you should only do this in Firefox since older Chrome versions do not support maxPacketLifeTime. Yes, it's a mess.
Please note that there is no reliable member in the RTCDataChannelInit dictionary. There is also no maxRetransmitTime attribute on the RTCDataChannel interface. Both have been removed a long time ago.

Related

IndexedDB breaks in Firefox after trying to save autoIncremented Blob

I am trying to implement Blob storage via IndexedDB for long Media recordings.
My code works fine in Chrome and Edge (not tested in Safari yet) - but won't do anything in Firefox. There are no errors, it just doesn't try to fulfill my requests past the initial DB Connection (which is successful). Intuitively, it seems that the processing is blocked by something. But I don't have anything in my code which would be blocking.
Simplified version of the code (without heavy logging and excessive error checks which I have added trying to debug):
const dbName = 'recording'
const storeValue = 'blobs'
let connection = null
const handler = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB
function connect() {
return new Promise((resolve, reject) => {
const request = handler.open(dbName)
request.onupgradeneeded = (event) => {
const db = event.target.result
if (db.objectStoreNames.contains(storeValue)) {
db.deleteObjectStore(storeValue)
}
db.createObjectStore(storeValue, {
keyPath: 'id',
autoIncrement: true,
})
}
request.onerror = () => {
reject()
}
request.onsuccess = () => {
connection = request.result
connection.onerror = () => {
connection = null
}
connection.onclose = () => {
connection = null
}
resolve()
}
})
}
async function saveChunk(chunk) {
if (!connection) await connect()
return new Promise((resolve, reject) => {
const store = connection.transaction(
storeValue,
'readwrite'
).objectStore(storeValue)
const req = store.add(chunk)
req.onsuccess = () => {
console.warn('DONE!') // Fires in Chrome and Edge - not in Firefox
resolve(req.result)
}
req.onerror = () => {
reject()
}
req.transaction.oncomplete = () => {
console.warn('DONE!') // Fires in Chrome and Edge - not in Firefox
}
})
}
// ... on blob available
await saveChunk(blob)
What I tried so far:
close any other other browser windows, anything that could count as on "open connection" that might be blocking execution
refresh Firefox profile
let my colleague test the code on his own machine => same result
Additional information that might useful:
Running in Nuxt 2.15.8 dev environment (localhost:3000). Code is used in the component as a Mixin. The project is rather large and uses a bunch of different browser APIs. There might be some kind of collision ?! This is the only place where we use IndexedDB, though, so to get to the bottom of this without any errors being thrown seems almost impossible.
Edit:
When I create a brand new Database, there is a brief window in which Transactions complete fine, but after some time has passed/something triggered, it goes back to being queued indefinitely.
I found out this morning when I had this structure:
...
clearDatabase() {
// get the store
const req = store.clear()
req.transaction.oncomplete = () => console.log('all good!')
}
await this.connect()
await this.clearDatabase()
'All good' fired. But any subsequent requests were broken same as before.
On page reload, even the clearDatabase request was broken again.
Something breaks with ongoing usage.
Edit2:
It's clearly connected to saving a Blob instance without an id with the autoIncrement option. Not only does it fail silently, it basically completely corrupts the DB. If I manually assign an incrementing ID to a Blob object, it works! If I leave out the id field for a regular simple object, it also works! Anyone knows about this? I feel like saving blobs is a common use-case so this should have been found already?!
I've concluded, unless proven otherwise, that it's a Firefox bug and opened a ticket on Bugzilla.
This happens with Blobs but might also be true for other instances. If you find yourself in the same situation there is a workaround. Don't rely on autoIncrement and assign IDs manually before trying to save them to the DB.

Can't connect to web socket from Electron when using self signed cert

I have an Electron app which tries to connect to a device over a web socket. The connection is encrypted (i.e. wss) but the SSL certificate is self signed and thus, untrusted.
Connecting inside Chrome is ok and it works. However inside Electron I run into problems. Without putting any certificate-error handlers on the BrowserWindow or on the app I receive the following error in the console output:
WebSocket connection to 'wss://some_ip:50443/' failed: Error in connection establishment: net::ERR_CERT_AUTHORITY_INVALID
Then shortly after:
User is closing WAMP connection.... unreachable
In my code, to make the connection I run the following.
const connection = new autobahn.Connection({
realm: 'some_realm',
url: 'wss://some_ip:50443'
});
connection.onopen = (session, details) => {
console.log('* User is opening WAMP connection....', session, details);
};
connection.onclose = (reason, details) => {
console.log('* User is closing WAMP connection....', reason, details);
return true;
};
connection.open();
// alternatively, this also displays the same error
const socket = new WebSocket(`wss://some_ip:50443`);
socket.onopen = function (event) {
console.log(event);
};
socket.onclose = function (event) {
console.log(event);
};
NOTE: Autobahn is a Websocket library for connecting using the WAMP protocol to a socket server of some sort. (in my case, the device) The underlying protocol is wss. Underneath the code above, a native JS new WebSocket() is being called. In other words:
As I mentioned, I've tested this code in the browser window and it works. I've also built a smaller application to try and isolate the issue. Still no luck.
I have tried adding the following code to my main.js process script:
app.commandLine.appendSwitch('ignore-certificate-errors');
and
win.webContents.on('certificate-error', (event, url, error, certificate, callback) => {
// On certificate error we disable default behaviour (stop loading the page)
// and we then say "it is all fine - true" to the callback
event.preventDefault();
callback(true);
});
and
app.on('certificate-error', (event, webContents, link, error, certificate, callback) => {
// On certificate error we disable default behaviour (stop loading the page)
// and we then say "it is all fine - true" to the callback
event.preventDefault();
callback(true);
});
This changed the error to:
WebSocket connection to 'wss://some_ip:50443/' failed: WebSocket opening handshake was canceled
My understanding is that the 'certificate-error' handlers above should escape any SSL certificate errors and allow the application to proceed. However, they're not.
I've also tried adding the following to main.js:
win = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
webSecurity: false
}
});
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = '1';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
With Election, how do I properly deal with a certificate from an untrusted authority? i.e. a self signed cert.
Any help would be much appreciated.
I had the same problem , all i added was your line:
app.commandLine.appendSwitch('ignore-certificate-errors');
I use socket.io, but i think its the same principal.
I do however connect to the https protocol and not wss directly.
This is what my connection looks like on the page:
socket = io.connect(
'https://yoursocketserver:yourport', {
'socketpath',
secure: false,
transports: ['websocket']
});
That seems to have done the trick.
Thank you for the help :) i hope this answer helps you too.

InValid Frame header on Websocket using node.js

I get the following error in my chrome console.
websocket.js:111 WebSocket connection to 'ws://c7f2053b.ngrok.io/socket.io/?EIO=3&transport=websocket' failed: Invalid frame header
In my firefox i get this
The connection to ws://c7f2053b.ngrok.io/socket.io/?EIO=3&transport=websocket&sid=h1U3iQ9b3INSkg9xAAAC was interrupted while the page was loading.
Is there anyway to clear this issue please suggest me ...
Please check
1) Chrome and Firefox versions. Older versions might not have full support for WebSockets
What browsers support HTML5 WebSocket API?
2) Test Basic code :: Try with regular JavaScript Code first and see if connection is establishing:-
websocket = new WebSocket(URL);
websocket.onopen = function(evt) {
alert("Connected...");
websocket.send(message);
websocket.onmessage = function(evt) {
alert(evt.data);
};
websocket.onclose = function(evt) {
alert(evt.data);
};
websocket.onerror = function(evt) {
alert(evt.data);
};

Signalr: Websockets connection issue

Our application uses SignalR and we have enabled the websockets in our applicaiton. Sometimes we are getting the below error in browser console window and during the same time the auto update is not working. After the relaunch it is started working.
Firefox:
"The connection to ws://xx.xx.xx.xx:xxxxx/signalr/connect?transport=webSockets&connectionToken=%2F54BwG4ui3MbJPK2t8DfS9AklLCtAEDQ1sHeAsZ6e3h2LVT0WYbbgGvCI2AlnsJf0AqY4AzMtp6FS0xl07td8kKFYhAmIEL4GjLCXP%2Bhlfy3k226j%2B4fXHVB8Vvblewc&connectionData=%5B%7B%22name%22%3A%22pushdatahub%22%7D%5D&tid=7 was interrupted while the page was loading."
Chrome:
jquery.signalR-1.0.0.min.js:10 WebSocket is already in CLOSING or CLOSED state.
Please refer below setup done on the server.
.Net framework 4.6.1 in the server.
websockets enabled in IIS/Application
httpruntime set in web.config
Server uses SignalR Hub
Sample client code:
$scope.isHubConnectionFailed = false;
$scope.connection = $.hubConnection(AppURL);
$scope.HubProxy = $scope.connection.createHubProxy(App.chatHub);
$scope.connection.start()
.done(function () {
$scope.isHubConnectionFailed = false;
})
.fail(function() {
$scope.isHubConnectionFailed = true;
});
var tryingToReconnect = false;
$scope.connection.reconnecting(function() {
tryingToReconnect = true;
});
$scope.connection.reconnected(function() {
tryingToReconnect = false;
$scope.isHubConnectionFailed = false;
});
$scope.connection.disconnected(function() {
if (tryingToReconnect) {
$scope.isHubConnectionFailed = true;
}
});
Anyone having the same issue?
Check the version of the browser your using.
Supported Platforms: http://www.asp.net/signalr/overview/getting-started/supported-platforms
There is an issue I found with signalr and azure, I am not sure if that is your situation but it might help to debug the issue. https://github.com/SignalR/SignalR/issues/2780

Backbone.js collection fetch request missing data parameter in IE9

So, I've used Backbone.js to write a messaging system. It works fine in Chrome and FF but IE9 has issues with a particular fetch call that kills it. (I'm working in MVC3).
I have a poll that checks for new messages coming in, which sends the date to the server. The poll is called with this method:
DoMessageFetch = function() {
var now = new Date().toUTCString();
Chat.mymessages.fetch({
cache: false,
data: {
Now: now
},
success: function (response) {
// if there are messages ...
// for each message, open a chat window
if (Chat.mymessages.length > 0) {
for (var i = 0; i < Chat.mymessages.length; i++) {
var useridto = Chat.mymessages.at(i).get("UserId");
var name = Chat.mymessages.at(i).get("ScreenName");
// a chat-window with this useridto is NOT on the page
if (!($('#chat-window-' + useridto).is(':visible'))) {
Chat.doChatMessageFetch(name, useridto, null); // this constructs a Backbone view
}
}
}
},
error: function () { console.log('ERROR: fetching general poll messages failed.'); }
});
Chat.mymessages.reset();
}
In IE9 the Now param is null when I watch breakpoints in my Controller. This means the request follows the wrong code path on the server...
I don't understand where my Now parameter went in IE. Can any one help?
This problem is due to the different behaviour of
new Date().toUTCString()
between IE , Google Chrome and Firefox.
For example the result in Chrome is :
"Thu, 20 Sep 2012 20:19:15 GMT"
while in IE you will get
"Thu, 20 Sep 2012 20:19:15 UTC"
MVC3 ModelBinder will ignore IE Format and leave your Now parameter null.The solution to this problem is to replace
new Date().toUTCString()
with
new Date().toJSON()
The only thing to note with this solution is that it will not work by default on IE7 due to the lack of the toJSON() function but this problem can be solved using Douglas Crockford json2.js library which is also recommended when using Backbone.js

Resources