Skip to content

Instantly share code, notes, and snippets.

@mganeko
Last active September 18, 2025 07:44
Show Gist options
  • Save mganeko/160a298bcc9f5c237dd4 to your computer and use it in GitHub Desktop.
Save mganeko/160a298bcc9f5c237dd4 to your computer and use it in GitHub Desktop.

Revisions

  1. mganeko revised this gist Dec 2, 2014. 1 changed file with 159 additions and 178 deletions.
    337 changes: 159 additions & 178 deletions signaling_mqtt.html
    Original file line number Diff line number Diff line change
    @@ -26,212 +26,193 @@
    var peerStarted = false;
    var mediaConstraints = {'mandatory': {'OfferToReceiveAudio':false, 'OfferToReceiveVideo':true }};
    //var mediaConstraints = {'mandatory': {'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }};
    //var signalingMode = "answer"; // or "offer"


    function onSDPText() {
    var text = textToReceiveSDP.value;
    if (peerConnection) {
    onAnswerText(text);
    }
    else {
    onOfferText(text);
    }
    textToReceiveSDP.value ="";
    var text = textToReceiveSDP.value;
    if (peerConnection) {
    onAnswerText(text);
    }
    else {
    onOfferText(text);
    }
    textToReceiveSDP.value ="";
    }

    function onOfferText(text) {
    console.log("Received offer text...")
    console.log(text);
    setOfferText(text);
    makeAnswer();
    console.log("Received offer text...")
    console.log(text);
    setOfferText(text);
    makeAnswer();
    }

    function onAnswerText(text) {
    console.log("Received answer text...")
    console.log(text);
    setAnswerText(text);
    console.log("Received answer text...")
    console.log(text);
    setAnswerText(text);
    }

    function sendSDPText(text) {
    console.log("---sending sdp text ---");
    console.log(text);
    console.log("---sending sdp text ---");
    console.log(text);

    textForSendSDP.value = text;
    textForSendSDP.focus();
    textForSendSDP.select();
    textForSendSDP.value = text;
    textForSendSDP.focus();
    textForSendSDP.select();
    }

    // ---------------------- video handling -----------------------
    // start local video
    function startVideo() {
    navigator.webkitGetUserMedia({video: true, audio: false},
    function (stream) { // success
    localStream = stream;
    localVideo.src = window.webkitURL.createObjectURL(stream);
    localVideo.play();
    localVideo.volume = 0;
    },
    function (error) { // error
    console.error('An error occurred: [CODE ' + error.code + ']');
    return;
    }
    );
    navigator.webkitGetUserMedia({video: true, audio: false},
    function (stream) { // success
    localStream = stream;
    localVideo.src = window.webkitURL.createObjectURL(stream);
    localVideo.play();
    localVideo.volume = 0;
    },
    function (error) { // error
    console.error('An error occurred: [CODE ' + error.code + ']');
    return;
    }
    );
    }

    // stop local video
    function stopVideo() {
    localVideo.src = "";
    localStream.stop();
    localVideo.src = "";
    localStream.stop();
    }

    // ---------------------- connection handling -----------------------
    function prepareNewConnection() {
    var pc_config = {"iceServers":[]};
    var peer = null;
    try {
    peer = new webkitRTCPeerConnection(pc_config);
    } catch (e) {
    console.log("Failed to create peerConnection, exception: " + e.message);
    var pc_config = {"iceServers":[]};
    var peer = null;
    try {
    peer = new webkitRTCPeerConnection(pc_config);
    } catch (e) {
    console.log("Failed to create peerConnection, exception: " + e.message);
    }

    // send any ice candidates to the other peer
    peer.onicecandidate = function (evt) {
    if (evt.candidate) {
    console.log(evt.candidate);
    } else {
    console.log("ice event phase =" + evt.eventPhase);
    sendSDPTextMQTT(peer.localDescription.type, peer.localDescription.sdp);
    }
    };

    // send any ice candidates to the other peer
    peer.onicecandidate = function (evt) {
    if (evt.candidate) {
    console.log(evt.candidate);
    /*
    sendCandidate({type: "candidate",
    sdpMLineIndex: evt.candidate.sdpMLineIndex,
    sdpMid: evt.candidate.sdpMid,
    candidate: evt.candidate.candidate}
    );
    */
    } else {
    console.log("ice event phase =" + evt.eventPhase);
    //sendSDPText(peer.localDescription.sdp);
    sendSDPTextMQTT(peer.localDescription.type, peer.localDescription.sdp);
    }

    //sendSDPText(peer.localDescription.sdp);
    };

    peer.oniceconnectionstatechange = function() {
    console.log('ice connection status=' + peer.iceConnectionState + ' gahter=' + peer.iceGatheringState);
    if ('completed' === peer.iceConnectionState) {
    console.log("candidate complete");
    }
    };

    peer.onsignalingstatechange = function() {
    console.log('signaling status=' + peer.signalingState);
    };

    console.log('Adding local stream...');
    peer.addStream(localStream);

    peer.addEventListener("addstream", onRemoteStreamAdded, false);
    peer.addEventListener("removestream", onRemoteStreamRemoved, false)


    // when remote adds a stream, hand it on to the local video element
    function onRemoteStreamAdded(event) {
    console.log("Added remote stream");
    remoteVideo.src = window.webkitURL.createObjectURL(event.stream);
    peer.oniceconnectionstatechange = function() {
    console.log('ice connection status=' + peer.iceConnectionState + ' gahter=' + peer.iceGatheringState);
    if ('completed' === peer.iceConnectionState) {
    console.log("candidate complete");
    }
    };

    // when remote removes a stream, remove it from the local video element
    function onRemoteStreamRemoved(event) {
    console.log("Remove remote stream");
    remoteVideo.src = "";
    }
    peer.onsignalingstatechange = function() {
    console.log('signaling status=' + peer.signalingState);
    };

    return peer;
    console.log('Adding local stream...');
    peer.addStream(localStream);

    peer.addEventListener("addstream", onRemoteStreamAdded, false);
    peer.addEventListener("removestream", onRemoteStreamRemoved, false)

    // when remote adds a stream, hand it on to the local video element
    function onRemoteStreamAdded(event) {
    console.log("Added remote stream");
    remoteVideo.src = window.webkitURL.createObjectURL(event.stream);
    }

    // when remote removes a stream, remove it from the local video element
    function onRemoteStreamRemoved(event) {
    console.log("Remove remote stream");
    remoteVideo.src = "";
    }

    return peer;
    }

    function makeOffer() {
    //signalingMode = "offer";
    unsubscribe("offer");
    subscribe("answer");
    peerConnection = prepareNewConnection();
    peerConnection.createOffer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    //sendSDP(sessionDescription);
    }, function () { // in case of error
    console.log("Create Offer failed");
    }, mediaConstraints);
    unsubscribe("offer");
    subscribe("answer");
    peerConnection = prepareNewConnection();
    peerConnection.createOffer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    }, function () { // in case of error
    console.log("Create Offer failed");
    }, mediaConstraints);
    }

    function setOfferText(text) {
    if (peerConnection) {
    console.error('peerConnection alreay exist!');
    }
    peerConnection = prepareNewConnection();
    var offer = new RTCSessionDescription({
    type : 'offer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(offer);
    if (peerConnection) {
    console.error('peerConnection alreay exist!');
    }
    peerConnection = prepareNewConnection();
    var offer = new RTCSessionDescription({
    type : 'offer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(offer);
    }


    function makeAnswer(evt) {
    console.log('sending Answer. Creating remote session description...' );
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }

    peerConnection.createAnswer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    //sendSDP(sessionDescription);
    }, function () { // in case of error
    console.log("Create Answer failed");
    }, mediaConstraints);
    console.log('sending Answer. Creating remote session description...' );
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }

    peerConnection.createAnswer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    }, function () { // in case of error
    console.log("Create Answer failed");
    }, mediaConstraints);
    }

    function setAnswerText(text) {
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }
    var answer = new RTCSessionDescription({
    type : 'answer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(answer);
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }
    var answer = new RTCSessionDescription({
    type : 'answer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(answer);
    }


    // -------- handling user UI event -----
    // start the connection upon user request
    function connect() {
    if (!peerStarted && localStream) {
    makeOffer();
    peerStarted = true;
    } else {
    alert("Local stream not running yet - try again.");
    }
    if (!peerStarted && localStream) {
    makeOffer();
    peerStarted = true;
    } else {
    alert("Local stream not running yet - try again.");
    }
    }

    // stop the connection upon user request
    function hangUp() {
    console.log("Hang up.");
    stop();
    console.log("Hang up.");
    stop();
    }

    function stop() {
    peerConnection.close();
    peerConnection = null;
    peerStarted = false;
    peerConnection.close();
    peerConnection = null;
    peerStarted = false;
    }





    // ---------------------------
    // from
    // http://tdoc.info/blog/2014/09/25/mqtt_javascript.html
    @@ -246,55 +227,55 @@
    client.connect({userName: user_name, password: pass, onSuccess:onConnect, onFailure: failConnect});

    function failConnect(e) {
    console.log("connect failed");
    console.log(e);
    console.log("connect failed");
    console.log(e);
    }

    function onConnect() {
    console.log("onConnect");
    subscribe("offer");
    console.log("onConnect");
    subscribe("offer");
    }

    function buildTopic(signalingType) {
    var topic = user_name + '/signaling/' + signalingType;
    return topic;
    var topic = user_name + '/signaling/' + signalingType;
    return topic;
    }

    // callback for receiving message
    function onMessageArrived(message) {
    console.log("onMessageArrived:" + message.destinationName + ' -- ' + message.payloadString);

    if (message.destinationName === buildTopic('answer')) {
    onAnswerText(message.payloadString)
    }
    else if (message.destinationName === buildTopic('offer')) {
    onOfferText(message.payloadString)
    }
    else {
    console.warn('Bad SDP topic');
    }
    console.log("onMessageArrived:" + message.destinationName + ' -- ' + message.payloadString);

    if (message.destinationName === buildTopic('answer')) {
    onAnswerText(message.payloadString)
    }
    else if (message.destinationName === buildTopic('offer')) {
    onOfferText(message.payloadString)
    }
    else {
    console.warn('Bad SDP topic');
    }
    }

    function subscribe(waitType) {
    // set callback
    client.onMessageArrived = onMessageArrived;
    // set callback
    client.onMessageArrived = onMessageArrived;

    // Subscribe
    var topic = buildTopic(waitType);
    client.subscribe(topic);
    // Subscribe
    var topic = buildTopic(waitType);
    client.subscribe(topic);
    }

    function unsubscribe(waitType) {
    // UnSubscribe
    var topic = buildTopic(waitType);
    client.unsubscribe(topic);
    // UnSubscribe
    var topic = buildTopic(waitType);
    client.unsubscribe(topic);
    }

    function sendSDPTextMQTT(type, text){
    var topic = buildTopic(type);
    message = new Paho.MQTT.Message(text);
    message.destinationName = topic;
    client.send(message);
    var topic = buildTopic(type);
    message = new Paho.MQTT.Message(text);
    message.destinationName = topic;
    client.send(message);
    }

    </script>
  2. mganeko revised this gist Dec 2, 2014. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions signaling_mqtt.html
    Original file line number Diff line number Diff line change
    @@ -208,7 +208,6 @@
    // -------- handling user UI event -----
    // start the connection upon user request
    function connect() {
    //if (!peerStarted && localStream && channelReady) {
    if (!peerStarted && localStream) {
    makeOffer();
    peerStarted = true;
    @@ -234,14 +233,15 @@


    // ---------------------------
    // from
    // http://tdoc.info/blog/2014/09/25/mqtt_javascript.html

    var clientId = "web_client_01";
    var user_name = "mganeko@github";
    var pass = "4isGlJjqRXw0Xu9i";
    var user_name = "your_github_id@github";
    var pass = "your_sango_password";
    var wsurl = "ws://lite.mqtt.shiguredo.jp:8080/mqtt";

    // WebSocketURLとClientIDからMQTT Clientを作成します
    // connect to MQTT broker
    var client = new Paho.MQTT.Client(wsurl, clientId);
    client.connect({userName: user_name, password: pass, onSuccess:onConnect, onFailure: failConnect});

  3. mganeko created this gist Dec 2, 2014.
    301 changes: 301 additions & 0 deletions signaling_mqtt.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,301 @@
    <!DOCTYPE html>
    <html>
    <head>
    <title>MQTT signaling</title>
    <meta charset="urt-8"/>
    <script src="http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git/plain/src/mqttws31.js"></script>
    </head>
    <body>
    <button type="button" onclick="startVideo();">Start video</button>
    <button type="button" onclick="stopVideo();">Stop video</button>

    <button type="button" onclick="connect();">Connect</button>
    <button type="button" onclick="hangUp();">Hang Up</button>
    <br />
    <div>
    <video id="local-video" autoplay style="width: 240px; height: 180px; border: 1px solid black;"></video>
    <video id="remote-video" autoplay style="width: 240px; height: 180px; border: 1px solid black;"></video>
    </div>

    </body>
    <script>
    var localVideo = document.getElementById('local-video');
    var remoteVideo = document.getElementById('remote-video');
    var localStream = null;
    var peerConnection = null;
    var peerStarted = false;
    var mediaConstraints = {'mandatory': {'OfferToReceiveAudio':false, 'OfferToReceiveVideo':true }};
    //var mediaConstraints = {'mandatory': {'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }};
    //var signalingMode = "answer"; // or "offer"

    function onSDPText() {
    var text = textToReceiveSDP.value;
    if (peerConnection) {
    onAnswerText(text);
    }
    else {
    onOfferText(text);
    }
    textToReceiveSDP.value ="";
    }

    function onOfferText(text) {
    console.log("Received offer text...")
    console.log(text);
    setOfferText(text);
    makeAnswer();
    }

    function onAnswerText(text) {
    console.log("Received answer text...")
    console.log(text);
    setAnswerText(text);
    }

    function sendSDPText(text) {
    console.log("---sending sdp text ---");
    console.log(text);

    textForSendSDP.value = text;
    textForSendSDP.focus();
    textForSendSDP.select();
    }

    // ---------------------- video handling -----------------------
    // start local video
    function startVideo() {
    navigator.webkitGetUserMedia({video: true, audio: false},
    function (stream) { // success
    localStream = stream;
    localVideo.src = window.webkitURL.createObjectURL(stream);
    localVideo.play();
    localVideo.volume = 0;
    },
    function (error) { // error
    console.error('An error occurred: [CODE ' + error.code + ']');
    return;
    }
    );
    }

    // stop local video
    function stopVideo() {
    localVideo.src = "";
    localStream.stop();
    }

    // ---------------------- connection handling -----------------------
    function prepareNewConnection() {
    var pc_config = {"iceServers":[]};
    var peer = null;
    try {
    peer = new webkitRTCPeerConnection(pc_config);
    } catch (e) {
    console.log("Failed to create peerConnection, exception: " + e.message);
    }

    // send any ice candidates to the other peer
    peer.onicecandidate = function (evt) {
    if (evt.candidate) {
    console.log(evt.candidate);
    /*
    sendCandidate({type: "candidate",
    sdpMLineIndex: evt.candidate.sdpMLineIndex,
    sdpMid: evt.candidate.sdpMid,
    candidate: evt.candidate.candidate}
    );
    */
    } else {
    console.log("ice event phase =" + evt.eventPhase);
    //sendSDPText(peer.localDescription.sdp);
    sendSDPTextMQTT(peer.localDescription.type, peer.localDescription.sdp);
    }

    //sendSDPText(peer.localDescription.sdp);
    };

    peer.oniceconnectionstatechange = function() {
    console.log('ice connection status=' + peer.iceConnectionState + ' gahter=' + peer.iceGatheringState);
    if ('completed' === peer.iceConnectionState) {
    console.log("candidate complete");
    }
    };

    peer.onsignalingstatechange = function() {
    console.log('signaling status=' + peer.signalingState);
    };

    console.log('Adding local stream...');
    peer.addStream(localStream);

    peer.addEventListener("addstream", onRemoteStreamAdded, false);
    peer.addEventListener("removestream", onRemoteStreamRemoved, false)


    // when remote adds a stream, hand it on to the local video element
    function onRemoteStreamAdded(event) {
    console.log("Added remote stream");
    remoteVideo.src = window.webkitURL.createObjectURL(event.stream);
    }

    // when remote removes a stream, remove it from the local video element
    function onRemoteStreamRemoved(event) {
    console.log("Remove remote stream");
    remoteVideo.src = "";
    }

    return peer;
    }

    function makeOffer() {
    //signalingMode = "offer";
    unsubscribe("offer");
    subscribe("answer");
    peerConnection = prepareNewConnection();
    peerConnection.createOffer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    //sendSDP(sessionDescription);
    }, function () { // in case of error
    console.log("Create Offer failed");
    }, mediaConstraints);
    }

    function setOfferText(text) {
    if (peerConnection) {
    console.error('peerConnection alreay exist!');
    }
    peerConnection = prepareNewConnection();
    var offer = new RTCSessionDescription({
    type : 'offer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(offer);
    }


    function makeAnswer(evt) {
    console.log('sending Answer. Creating remote session description...' );
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }

    peerConnection.createAnswer(function (sessionDescription) { // in case of success
    peerConnection.setLocalDescription(sessionDescription);
    console.log("Sending: SDP");
    console.log(sessionDescription);
    //sendSDP(sessionDescription);
    }, function () { // in case of error
    console.log("Create Answer failed");
    }, mediaConstraints);
    }

    function setAnswerText(text) {
    if (! peerConnection) {
    console.error('peerConnection NOT exist!');
    return;
    }
    var answer = new RTCSessionDescription({
    type : 'answer',
    sdp : text,
    });
    peerConnection.setRemoteDescription(answer);
    }


    // -------- handling user UI event -----
    // start the connection upon user request
    function connect() {
    //if (!peerStarted && localStream && channelReady) {
    if (!peerStarted && localStream) {
    makeOffer();
    peerStarted = true;
    } else {
    alert("Local stream not running yet - try again.");
    }
    }

    // stop the connection upon user request
    function hangUp() {
    console.log("Hang up.");
    stop();
    }

    function stop() {
    peerConnection.close();
    peerConnection = null;
    peerStarted = false;
    }





    // ---------------------------
    // http://tdoc.info/blog/2014/09/25/mqtt_javascript.html

    var clientId = "web_client_01";
    var user_name = "mganeko@github";
    var pass = "4isGlJjqRXw0Xu9i";
    var wsurl = "ws://lite.mqtt.shiguredo.jp:8080/mqtt";

    // WebSocketURLとClientIDからMQTT Clientを作成します
    var client = new Paho.MQTT.Client(wsurl, clientId);
    client.connect({userName: user_name, password: pass, onSuccess:onConnect, onFailure: failConnect});

    function failConnect(e) {
    console.log("connect failed");
    console.log(e);
    }

    function onConnect() {
    console.log("onConnect");
    subscribe("offer");
    }

    function buildTopic(signalingType) {
    var topic = user_name + '/signaling/' + signalingType;
    return topic;
    }

    // callback for receiving message
    function onMessageArrived(message) {
    console.log("onMessageArrived:" + message.destinationName + ' -- ' + message.payloadString);

    if (message.destinationName === buildTopic('answer')) {
    onAnswerText(message.payloadString)
    }
    else if (message.destinationName === buildTopic('offer')) {
    onOfferText(message.payloadString)
    }
    else {
    console.warn('Bad SDP topic');
    }
    }

    function subscribe(waitType) {
    // set callback
    client.onMessageArrived = onMessageArrived;

    // Subscribe
    var topic = buildTopic(waitType);
    client.subscribe(topic);
    }

    function unsubscribe(waitType) {
    // UnSubscribe
    var topic = buildTopic(waitType);
    client.unsubscribe(topic);
    }

    function sendSDPTextMQTT(type, text){
    var topic = buildTopic(type);
    message = new Paho.MQTT.Message(text);
    message.destinationName = topic;
    client.send(message);
    }

    </script>
    </html>