├── .gitignore
├── README.md
├── webrtc_local_communication
├── rtc.html
└── rtc.js
└── webrtc_server_client
├── index.js
├── package-lock.json
├── package.json
├── rtc.html
└── rtc.js
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/node,macos
3 | # Edit at https://www.gitignore.io/?templates=node,macos
4 |
5 | ### macOS ###
6 | # General
7 | .DS_Store
8 | .AppleDouble
9 | .LSOverride
10 |
11 | # Icon must end with two \r
12 | Icon
13 |
14 | # Thumbnails
15 | ._*
16 |
17 | # Files that might appear in the root of a volume
18 | .DocumentRevisions-V100
19 | .fseventsd
20 | .Spotlight-V100
21 | .TemporaryItems
22 | .Trashes
23 | .VolumeIcon.icns
24 | .com.apple.timemachine.donotpresent
25 |
26 | # Directories potentially created on remote AFP share
27 | .AppleDB
28 | .AppleDesktop
29 | Network Trash Folder
30 | Temporary Items
31 | .apdisk
32 |
33 | ### Node ###
34 | # Logs
35 | logs
36 | *.log
37 | npm-debug.log*
38 | yarn-debug.log*
39 | yarn-error.log*
40 | lerna-debug.log*
41 |
42 | # Diagnostic reports (https://nodejs.org/api/report.html)
43 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
44 |
45 | # Runtime data
46 | pids
47 | *.pid
48 | *.seed
49 | *.pid.lock
50 |
51 | # Directory for instrumented libs generated by jscoverage/JSCover
52 | lib-cov
53 |
54 | # Coverage directory used by tools like istanbul
55 | coverage
56 | *.lcov
57 |
58 | # nyc test coverage
59 | .nyc_output
60 |
61 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
62 | .grunt
63 |
64 | # Bower dependency directory (https://bower.io/)
65 | bower_components
66 |
67 | # node-waf configuration
68 | .lock-wscript
69 |
70 | # Compiled binary addons (https://nodejs.org/api/addons.html)
71 | build/Release
72 |
73 | # Dependency directories
74 | node_modules/
75 | jspm_packages/
76 |
77 | # TypeScript v1 declaration files
78 | typings/
79 |
80 | # TypeScript cache
81 | *.tsbuildinfo
82 |
83 | # Optional npm cache directory
84 | .npm
85 |
86 | # Optional eslint cache
87 | .eslintcache
88 |
89 | # Optional REPL history
90 | .node_repl_history
91 |
92 | # Output of 'npm pack'
93 | *.tgz
94 |
95 | # Yarn Integrity file
96 | .yarn-integrity
97 |
98 | # dotenv environment variables file
99 | .env
100 | .env.test
101 |
102 | # parcel-bundler cache (https://parceljs.org/)
103 | .cache
104 |
105 | # next.js build output
106 | .next
107 |
108 | # nuxt.js build output
109 | .nuxt
110 |
111 | # rollup.js default build output
112 | dist/
113 |
114 | # Uncomment the public line if your project uses Gatsby
115 | # https://nextjs.org/blog/next-9-1#public-directory-support
116 | # https://create-react-app.dev/docs/using-the-public-folder/#docsNav
117 | # public
118 |
119 | # Storybook build outputs
120 | .out
121 | .storybook-out
122 |
123 | # vuepress build output
124 | .vuepress/dist
125 |
126 | # Serverless directories
127 | .serverless/
128 |
129 | # FuseBox cache
130 | .fusebox/
131 |
132 | # DynamoDB Local files
133 | .dynamodb/
134 |
135 | # Temporary folders
136 | tmp/
137 | temp/
138 |
139 | # End of https://www.gitignore.io/api/node,macos
140 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## WebRtcTutorial
2 |
3 | [](https://hits.seeyoufarm.com)
4 |
5 |
6 | #### 관련 내용은 다음 링크에서 확인하실 수 있습니다.
7 | [바로가기](https://velog.io/@ehdrms2034/WebRTC-%EC%9B%B9%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EB%A1%9C-%ED%99%94%EC%83%81-%EC%B1%84%ED%8C%85%EC%9D%84-%EB%A7%8C%EB%93%A4-%EC%88%98-%EC%9E%88%EB%8B%A4%EA%B3%A0)
8 |
--------------------------------------------------------------------------------
/webrtc_local_communication/rtc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/webrtc_local_communication/rtc.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | let dataChannelSend = document.getElementById("dataChannelSend");
4 | let dataChannelReceive = document.getElementById("dataChannelReceive");
5 | let sendBtn = document.getElementById("send");
6 | let pcConstraint;
7 | let dataConstraint;
8 | let localConnection;
9 | let remoteConnection;
10 | let sendChannel;
11 | let receiveChannel;
12 |
13 | sendBtn.onclick = sendData;
14 |
15 | createConnection();
16 |
17 | function createConnection() {
18 | let servers = null;
19 | pcConstraint = null;
20 | dataConstraint = null;
21 |
22 | window.localConnection = localConnection = new RTCPeerConnection(
23 | servers,
24 | pcConstraint
25 | );
26 |
27 | sendChannel = localConnection.createDataChannel(
28 | "sendDataChannel",
29 | dataConstraint
30 | );
31 |
32 | localConnection.onicecandidate = iceCallback1;
33 | sendChannel.onopen = onSendChannelStateChange;
34 | sendChannel.onclose = onSendChannelStateChange;
35 |
36 | window.remoteConnection = remoteConnection
37 | = new RTCPeerConnection(servers,pcConstraint);
38 |
39 | remoteConnection.onicecandidate = iceCallback2;
40 | remoteConnection.ondatachannel = receiveChannelCallback;
41 |
42 | localConnection.createOffer().then(
43 | gotDescription1,
44 | onCreateSessionDescriptionError
45 | );
46 | }
47 |
48 | function iceCallback1(event) {
49 | console.log('local ice callback')
50 | if (event.candidate) {
51 | remoteConnection
52 | .addIceCandidate(event.candidate)
53 | .then(onAddIceCandidateSuccess, onAddIceCandidateError);
54 | }
55 | }
56 |
57 | function iceCallback2(event) {
58 | if (event.candidate) {
59 | localConnection
60 | .addIceCandidate(event.candidate)
61 | .then(onAddIceCandidateSuccess, onAddIceCandidateError);
62 | }
63 | }
64 |
65 | function onAddIceCandidateSuccess() {
66 | console.log("AddIce Success");
67 | }
68 |
69 | function onAddIceCandidateError(error) {
70 | console.error("AddIce error" + error.toString());
71 | }
72 |
73 | function onSendChannelStateChange() {
74 | var readyState = sendChannel.readyState;
75 | // /trace("Send channel state is: " + readyState);
76 | if (readyState === "open") {
77 | console.log('opened');
78 | } else {
79 | console.log('closed');
80 | }
81 | }
82 |
83 | function receiveChannelCallback(event){
84 | receiveChannel = event.channel;
85 | receiveChannel.onmessage = onReceiveMessageCallback;
86 | }
87 |
88 | function onReceiveMessageCallback(event){
89 | dataChannelReceive.value = event.data;
90 | }
91 |
92 | function gotDescription1(desc){
93 | console.log(desc);
94 | localConnection.setLocalDescription(desc);
95 | remoteConnection.setRemoteDescription(desc);
96 | remoteConnection.createAnswer().then(
97 | gotDescription2,
98 | onCreateSessionDescriptionError
99 | );
100 | }
101 |
102 | function gotDescription2(desc){
103 | remoteConnection.setLocalDescription(desc);
104 | localConnection.setRemoteDescription(desc);
105 | }
106 |
107 | function sendData(){
108 | let data = dataChannelSend.value;
109 | console.log('btn Data : ',data);
110 | sendChannel.send(data);
111 | }
112 |
113 |
114 | function onCreateSessionDescriptionError(error) {
115 | console.error('Failed to create session description: ' + error.toString());
116 | }
--------------------------------------------------------------------------------
/webrtc_server_client/index.js:
--------------------------------------------------------------------------------
1 | const http = require('http');
2 | const os = require('os');
3 | const socketIO = require('socket.io');
4 | const nodeStatic = require('node-static');
5 |
6 | let fileServer = new(nodeStatic.Server)();
7 | let app = http.createServer((req,res)=>{
8 | fileServer.serve(req,res);
9 | }).listen(8080);
10 |
11 | let io = socketIO.listen(app);
12 | io.sockets.on('connection',socket=>{
13 | function log() {
14 | let array = ['Message from server:'];
15 | array.push.apply(array,arguments);
16 | socket.emit('log',array);
17 | }
18 |
19 | socket.on('message',message=>{
20 | log('Client said : ' ,message);
21 | socket.broadcast.emit('message',message);
22 | });
23 |
24 | socket.on('create or join',room=>{
25 | let clientsInRoom = io.sockets.adapter.rooms[room];
26 | let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;
27 | log('Room ' + room + ' now has ' + numClients + ' client(s)');
28 |
29 | if(numClients === 0){
30 | console.log('create room!');
31 | socket.join(room);
32 | log('Client ID ' + socket.id + ' created room ' + room);
33 | socket.emit('created',room,socket.id);
34 | }
35 | else if(numClients===1){
36 | console.log('join room!');
37 | log('Client Id' + socket.id + 'joined room' + room);
38 | io.sockets.in(room).emit('join',room);
39 | socket.join(room);
40 | socket.emit('joined',room,socket.id);
41 | io.sockets.in(room).emit('ready');
42 | }else{
43 | socket.emit('full',room);
44 | }
45 | });
46 |
47 |
48 | });
49 |
--------------------------------------------------------------------------------
/webrtc_server_client/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webrtc5",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "after": {
17 | "version": "0.8.2",
18 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
19 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
20 | },
21 | "arraybuffer.slice": {
22 | "version": "0.0.7",
23 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
24 | "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
25 | },
26 | "async-limiter": {
27 | "version": "1.0.1",
28 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
29 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
30 | },
31 | "backo2": {
32 | "version": "1.0.2",
33 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
34 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
35 | },
36 | "base64-arraybuffer": {
37 | "version": "0.1.5",
38 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
39 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
40 | },
41 | "base64id": {
42 | "version": "2.0.0",
43 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
44 | "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
45 | },
46 | "better-assert": {
47 | "version": "1.0.2",
48 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
49 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
50 | "requires": {
51 | "callsite": "1.0.0"
52 | }
53 | },
54 | "blob": {
55 | "version": "0.0.5",
56 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
57 | "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
58 | },
59 | "callsite": {
60 | "version": "1.0.0",
61 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
62 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
63 | },
64 | "colors": {
65 | "version": "1.4.0",
66 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
67 | "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
68 | },
69 | "component-bind": {
70 | "version": "1.0.0",
71 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
72 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
73 | },
74 | "component-emitter": {
75 | "version": "1.2.1",
76 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
77 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
78 | },
79 | "component-inherit": {
80 | "version": "0.0.3",
81 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
82 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
83 | },
84 | "cookie": {
85 | "version": "0.3.1",
86 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
87 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
88 | },
89 | "debug": {
90 | "version": "4.1.1",
91 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
92 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
93 | "requires": {
94 | "ms": "^2.1.1"
95 | }
96 | },
97 | "engine.io": {
98 | "version": "3.4.1",
99 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.1.tgz",
100 | "integrity": "sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw==",
101 | "requires": {
102 | "accepts": "~1.3.4",
103 | "base64id": "2.0.0",
104 | "cookie": "0.3.1",
105 | "debug": "~4.1.0",
106 | "engine.io-parser": "~2.2.0",
107 | "ws": "^7.1.2"
108 | }
109 | },
110 | "engine.io-client": {
111 | "version": "3.4.1",
112 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.1.tgz",
113 | "integrity": "sha512-RJNmA+A9Js+8Aoq815xpGAsgWH1VoSYM//2VgIiu9lNOaHFfLpTjH4tOzktBpjIs5lvOfiNY1dwf+NuU6D38Mw==",
114 | "requires": {
115 | "component-emitter": "1.2.1",
116 | "component-inherit": "0.0.3",
117 | "debug": "~4.1.0",
118 | "engine.io-parser": "~2.2.0",
119 | "has-cors": "1.1.0",
120 | "indexof": "0.0.1",
121 | "parseqs": "0.0.5",
122 | "parseuri": "0.0.5",
123 | "ws": "~6.1.0",
124 | "xmlhttprequest-ssl": "~1.5.4",
125 | "yeast": "0.1.2"
126 | },
127 | "dependencies": {
128 | "ws": {
129 | "version": "6.1.4",
130 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
131 | "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
132 | "requires": {
133 | "async-limiter": "~1.0.0"
134 | }
135 | }
136 | }
137 | },
138 | "engine.io-parser": {
139 | "version": "2.2.0",
140 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
141 | "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
142 | "requires": {
143 | "after": "0.8.2",
144 | "arraybuffer.slice": "~0.0.7",
145 | "base64-arraybuffer": "0.1.5",
146 | "blob": "0.0.5",
147 | "has-binary2": "~1.0.2"
148 | }
149 | },
150 | "has-binary2": {
151 | "version": "1.0.3",
152 | "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
153 | "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
154 | "requires": {
155 | "isarray": "2.0.1"
156 | }
157 | },
158 | "has-cors": {
159 | "version": "1.1.0",
160 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
161 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
162 | },
163 | "indexof": {
164 | "version": "0.0.1",
165 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
166 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
167 | },
168 | "isarray": {
169 | "version": "2.0.1",
170 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
171 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
172 | },
173 | "mime": {
174 | "version": "1.6.0",
175 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
176 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
177 | },
178 | "mime-db": {
179 | "version": "1.43.0",
180 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
181 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
182 | },
183 | "mime-types": {
184 | "version": "2.1.26",
185 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
186 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
187 | "requires": {
188 | "mime-db": "1.43.0"
189 | }
190 | },
191 | "minimist": {
192 | "version": "0.0.10",
193 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
194 | "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
195 | },
196 | "ms": {
197 | "version": "2.1.2",
198 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
199 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
200 | },
201 | "negotiator": {
202 | "version": "0.6.2",
203 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
204 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
205 | },
206 | "node-static": {
207 | "version": "0.7.11",
208 | "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz",
209 | "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==",
210 | "requires": {
211 | "colors": ">=0.6.0",
212 | "mime": "^1.2.9",
213 | "optimist": ">=0.3.4"
214 | }
215 | },
216 | "object-component": {
217 | "version": "0.0.3",
218 | "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
219 | "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
220 | },
221 | "optimist": {
222 | "version": "0.6.1",
223 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
224 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
225 | "requires": {
226 | "minimist": "~0.0.1",
227 | "wordwrap": "~0.0.2"
228 | }
229 | },
230 | "parseqs": {
231 | "version": "0.0.5",
232 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
233 | "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
234 | "requires": {
235 | "better-assert": "~1.0.0"
236 | }
237 | },
238 | "parseuri": {
239 | "version": "0.0.5",
240 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
241 | "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
242 | "requires": {
243 | "better-assert": "~1.0.0"
244 | }
245 | },
246 | "socket.io": {
247 | "version": "2.3.0",
248 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
249 | "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
250 | "requires": {
251 | "debug": "~4.1.0",
252 | "engine.io": "~3.4.0",
253 | "has-binary2": "~1.0.2",
254 | "socket.io-adapter": "~1.1.0",
255 | "socket.io-client": "2.3.0",
256 | "socket.io-parser": "~3.4.0"
257 | }
258 | },
259 | "socket.io-adapter": {
260 | "version": "1.1.2",
261 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
262 | "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g=="
263 | },
264 | "socket.io-client": {
265 | "version": "2.3.0",
266 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
267 | "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
268 | "requires": {
269 | "backo2": "1.0.2",
270 | "base64-arraybuffer": "0.1.5",
271 | "component-bind": "1.0.0",
272 | "component-emitter": "1.2.1",
273 | "debug": "~4.1.0",
274 | "engine.io-client": "~3.4.0",
275 | "has-binary2": "~1.0.2",
276 | "has-cors": "1.1.0",
277 | "indexof": "0.0.1",
278 | "object-component": "0.0.3",
279 | "parseqs": "0.0.5",
280 | "parseuri": "0.0.5",
281 | "socket.io-parser": "~3.3.0",
282 | "to-array": "0.1.4"
283 | },
284 | "dependencies": {
285 | "ms": {
286 | "version": "2.0.0",
287 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
288 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
289 | },
290 | "socket.io-parser": {
291 | "version": "3.3.0",
292 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
293 | "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
294 | "requires": {
295 | "component-emitter": "1.2.1",
296 | "debug": "~3.1.0",
297 | "isarray": "2.0.1"
298 | },
299 | "dependencies": {
300 | "debug": {
301 | "version": "3.1.0",
302 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
303 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
304 | "requires": {
305 | "ms": "2.0.0"
306 | }
307 | }
308 | }
309 | }
310 | }
311 | },
312 | "socket.io-parser": {
313 | "version": "3.4.0",
314 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz",
315 | "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==",
316 | "requires": {
317 | "component-emitter": "1.2.1",
318 | "debug": "~4.1.0",
319 | "isarray": "2.0.1"
320 | }
321 | },
322 | "to-array": {
323 | "version": "0.1.4",
324 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
325 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
326 | },
327 | "wordwrap": {
328 | "version": "0.0.3",
329 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
330 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
331 | },
332 | "ws": {
333 | "version": "7.2.3",
334 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
335 | "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ=="
336 | },
337 | "xmlhttprequest-ssl": {
338 | "version": "1.5.5",
339 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
340 | "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
341 | },
342 | "yeast": {
343 | "version": "0.1.2",
344 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
345 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
346 | }
347 | }
348 | }
349 |
--------------------------------------------------------------------------------
/webrtc_server_client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webrtc5",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "rtc.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "dependencies": {
12 | "node-static": "^0.7.11",
13 | "socket.io": "^2.3.0",
14 | "socket.io-client": "^2.3.0"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/webrtc_server_client/rtc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | WebRtc tutorial
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/webrtc_server_client/rtc.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | let localVideo = document.getElementById("localVideo");
4 | let remoteVideo = document.getElementById("remoteVideo");
5 | let isInitiator = false;
6 | let isChannelReady = false;
7 | let isStarted = false;
8 | let localStream;
9 | let remoteStream;
10 | let pc;
11 |
12 | let pcConfig = {
13 | 'iceServers': [{
14 | 'urls': 'stun:stun.l.google.com:19302'
15 | }]
16 | }
17 |
18 | let room = 'foo';
19 |
20 | let socket = io.connect();
21 |
22 | if(room !==''){
23 | socket.emit('create or join',room);
24 | console.log('Attempted to create or join Room',room);
25 | }
26 |
27 | socket.on('created', (room,id)=>{
28 | console.log('Created room' + room+'socket ID : '+id);
29 | isInitiator= true;
30 | })
31 |
32 | socket.on('full', room=>{
33 | console.log('Room '+room+'is full');
34 | });
35 |
36 | socket.on('join',room=>{
37 | console.log('Another peer made a request to join room' + room);
38 | console.log('This peer is the initiator of room' + room + '!');
39 | isChannelReady = true;
40 | })
41 |
42 | socket.on('joined',room=>{
43 | console.log('joined : '+ room );
44 | isChannelReady= true;
45 | })
46 | socket.on('log', array=>{
47 | console.log.apply(console,array);
48 | });
49 |
50 | socket.on('message', (message)=>{
51 | console.log('Client received message :',message);
52 | if(message === 'got user media'){
53 | maybeStart();
54 | }else if(message.type === 'offer'){
55 | if(!isInitiator && !isStarted){
56 | maybeStart();
57 | }
58 | pc.setRemoteDescription(new RTCSessionDescription(message));
59 | doAnswer();
60 | }else if(message.type ==='answer' && isStarted){
61 | pc.setRemoteDescription(new RTCSessionDescription(message));
62 | }else if(message.type ==='candidate' &&isStarted){
63 | const candidate = new RTCIceCandidate({
64 | sdpMLineIndex : message.label,
65 | candidate:message.candidate
66 | });
67 |
68 | pc.addIceCandidate(candidate);
69 | }
70 | })
71 | function sendMessage(message){
72 | console.log('Client sending message: ',message);
73 | socket.emit('message',message);
74 | }
75 |
76 | navigator.mediaDevices
77 | .getUserMedia({
78 | video: true,
79 | audio: false,
80 | })
81 | .then(gotStream)
82 | .catch((error) => console.error(error));
83 |
84 | function gotStream(stream) {
85 | console.log("Adding local stream");
86 | localStream = stream;
87 | localVideo.srcObject = stream;
88 | sendMessage("got user media");
89 | if (isInitiator) {
90 | maybeStart();
91 | }
92 | }
93 |
94 | function createPeerConnection() {
95 | try {
96 | pc = new RTCPeerConnection(null);
97 | pc.onicecandidate = handleIceCandidate;
98 | pc.onaddstream = handleRemoteStreamAdded;
99 | console.log("Created RTCPeerConnection");
100 | } catch (e) {
101 | alert("connot create RTCPeerConnection object");
102 | return;
103 | }
104 | }
105 |
106 | function handleIceCandidate(event) {
107 | console.log("iceCandidateEvent", event);
108 | if (event.candidate) {
109 | sendMessage({
110 | type: "candidate",
111 | label: event.candidate.sdpMLineIndex,
112 | id: event.candidate.sdpMid,
113 | candidate: event.candidate.candidate,
114 | });
115 | } else {
116 | console.log("end of candidates");
117 | }
118 | }
119 |
120 | function handleCreateOfferError(event) {
121 | console.log("createOffer() error: ", event);
122 | }
123 |
124 | function handleRemoteStreamAdded(event) {
125 | console.log("remote stream added");
126 | remoteStream = event.stream;
127 | remoteVideo.srcObject = remoteStream;
128 | }
129 |
130 | function maybeStart() {
131 | console.log(">>MaybeStart() : ", isStarted, localStream, isChannelReady);
132 | if (!isStarted && typeof localStream !== "undefined" && isChannelReady) {
133 | console.log(">>>>> creating peer connection");
134 | createPeerConnection();
135 | pc.addStream(localStream);
136 | isStarted = true;
137 | console.log("isInitiator : ", isInitiator);
138 | if (isInitiator) {
139 | doCall();
140 | }
141 | }else{
142 | console.error('maybeStart not Started!');
143 | }
144 | }
145 |
146 | function doCall() {
147 | console.log("Sending offer to peer");
148 | pc.createOffer(setLocalAndSendMessage, handleCreateOfferError);
149 | }
150 |
151 | function doAnswer() {
152 | console.log("Sending answer to peer");
153 | pc.createAnswer().then(
154 | setLocalAndSendMessage,
155 | onCreateSessionDescriptionError
156 | );
157 | }
158 |
159 | function setLocalAndSendMessage(sessionDescription) {
160 | pc.setLocalDescription(sessionDescription);
161 | sendMessage(sessionDescription);
162 | }
163 |
164 | function onCreateSessionDescriptionError(error) {
165 | console.error("Falied to create session Description", error);
166 | }
167 |
--------------------------------------------------------------------------------