2016-02-08 4 views
1

Я пытаюсь реализовать механизм отправки текстовых данных (например, JSON) со страницы на страницу, используя javascript на такой же машине.
Я нашел код и обернул его, но он работает только на той же странице.
На данный момент я не хочу использовать структуру WwebRTC, только adapter.js.WebRTC Между двумя страницами на одной машине

//Must include adapter.js before 

var WebRTCManager = (function() { 

    'use strict'; 

    //Ctor 
    function WebRTCManagerFn() { 

     console.log('WebRTCManagerFn ctor reached'); 

     this._events = {}; 

     this._localConnection = null 
     this._remoteConnection = null; 
     this._sendChannel = null; 
     this._receiveChannel = null; 
    } 

    WebRTCManagerFn.prototype.addEventListener = function (name, handler)  { 
     if (this._events.hasOwnProperty(name)) 
      this._events[name].push(handler); 
     else 
      this._events[name] = [handler]; 
    }; 

    WebRTCManagerFn.prototype._fireEvent = function (name, event) { 
     if (!this._events.hasOwnProperty(name)) 
      return; 

     if (!event) 
      event = {}; 

     var listeners = this._events[name], l = listeners.length; 
     for (var i = 0; i < l; i++) { 
      listeners[i].call(null, event); 
     } 
    }; 

WebRTCManagerFn.prototype.createConnection = function() { 
    var servers = null; 
    var pcConstraint = null; 
    var dataConstraint = null; 

    console.log('Using SCTP based data channels'); 

    // SCTP is supported from Chrome 31 and is supported in FF. 
    // No need to pass DTLS constraint as it is on by default in Chrome 31. 
    // For SCTP, reliable and ordered is true by default. 
    // Add localConnection to global scope to make it visible 
    // from the browser console. 
    window.localConnection = this._localConnection = 
     new RTCPeerConnection(servers, pcConstraint); 
    console.log('Created local peer connection object localConnection'); 

    this._sendChannel = this._localConnection.createDataChannel('sendDataChannel', 
      dataConstraint); 
    console.log('Created send data channel'); 
    this._localConnection.onicecandidate = this._localIceCallback.bind(this); 
    this._sendChannel.onopen = this._onSendChannelStateChange.bind(this); 
    this._sendChannel.onclose = this._onSendChannelStateChange.bind(this); 

    // Add remoteConnection to global scope to make it visible 
    // from the browser console. 
    window.remoteConnection = this._remoteConnection = 
     new RTCPeerConnection(servers, pcConstraint); 
    console.log('Created remote peer connection object remoteConnection'); 
    this._remoteConnection.onicecandidate = this._remoteIceCallback.bind(this); 
    this._remoteConnection.ondatachannel = this._receiveChannelCallback.bind(this); 

    this._localConnection.createOffer(this._gotOfferFromLocalConnection.bind(this), this._onCreateSessionDescriptionError.bind(this)); 
} 

WebRTCManagerFn.prototype._onCreateSessionDescriptionError = function (error) { 
    console.log('Failed to create session description: ' + error.toString()); 
} 

WebRTCManagerFn.prototype.sendMessage = function (msgText) { 
    var msg = new Message(msgText); 

    // Send the msg object as a JSON-formatted string. 
    var data = JSON.stringify(msg); 
    this._sendChannel.send(data); 

    console.log('Sent Data: ' + data); 
} 

WebRTCManagerFn.prototype.closeDataChannels = function() { 
    console.log('Closing data channels'); 
    this._sendChannel.close(); 
    console.log('Closed data channel with label: ' + this._sendChannel.label); 
    this._receiveChannel.close(); 
    console.log('Closed data channel with label: ' + this._receiveChannel.label); 
    this._localConnection.close(); 
    this._remoteConnection.close(); 
    this._localConnection = null; 
    this._remoteConnection = null; 
    console.log('Closed peer connections'); 
} 

WebRTCManagerFn.prototype._gotOfferFromLocalConnection = function (desc) { 
    console.log('reached _gotOfferFromLocalConnection'); 
    if (this && this._localConnection != 'undefined' && this._remoteConnection != 'undefined') { 
     this._localConnection.setLocalDescription(desc); 
     console.log('Offer from localConnection \n' + desc.sdp); 
     this._remoteConnection.setRemoteDescription(desc); 
     this._remoteConnection.createAnswer(this._gotAnswerFromRemoteConnection.bind(this), 
      this._onCreateSessionDescriptionError.bind(this)); 
    } 
} 

WebRTCManagerFn.prototype._gotAnswerFromRemoteConnection = function (desc) { 
    console.log('reached _gotAnswerFromRemoteConnection'); 
    if (this && this._localConnection != 'undefined' && this._remoteConnection != 'undefined') { 
     this._remoteConnection.setLocalDescription(desc); 
     console.log('Answer from remoteConnection \n' + desc.sdp); 
     this._localConnection.setRemoteDescription(desc); 
    } 
} 

WebRTCManagerFn.prototype._localIceCallback = function (event) { 
    console.log('local ice callback'); 
    if (event.candidate) { 
     this._remoteConnection.addIceCandidate(event.candidate, 
      this._onAddIceCandidateSuccess.bind(this), this._onAddIceCandidateError.bind(this)); 
     console.log('Local ICE candidate: \n' + event.candidate.candidate); 
    } 
} 

WebRTCManagerFn.prototype._remoteIceCallback = function (event) { 
    console.log('remote ice callback'); 
    if (event.candidate) { 
     this._localConnection.addIceCandidate(event.candidate, 
      this._onAddIceCandidateSuccess.bind(this), this._onAddIceCandidateError.bind(this)); 
     console.log('Remote ICE candidate: \n ' + event.candidate.candidate); 
    } 
} 

WebRTCManagerFn.prototype._onAddIceCandidateSuccess = function (evt) { 
    debugger; 
    console.log('AddIceCandidate success. evt: '+ evt); 
} 

WebRTCManagerFn.prototype._onAddIceCandidateError = function (error) { 
    console.log('Failed to add Ice Candidate: ' + error.toString()); 
} 

WebRTCManagerFn.prototype._receiveChannelCallback = function (event) { 
    console.log('Receive Channel Callback'); 
    this._receiveChannel = event.channel; 
    this._receiveChannel.onmessage = this._onReceiveMessageCallback.bind(this); 
    this._receiveChannel.onopen = this._onReceiveChannelStateChange.bind(this); 
    this._receiveChannel.onclose = this._onReceiveChannelStateChange.bind(this); 
} 

WebRTCManagerFn.prototype._onReceiveMessageCallback = function (event) { 
    console.log('Received Message: ' + event.data); 
    console.log('Received Message this is: ' + this); 

    var msgObj = JSON.parse(event.data); 

    this._fireEvent("messageRecieved", { 
     details: { 
      msg: msgObj 
     } 
    }); 
} 

WebRTCManagerFn.prototype._onSendChannelStateChange = function() { 
    console.log('_onSendChannelStateChange'); 
    var readyState = this._sendChannel.readyState; 
    console.log('Send channel state is: ' + readyState); 
} 

WebRTCManagerFn.prototype._onReceiveChannelStateChange = function() { 
    var readyState = this._receiveChannel.readyState; 
    console.log('Receive channel state is: ' + readyState); 
} 

return WebRTCManagerFn; 
})(); 

Мой вопрос заключается в том, как данные проходят между двумя страницами на одной и той же машине с использованием WebRTC?

+0

У вас есть сигнальный сервер? У вас есть более конкретное описание проблемы с тем, что связано с передачей межстрановой страницы? – deceze

+0

В моей реализации сообщение получено внутри страницы. Я хотел бы иметь двухстороннюю связь между двумя разными страницами. Сервер сигнализации - это локальный хост. Я думаю, что мне что-то не хватает ... – Yaron

+0

Это означает, что вам нужен способ обмена сообщениями; это почти * нерелевантно, находится ли это между двумя страницами на одном компьютере или на разных компьютерах. Лучшим выбором является сервер сигнализации. Если вы можете уточнить точные ограничения и ситуацию, возможно, можно предложить другую альтернативу. – deceze

ответ

4

Эта WebRTC вкладка чата демо работает через вкладки или окна в том же браузере без сервера: https://jsfiddle.net/f5y48hcd/ (я отказался сделать его работу в фрагменте кода из-за SecurityError.)

Открыть скрипку в двух окнах и попробуйте. Для справки, вот код WebRTC:

var pc = new RTCPeerConnection(), dc, enterPressed = e => e.keyCode == 13; 

var connect =() => init(dc = pc.createDataChannel("chat")); 
pc.ondatachannel = e => init(dc = e.channel); 

var init = dc => { 
    dc.onopen = e => (dc.send("Hi!"), chat.select()); 
    dc.onclose = e => log("Bye!"); 
    dc.onmessage = e => log(e.data); 
}; 

chat.onkeypress = e => { 
    if (!enterPressed(e)) return; 
    dc.send(chat.value); 
    log("> " + chat.value); 
    chat.value = ""; 
}; 

var sc = new localSocket(), send = obj => sc.send(JSON.stringify(obj)); 
var incoming = msg => msg.sdp && 
    pc.setRemoteDescription(new RTCSessionDescription(msg.sdp)) 
    .then(() => pc.signalingState == "stable" || pc.createAnswer() 
    .then(answer => pc.setLocalDescription(answer)) 
    .then(() => send({ sdp: pc.localDescription }))) 
    .catch(log) || msg.candidate && 
    pc.addIceCandidate(new RTCIceCandidate(msg.candidate)).catch(log); 
sc.onmessage = e => incoming(JSON.parse(e.data)); 

pc.oniceconnectionstatechange = e => log(pc.iceConnectionState); 
pc.onicecandidate = e => send({ candidate: e.candidate }); 
pc.onnegotiationneeded = e => pc.createOffer() 
    .then(offer => pc.setLocalDescription(offer)) 
    .then(() => send({ sdp: pc.localDescription })) 
    .catch(log); 

var log = msg => div.innerHTML += "<br>" + msg; 

Я использую это для демонстрации каналов данных WebRTC. Обратите внимание, что секретный соус является localSocket.js, что я написал для этого, который выглядит следующим образом:

function localSocket() { 
    localStorage.a = localStorage.b = JSON.stringify([]); 
    this.index = 0; 
    this.interval = setInterval(() => { 
    if (!this.in) { 
     if (!JSON.parse(localStorage.a).length) return; 
     this.in = "a"; this.out = "b"; 
    } 
    var arr = JSON.parse(localStorage[this.in]); 
    if (arr.length <= this.index) return; 
    if (this.onmessage) this.onmessage({ data: arr[this.index] }); 
    this.index++; 
    }, 200); 
    setTimeout(() => this.onopen && this.onopen({})); 
} 
localSocket.prototype = { 
    send: function(msg) { 
    if (!this.out) { 
     this.out = "a"; this.in = "b"; 
    } 
    var arr = JSON.parse(localStorage[this.out]); 
    arr.push(msg); 
    localStorage[this.out] = JSON.stringify(arr); 
    }, 
    close: function() { 
    clearInterval(this.interval); 
    } 
}; 

Это в основном использует LocalStorage для имитации веб-сокетов локально между двумя вкладками. Если это все, что вы хотите сделать, вам даже не нужны каналы данных WebRTC.

Отказ от ответственности: Он не очень надежный и полагается на две страницы, готовые к общению, а не готовые к производству любыми способами.

+0

Это очень приятно, но это не ассассалистика двух вкладок, а не только неассаральных текстовых сообщений. Я пытаюсь исследовать skylake chat. Это очень близко к тому, что я пытаюсь достичь. – Yaron

+0

Кажется, что все, что вы просили. Пожалуйста, уточните, что вы ищете, чего не делаете. – jib

+0

Прежде всего, я очень ценю ваш ответ. Локальное хранилище проблематично, поскольку оно ограничивает решение только приложениями, запущенными в браузере Chrome. WebRTC поддерживается на границе MS и FireFox, и между ними может быть обмен сообщениями. Я нахожусь в поиске реального кросс-браузера IPC. – Yaron

Смежные вопросы