dataChannel.js (9955B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 /** 6 * Returns the contents of a blob as text 7 * 8 * @param {Blob} blob 9 The blob to retrieve the contents from 10 */ 11 function getBlobContent(blob) { 12 return new Promise(resolve => { 13 var reader = new FileReader(); 14 // Listen for 'onloadend' which will always be called after a success or failure 15 reader.onloadend = event => resolve(event.target.result); 16 reader.readAsText(blob); 17 }); 18 } 19 20 /** 21 * Returns the contents of a blob as text 22 * 23 * @param {ArrayBuffer} arraybuffer 24 The ArrayBuffer to retrieve the contents from 25 */ 26 function getArrayBufferContent(arraybuffer) { 27 const decoder = new TextDecoder("utf-8"); 28 return decoder.decode(arraybuffer); 29 } 30 31 var commandsCreateDataChannel = [ 32 function PC_REMOTE_EXPECT_DATA_CHANNEL(test) { 33 test.pcRemote.expectDataChannel(); 34 }, 35 36 function PC_LOCAL_CREATE_DATA_CHANNEL(test) { 37 var channel = test.pcLocal.createDataChannel({}); 38 is( 39 channel.binaryType, 40 "arraybuffer", 41 channel + " is of binary type 'arraybuffer'" 42 ); 43 44 is( 45 test.pcLocal.signalingState, 46 STABLE, 47 "Create datachannel does not change signaling state" 48 ); 49 return test.pcLocal.observedNegotiationNeeded; 50 }, 51 ]; 52 53 var commandsWaitForDataChannel = [ 54 function PC_LOCAL_VERIFY_DATA_CHANNEL_STATE(test) { 55 return test.pcLocal.dataChannels[0].opened; 56 }, 57 58 function PC_REMOTE_VERIFY_DATA_CHANNEL_STATE(test) { 59 return test.pcRemote.nextDataChannel.then(channel => channel.opened); 60 }, 61 ]; 62 63 var commandsCheckDataChannel = [ 64 function SEND_MESSAGE(test) { 65 var message = "Lorem ipsum dolor sit amet"; 66 67 info("Sending message:" + message); 68 return test.send(message).then(result => { 69 is( 70 result.data, 71 message, 72 "Message correctly transmitted from pcLocal to pcRemote." 73 ); 74 }); 75 }, 76 77 function SEND_BLOB(test) { 78 var contents = "At vero eos et accusam et justo duo dolores et ea rebum."; 79 var blob = new Blob([contents], { type: "text/plain" }); 80 81 info("Sending blob"); 82 return test.send(blob).then(result => { 83 ok( 84 result.data instanceof ArrayBuffer, 85 "Received data is of instance ArrayBuffer" 86 ); 87 is( 88 result.data.byteLength, 89 blob.size, 90 "Received data has the correct size." 91 ); 92 93 const recv_contents = getArrayBufferContent(result.data); 94 is(recv_contents, contents, "Received data has the correct content."); 95 }); 96 }, 97 98 function CREATE_SECOND_DATA_CHANNEL(test) { 99 return test.createDataChannel({}).then(result => { 100 is( 101 result.remote.binaryType, 102 "arraybuffer", 103 "remote data channel is of binary type 'arraybuffer'" 104 ); 105 }); 106 }, 107 108 function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL(test) { 109 var channels = test.pcRemote.dataChannels; 110 var message = "I am the Omega"; 111 112 info("Sending message:" + message); 113 return test.send(message).then(result => { 114 is( 115 channels.indexOf(result.channel), 116 channels.length - 1, 117 "Last channel used" 118 ); 119 is(result.data, message, "Received message has the correct content."); 120 }); 121 }, 122 123 function SEND_MESSAGE_THROUGH_FIRST_CHANNEL(test) { 124 var message = "Message through 1st channel"; 125 var options = { 126 sourceChannel: test.pcLocal.dataChannels[0], 127 targetChannel: test.pcRemote.dataChannels[0], 128 }; 129 130 info("Sending message:" + message); 131 return test.send(message, options).then(result => { 132 is( 133 test.pcRemote.dataChannels.indexOf(result.channel), 134 0, 135 "1st channel used" 136 ); 137 is(result.data, message, "Received message has the correct content."); 138 }); 139 }, 140 141 function SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL(test) { 142 var message = "Return a message also through 1st channel"; 143 var options = { 144 sourceChannel: test.pcRemote.dataChannels[0], 145 targetChannel: test.pcLocal.dataChannels[0], 146 }; 147 148 info("Sending message:" + message); 149 return test.send(message, options).then(result => { 150 is( 151 test.pcLocal.dataChannels.indexOf(result.channel), 152 0, 153 "1st channel used" 154 ); 155 is(result.data, message, "Return message has the correct content."); 156 }); 157 }, 158 159 function CREATE_NEGOTIATED_DATA_CHANNEL_MAX_RETRANSMITS(test) { 160 var options = { 161 negotiated: true, 162 id: 5, 163 protocol: "foo/bar", 164 ordered: false, 165 maxRetransmits: 500, 166 }; 167 return test.createDataChannel(options).then(result => { 168 is( 169 result.local.binaryType, 170 "arraybuffer", 171 result.remote + " is of binary type 'arraybuffer'" 172 ); 173 is( 174 result.local.id, 175 options.id, 176 result.local + " id is:" + result.local.id 177 ); 178 is( 179 result.local.protocol, 180 options.protocol, 181 result.local + " protocol is:" + result.local.protocol 182 ); 183 is( 184 result.local.ordered, 185 options.ordered, 186 result.local + " ordered is:" + result.local.ordered 187 ); 188 is( 189 result.local.maxRetransmits, 190 options.maxRetransmits, 191 result.local + " maxRetransmits is:" + result.local.maxRetransmits 192 ); 193 is( 194 result.local.maxPacketLifeTime, 195 null, 196 result.local + " maxPacketLifeTime is:" + result.local.maxPacketLifeTime 197 ); 198 199 is( 200 result.remote.binaryType, 201 "arraybuffer", 202 result.remote + " is of binary type 'arraybuffer'" 203 ); 204 is( 205 result.remote.id, 206 options.id, 207 result.remote + " id is:" + result.remote.id 208 ); 209 is( 210 result.remote.protocol, 211 options.protocol, 212 result.remote + " protocol is:" + result.remote.protocol 213 ); 214 is( 215 result.remote.ordered, 216 options.ordered, 217 result.remote + " ordered is:" + result.remote.ordered 218 ); 219 is( 220 result.remote.maxRetransmits, 221 options.maxRetransmits, 222 result.remote + " maxRetransmits is:" + result.remote.maxRetransmits 223 ); 224 is( 225 result.remote.maxPacketLifeTime, 226 null, 227 result.remote + 228 " maxPacketLifeTime is:" + 229 result.remote.maxPacketLifeTime 230 ); 231 }); 232 }, 233 234 function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2(test) { 235 var channels = test.pcRemote.dataChannels; 236 var message = "I am the walrus; Goo goo g'joob"; 237 238 info("Sending message:" + message); 239 return test.send(message).then(result => { 240 is( 241 channels.indexOf(result.channel), 242 channels.length - 1, 243 "Last channel used" 244 ); 245 is(result.data, message, "Received message has the correct content."); 246 }); 247 }, 248 249 function CREATE_NEGOTIATED_DATA_CHANNEL_MAX_PACKET_LIFE_TIME(test) { 250 var options = { 251 ordered: false, 252 maxPacketLifeTime: 10, 253 }; 254 return test.createDataChannel(options).then(result => { 255 is( 256 result.local.binaryType, 257 "arraybuffer", 258 result.local + " is of binary type 'arraybuffer'" 259 ); 260 is( 261 result.local.protocol, 262 "", 263 result.local + " protocol is:" + result.local.protocol 264 ); 265 is( 266 result.local.ordered, 267 options.ordered, 268 result.local + " ordered is:" + result.local.ordered 269 ); 270 is( 271 result.local.maxRetransmits, 272 null, 273 result.local + " maxRetransmits is:" + result.local.maxRetransmits 274 ); 275 is( 276 result.local.maxPacketLifeTime, 277 options.maxPacketLifeTime, 278 result.local + " maxPacketLifeTime is:" + result.local.maxPacketLifeTime 279 ); 280 281 is( 282 result.remote.binaryType, 283 "arraybuffer", 284 result.remote + " is of binary type 'arraybuffer'" 285 ); 286 is( 287 result.remote.protocol, 288 "", 289 result.remote + " protocol is:" + result.remote.protocol 290 ); 291 is( 292 result.remote.ordered, 293 options.ordered, 294 result.remote + " ordered is:" + result.remote.ordered 295 ); 296 is( 297 result.remote.maxRetransmits, 298 null, 299 result.remote + " maxRetransmits is:" + result.remote.maxRetransmits 300 ); 301 is( 302 result.remote.maxPacketLifeTime, 303 options.maxPacketLifeTime, 304 result.remote + 305 " maxPacketLifeTime is:" + 306 result.remote.maxPacketLifeTime 307 ); 308 }); 309 }, 310 311 function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL3(test) { 312 var channels = test.pcRemote.dataChannels; 313 var message = "Nice to see you working maxPacketLifeTime"; 314 315 info("Sending message:" + message); 316 return test.send(message).then(result => { 317 is( 318 channels.indexOf(result.channel), 319 channels.length - 1, 320 "Last channel used" 321 ); 322 is(result.data, message, "Received message has the correct content."); 323 }); 324 }, 325 ]; 326 327 var commandsCheckLargeXfer = [ 328 function SEND_BIG_BUFFER(test) { 329 var size = 2 * 1024 * 1024; // SCTP internal buffer is now 1MB, so use 2MB to ensure the buffer gets full 330 var buffer = new ArrayBuffer(size); 331 var options = {}; 332 options.bufferedAmountLowThreshold = 64 * 1024; 333 info("Sending arraybuffer"); 334 return test.send(buffer, options).then(result => { 335 ok( 336 result.data instanceof ArrayBuffer, 337 "Received data is of instance ArrayBuffer" 338 ); 339 is(result.data.byteLength, size, "Received data has the correct size."); 340 }); 341 }, 342 ]; 343 344 function addInitialDataChannel(chain) { 345 chain.insertBefore("PC_LOCAL_CREATE_OFFER", commandsCreateDataChannel); 346 chain.insertBefore( 347 "PC_LOCAL_WAIT_FOR_MEDIA_FLOW", 348 commandsWaitForDataChannel 349 ); 350 chain.removeAfter("PC_REMOTE_CHECK_ICE_CONNECTIONS"); 351 chain.append(commandsCheckDataChannel); 352 }