Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

혼자서 앱 만드는 개발자 함께하는 AI 세상

webrtc 채팅 텍스트 데이터 전송을 위한 datachannel 추가 본문

WEBRTC

webrtc 채팅 텍스트 데이터 전송을 위한 datachannel 추가

혼앱사 2023. 1. 9. 00:34
반응형
  •  메세지 전송 버튼 처리 추가  데이터 채널을 만들어서 서로 메세지를 교환한다.

pc.ondatachannel = function (event) { // 데이터 채널로부터 이벤트를 받아올때 처리하는  로직(받는쪽 로직)
 var receiveChannel = event.channel;
        receiveChannel.onmessage = function (event) {
          console.log(  event );
          var data= JSON.parse(event.data);
                      console.log(  data.message ,data.timestamp ); // 우선 콘솔에 찍어줌
                };
            }; 
var dataChannelOptions = { 
                  reliable:true 
                };

 

pc.ondatachannel = function (event) { // 데이터 채널로부터 이벤트를 받아올때 처리하는  로직(받는쪽 로직)
 var receiveChannel = event.channel;
        receiveChannel.onmessage = function (event) {
          console.log(  event );
          var data= JSON.parse(event.data);
                      console.log(  data.message ,data.timestamp ); // 우선 콘솔에 찍어줌
                };
            }; 
 
var dataChannelOptions = { 
                  reliable:true 
                }; 
dc = pc.createDataChannel("message",dataChannelOptions);// 데이터 채널 생성

 dc.onerror = function (error) {console.log("Error:", error); };
 var sendMsgBtn = document.querySelector('#sendbtn'); 
sendMsgBtn.addEventListener("click", function (event) {  //화면에서 버튼을 클릭할때 메세지를 보냄
   console.log("send message");
     const obj = {
"message": 'send Message' ,
"timestamp": new Date()
  } 
   dc.send(JSON.stringify(obj));  // 메세지를 보내는 부분
 });


  
       

 아래 빨간색 칠한 부분을 추가해 주면 적용된다.

 

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
</head>

<body>
    <div>
        <video id="localVideo" autoplay="true" muted="muted"></video>
        <video id="remoteVideo" autoplay="true" style="display:"></video>

		<input type="button" name="sendbtn" id="sendbtn" value="send"  ></input>

         
    </div>
    <script type="text/javascript">

        var answer = 0;
        var pc = null;
		var pc2 = null
        var localStream = null;
        var ws = null;
		var dc = null;

        // Not necessary with websockets, but here I need it to distinguish calls
        var unique = Math.floor(100000 + Math.random() * 900000);
	    var localVideo = document.getElementById('localVideo');
        var remoteVideo = document.getElementById('remoteVideo');
        var configuration = {
            'iceServers': [
                 { 'urls': 'stun:stun.stunprotocol.org:3478' },
                 { 'urls': 'stun:stun.l.google.com:19302' }
                ]
        };
        // Start
        navigator.mediaDevices.getUserMedia({
            audio: true, // audio is off here, enable this line to get audio too
            video: true
        }).then(function (stream) {
            localVideo.srcObject = stream;
            localStream = stream;
            try {
                ws = new EventSource('serverGet.php?unique=' + unique);
            } catch (e) {
                console.error("Could not create eventSource ", e);
            }

            // Websocket-hack: EventSource does not have a 'send()'
            // so I use an ajax-xmlHttpRequest for posting data.
            // Now the eventsource-functions are equal to websocket.
            ws.send = function send(message) {
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function () {
                    if (this.readyState != 4) {
                        return;
                    }
                    if (this.status != 200) {
                        console.log("Error sending to server with message: " + message);
                    }
                };
                xhttp.open('POST', 'serverPost.php?unique=' + unique, true);
                xhttp.setRequestHeader("Content-Type", "Application/X-Www-Form-Urlencoded");
                xhttp.send(message);
            }

            // Websocket-hack: onmessage is extended for receiving 
            // multiple events at once for speed, because the polling 
            // frequency of EventSource is low.
            ws.onmessage = function (e) {
                if (e.data.includes("_MULTIPLEVENTS_")) {
                    console.log("74 line==============");
                    console.log(e);

                    multiple = e.data.split("_MULTIPLEVENTS_");
                    for (x = 0; x < multiple.length; x++) {
                        console.log(multiple[x])
                        onsinglemessage(multiple[x]);
                    }
                } else {
                    console.log("81 ------> line==============");
                    console.log(e.data);
                    onsinglemessage(e.data);
                }
            }

            // Go show myself
            localVideo.addEventListener('loadedmetadata',
                function () {
                    publish('client-call', null)
                }
            );

        }).catch(function (e) {
            console.log("Problem while getting audio/video stuff ", e);
        });


        function onsinglemessage(data) {
            var package = JSON.parse(data);
            var data = package.data;

            console.log("received single message: " + package.event);
            switch (package.event) {
                case 'client-call':
                    icecandidate(localStream);
                    pc.createOffer({
                        offerToReceiveAudio: 1,
                        offerToReceiveVideo: 1
                    }).then(function (desc) {
                        pc.setLocalDescription(desc).then(
                            function () {
                                publish('client-offer', pc.localDescription);
                            }
                        ).catch(function (e) {
                            console.log("Problem with publishing client offer" + e);
                        });
                    }).catch(function (e) {
                        console.log("Problem while doing client-call: " + e);
                    });
                    break;
                case 'client-answer':
                    if (pc == null) {
                        console.error('Before processing the client-answer, I need a client-offer');
                        break;
                    }
                    pc.setRemoteDescription(new RTCSessionDescription(data), function () { },
                        function (e) {
                            console.log("Problem while doing client-answer: ", e);
                        });
                    break;
                case 'client-offer':
                    icecandidate(localStream);
                    pc.setRemoteDescription(new RTCSessionDescription(data), function () {
                        if (!answer) {
                            pc.createAnswer(function (desc) {
                                pc.setLocalDescription(desc, function () {
                                    publish('client-answer', pc.localDescription);
                                }, function (e) {
                                    console.log("Problem getting client answer: ", e);
                                });
                            }
                                , function (e) {
                                    console.log("Problem while doing client-offer: ", e);
                                });
                            answer = 1;
                        }
                    }, function (e) {
                        console.log("Problem while doing client-offer2: ", e);
                    });
                    break;
                case 'client-candidate':
				console.log("156==============================================client-candidate");
				console.log(pc);
                    if (pc == null) {
                        console.error('Before processing the client-answer, I need a client-offer');
                        break;
                    }
                    pc.addIceCandidate(new RTCIceCandidate(data), function () { },
                        function (e) { console.log("Problem adding ice candidate: " + e); });
                    break;
            }
        };
      function icecandidate(localStream) {
            pc = new RTCPeerConnection(configuration);
		    pc.onicecandidate = function (event) {
                if (event.candidate) {
                    publish('client-candidate', event.candidate);
					 send({ 
                           type: "candidate", 
                           candidate: event.candidate 
                        });
                }
            };
            try {
                pc.addStream(localStream);
            } catch (e) {
                var tracks = localStream.getTracks();
                for (var i = 0; i < tracks.length; i++) {
                    pc.addTrack(tracks[i], localStream);
                }
            }
            pc.ontrack = function (e) {
                //  document.getElementById('remoteVideo').style.display="block";
                // document.getElementById('localVideo').style.display="none";
                remoteVideo.srcObject = e.streams[0];
            };

			  pc.ondatachannel = function (event) {
                      var receiveChannel = event.channel;
                      receiveChannel.onmessage = function (event) {
                          console.log("ondatachannel message:", event.data);
                      };
                  }; 


			var dataChannelOptions = { 
                  reliable:true 
                };
			 dc = pc.createDataChannel("message",dataChannelOptions);
		 

			 dc.onerror = function (error) { 
                  console.log("Error:", error); 
               };

             dc.onmessage = function (event) { 
                  console.log("Got message:", event.data); 
               };  
			 var sendMsgBtn = document.querySelector('#sendbtn'); 
			 sendMsgBtn.addEventListener("click", function (event) { 
							   console.log("send message");
							//   var val = msgInput.value; 
							   dc.send("send message"); 
							});
 

        }
        function publish(event, data) {
            console.log("sending ws.send: " + event);
            console.log("sending ws.send: data: " + data);
            console.log(data);
            ws.send(JSON.stringify({
                event: event,
                data: data
            }));
        }


		function sendMessage(msg) {
			  const obj = {
				"message": msg,
				"timestamp": new Date()
			  }
				console.log(dc);
				dc.send(JSON.stringify(obj));
			}


    </script>
</body>

</html>

 

 

  • - 관련 사이트


https://doublem.org/webrtc-story-02/

 

WebRTC 시그널링 서버 구현하기 | Doublem.org

WebRTC 시그널링을 구현해보자

doublem.org

http://john-home.iptime.org:8085/xe/index.php?mid=board_sKSz42&document_srl=1439

 

관련 용어 

SDP는 Session Description Protocol로 RFC 4566에 규정된 스트리밍 미디어의 초기화 인수를 기술하고 협상하기 위한 것이다.

728x90
반응형
Comments