일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 마이봇#챗봇
- figma#flutter#dhwise#피그마#플러터#피그마 to 플러터 #figma to flutter
- flutterfire configure#파이어베이스#플러터
- 펫버틀러#서버연동#프로필등록#로그인서버연동#이미지#동영상#업로드용 화면#앱개발#플러터#반려생활#로딩바#loading bar#
- 마이봇#핸드폰대체#
- 커피#그라인더#통돌이 오픈 #로스팅#드립커피#생두#원두
- firebase#message#메세지#플러터#안드로이드
- flutter#ios#앱개발#마이봇#
- #창작#SNS#스포츠#반려동물#연애#과제#레시피#활동#건강#운세#글쓰기#비즈니스 #AI비서#챗GPT#CHATGPT
- 플러터#
- 임대사업자#리걸테크#legaltech#마이봇#챗봇#법률챗봇#임대사업자챗봇#chatgpt#
- postgres#vector
- 로우코드#ERP#관리시스템#상품관리#선택박스#자동화프로그램
- 플러터#sms#mms#문자보내기
- 마이봇#API 설정
- 시트메타#관리시스템#테이블연동#품목관리
- flutter#채팅창@메모창#url링크#날짜추가
- 마이봇#문서챗봇#PDF#TEXT#유투브#챗봇만들기#랭체인# langchain#벡터데이터#자료검색#챗GPT#GPT4#챗지피티
- 마이봇#chatgpt#ai#인공지능
- ax5#tree#grid#단계별 펼치기# depth #시트메타
- 쇼핑몰관리시스템#매입관리#시트메타#매입채널#엑셀업로드
- 로우코드#lowcode#erp#관리시스템#시트메이트#시트메타#엑셀업로드#엑셀다운로드#그리드#데이터관리#생산관리시스템#로그관리#히스토리#입력체크
- 마이봇#pdf챗봇#상담챗봇#faq챗봇#chatgpt#랭체인#llm
- PDF검색#PDF검색챗봇#NEXTJS#스터디#스타트업#랭체이#langchain#prisma#sqlite#
- fcm#메세지전송#안드로이드메세지#플러터메세지전송
- flutter#sqlite#chatGPT#
- mediasaop#webrtc#미디어서버#
- PDF#챗봇검색#서비스#GPT4#PGT3.5#GPT#랭체인#챗봇#CHATBOT#LLM#문서검색
- 마이봇#아이폰#아이폰심사#IT고시#
- 광동온더그린#프랜즈#가상CC#스크린골프#
- Today
- Total
혼자서 앱 만드는 개발자 함께하는 AI 세상
webrtc 채팅 텍스트 데이터 전송을 위한 datachannel 추가 본문
- 메세지 전송 버튼 처리 추가 데이터 채널을 만들어서 서로 메세지를 교환한다.
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/
http://john-home.iptime.org:8085/xe/index.php?mid=board_sKSz42&document_srl=1439
관련 용어
SDP는 Session Description Protocol로 RFC 4566에 규정된 스트리밍 미디어의 초기화 인수를 기술하고 협상하기 위한 것이다.
'WEBRTC' 카테고리의 다른 글
pdf 파일 불러와서 canvas 그리기 테스트1 (1) | 2024.03.20 |
---|---|
mediasoup-demo 적용 (0) | 2024.03.08 |
webrtc 기반의 간단한 웹 기반 오픈 채팅방 구축 하기 (0) | 2023.02.11 |
WEBRTC (PHP 웹 적용 구성)- 첫(1)번째 HTML 구성하기 (0) | 2023.01.07 |