Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
students
bora-it
Commits
63618602
Commit
63618602
authored
Jul 27, 2021
by
이재연
Browse files
Merge remote-tracking branch 'origin/seoyeon2' into jaeyeoniiiiii
parents
e72932e2
3aa0a668
Changes
29
Show whitespace changes
Inline
Side-by-side
app.js
View file @
63618602
// express 설정 파일
// express 설정 파일
import
express
from
"
express
"
;
import
express
from
"
express
"
;
import
fs
from
"
fs
"
;
import
cors
from
"
cors
"
;
import
socketio
from
"
socket.io
"
;
import
http
from
"
http
"
;
import
wrtc
from
"
wrtc
"
;
import
cookieParser
from
"
cookie-parser
"
;
import
cookieParser
from
"
cookie-parser
"
;
import
mainRouter
from
"
./routes/index.js
"
;
import
mainRouter
from
"
./routes/index.js
"
;
const
app
=
express
();
const
app
=
express
();
app
.
use
(
cors
());
const
server
=
http
.
createServer
(
app
);
app
.
use
(
express
.
json
());
app
.
use
(
express
.
json
());
// app.use('/uploads', express.static('uploads'))
app
.
use
(
express
.
urlencoded
({
extended
:
true
}));
app
.
use
(
express
.
urlencoded
({
extended
:
true
}));
app
.
use
(
cookieParser
());
app
.
use
(
cookieParser
());
app
.
use
(
"
/api
"
,
mainRouter
);
app
.
use
(
"
/api
"
,
mainRouter
);
export
default
app
;
let
receiverPCs
=
{};
let
senderPCs
=
{};
let
users
=
{};
let
socketToRoom
=
{};
const
pc_config
=
{
iceServers
:
[
// {
// urls: 'stun:[STUN_IP]:[PORT]',
// 'credentials': '[YOR CREDENTIALS]',
// 'username': '[USERNAME]'
// },
{
urls
:
"
stun:stun.l.google.com:19302
"
,
},
],
};
const
isIncluded
=
(
array
,
id
)
=>
{
let
len
=
array
.
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
if
(
array
[
i
].
id
===
id
)
return
true
;
}
return
false
;
};
const
createReceiverPeerConnection
=
(
socketID
,
socket
,
roomID
)
=>
{
let
pc
=
new
wrtc
.
RTCPeerConnection
(
pc_config
);
if
(
receiverPCs
[
socketID
])
receiverPCs
[
socketID
]
=
pc
;
else
receiverPCs
=
{
...
receiverPCs
,
[
socketID
]:
pc
};
pc
.
onicecandidate
=
(
e
)
=>
{
//console.log(`socketID: ${socketID}'s receiverPeerConnection icecandidate`);
socket
.
to
(
socketID
).
emit
(
"
getSenderCandidate
"
,
{
candidate
:
e
.
candidate
,
});
};
pc
.
oniceconnectionstatechange
=
(
e
)
=>
{
//console.log(e);
};
pc
.
ontrack
=
(
e
)
=>
{
if
(
users
[
roomID
])
{
if
(
!
isIncluded
(
users
[
roomID
],
socketID
))
{
users
[
roomID
].
push
({
id
:
socketID
,
stream
:
e
.
streams
[
0
],
});
}
else
return
;
}
else
{
users
[
roomID
]
=
[
{
id
:
socketID
,
stream
:
e
.
streams
[
0
],
},
];
}
socket
.
broadcast
.
to
(
roomID
).
emit
(
"
userEnter
"
,
{
id
:
socketID
});
};
return
pc
;
};
const
createSenderPeerConnection
=
(
receiverSocketID
,
senderSocketID
,
socket
,
roomID
)
=>
{
let
pc
=
new
wrtc
.
RTCPeerConnection
(
pc_config
);
if
(
senderPCs
[
senderSocketID
])
{
senderPCs
[
senderSocketID
].
filter
((
user
)
=>
user
.
id
!==
receiverSocketID
);
senderPCs
[
senderSocketID
].
push
({
id
:
receiverSocketID
,
pc
:
pc
});
}
else
senderPCs
=
{
...
senderPCs
,
[
senderSocketID
]:
[{
id
:
receiverSocketID
,
pc
:
pc
}],
};
pc
.
onicecandidate
=
(
e
)
=>
{
//console.log(`socketID: ${receiverSocketID}'s senderPeerConnection icecandidate`);
socket
.
to
(
receiverSocketID
).
emit
(
"
getReceiverCandidate
"
,
{
id
:
senderSocketID
,
candidate
:
e
.
candidate
,
});
};
pc
.
oniceconnectionstatechange
=
(
e
)
=>
{
//console.log(e);
};
const
sendUser
=
users
[
roomID
].
filter
((
user
)
=>
user
.
id
===
senderSocketID
);
sendUser
[
0
].
stream
.
getTracks
().
forEach
((
track
)
=>
{
pc
.
addTrack
(
track
,
sendUser
[
0
].
stream
);
});
return
pc
;
};
const
getOtherUsersInRoom
=
(
socketID
,
roomID
)
=>
{
let
allUsers
=
[];
if
(
!
users
[
roomID
])
return
allUsers
;
let
len
=
users
[
roomID
].
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
if
(
users
[
roomID
][
i
].
id
===
socketID
)
continue
;
allUsers
.
push
({
id
:
users
[
roomID
][
i
].
id
});
}
return
allUsers
;
};
const
deleteUser
=
(
socketID
,
roomID
)
=>
{
let
roomUsers
=
users
[
roomID
];
if
(
!
roomUsers
)
return
;
roomUsers
=
roomUsers
.
filter
((
user
)
=>
user
.
id
!==
socketID
);
users
[
roomID
]
=
roomUsers
;
if
(
roomUsers
.
length
===
0
)
{
delete
users
[
roomID
];
}
delete
socketToRoom
[
socketID
];
};
const
closeRecevierPC
=
(
socketID
)
=>
{
if
(
!
receiverPCs
[
socketID
])
return
;
receiverPCs
[
socketID
].
close
();
delete
receiverPCs
[
socketID
];
};
const
closeSenderPCs
=
(
socketID
)
=>
{
if
(
!
senderPCs
[
socketID
])
return
;
let
len
=
senderPCs
[
socketID
].
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
senderPCs
[
socketID
][
i
].
pc
.
close
();
let
_senderPCs
=
senderPCs
[
senderPCs
[
socketID
][
i
].
id
];
let
senderPC
=
_senderPCs
.
filter
((
sPC
)
=>
sPC
.
id
===
socketID
);
if
(
senderPC
[
0
])
{
senderPC
[
0
].
pc
.
close
();
senderPCs
[
senderPCs
[
socketID
][
i
].
id
]
=
_senderPCs
.
filter
(
(
sPC
)
=>
sPC
.
id
!==
socketID
);
}
}
delete
senderPCs
[
socketID
];
};
const
io
=
socketio
.
listen
(
server
);
io
.
sockets
.
on
(
"
connection
"
,
(
socket
)
=>
{
console
.
log
(
"
socket connection complete
"
)
socket
.
on
(
"
joinRoom
"
,
(
data
)
=>
{
try
{
let
allUsers
=
getOtherUsersInRoom
(
data
.
id
,
data
.
roomID
);
io
.
to
(
data
.
id
).
emit
(
"
allUsers
"
,
{
users
:
allUsers
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
socket
.
on
(
"
senderOffer
"
,
async
(
data
)
=>
{
try
{
socketToRoom
[
data
.
senderSocketID
]
=
data
.
roomID
;
let
pc
=
createReceiverPeerConnection
(
data
.
senderSocketID
,
socket
,
data
.
roomID
);
await
pc
.
setRemoteDescription
(
data
.
sdp
);
let
sdp
=
await
pc
.
createAnswer
({
offerToReceiveAudio
:
true
,
offerToReceiveVideo
:
true
,
});
await
pc
.
setLocalDescription
(
sdp
);
socket
.
join
(
data
.
roomID
);
io
.
to
(
data
.
senderSocketID
).
emit
(
"
getSenderAnswer
"
,
{
sdp
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
socket
.
on
(
"
senderCandidate
"
,
async
(
data
)
=>
{
try
{
let
pc
=
receiverPCs
[
data
.
senderSocketID
];
await
pc
.
addIceCandidate
(
new
wrtc
.
RTCIceCandidate
(
data
.
candidate
));
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
socket
.
on
(
"
receiverOffer
"
,
async
(
data
)
=>
{
try
{
let
pc
=
createSenderPeerConnection
(
data
.
receiverSocketID
,
data
.
senderSocketID
,
socket
,
data
.
roomID
);
await
pc
.
setRemoteDescription
(
data
.
sdp
);
let
sdp
=
await
pc
.
createAnswer
({
offerToReceiveAudio
:
false
,
offerToReceiveVideo
:
false
,
});
await
pc
.
setLocalDescription
(
sdp
);
io
.
to
(
data
.
receiverSocketID
).
emit
(
"
getReceiverAnswer
"
,
{
id
:
data
.
senderSocketID
,
sdp
,
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
socket
.
on
(
"
receiverCandidate
"
,
async
(
data
)
=>
{
try
{
const
senderPC
=
senderPCs
[
data
.
senderSocketID
].
filter
(
(
sPC
)
=>
sPC
.
id
===
data
.
receiverSocketID
);
await
senderPC
[
0
].
pc
.
addIceCandidate
(
new
wrtc
.
RTCIceCandidate
(
data
.
candidate
)
);
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
socket
.
on
(
"
disconnect
"
,
()
=>
{
try
{
let
roomID
=
socketToRoom
[
socket
.
id
];
deleteUser
(
socket
.
id
,
roomID
);
closeRecevierPC
(
socket
.
id
);
closeSenderPCs
(
socket
.
id
);
socket
.
broadcast
.
to
(
roomID
).
emit
(
"
userExit
"
,
{
id
:
socket
.
id
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
});
export
default
server
;
client/package.json
View file @
63618602
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
"@testing-library/user-event"
:
"^12.1.10"
,
"@testing-library/user-event"
:
"^12.1.10"
,
"axios"
:
"^0.21.1"
,
"axios"
:
"^0.21.1"
,
"bootstrap"
:
"^5.0.2"
,
"bootstrap"
:
"^5.0.2"
,
"nanoid"
:
"^3.1.23"
,
"node-sass"
:
"^6.0.1"
,
"node-sass"
:
"^6.0.1"
,
"react"
:
"^17.0.2"
,
"react"
:
"^17.0.2"
,
"react-dom"
:
"^17.0.2"
,
"react-dom"
:
"^17.0.2"
,
...
@@ -23,6 +24,9 @@
...
@@ -23,6 +24,9 @@
"test"
:
"react-scripts test"
,
"test"
:
"react-scripts test"
,
"eject"
:
"react-scripts eject"
"eject"
:
"react-scripts eject"
},
},
"nodemonConfig"
:{
"ignore"
:[
"test/*"
,
"docs/*"
,
"client/*"
]
},
"eslintConfig"
:
{
"eslintConfig"
:
{
"extends"
:
[
"extends"
:
[
"react-app"
,
"react-app"
,
...
...
client/src/apis/room.api.js
View file @
63618602
import
axios
from
"
axios
"
;
import
axios
from
"
axios
"
;
const
login
=
async
(
payload
)
=>
{
const
create
=
async
(
payload
)
=>
{
const
{
data
}
=
await
axios
.
post
(
"
/api/
login
"
,
payload
);
const
{
data
}
=
await
axios
.
post
(
"
/api/
room/create
"
,
payload
);
return
data
;
return
data
;
};
};
const
signup
=
async
(
payload
)
=>
{
const
join
=
async
(
payload
)
=>
{
const
{
data
}
=
await
axios
.
p
os
t
(
"
/api/
signup
"
,
payload
);
const
{
data
}
=
await
axios
.
p
u
t
(
"
/api/
room/join
"
,
payload
);
return
data
;
return
data
;
};
};
const
roomApi
=
{
login
,
signup
};
const
roomApi
=
{
create
,
join
};
export
default
roomApi
;
export
default
roomApi
;
client/src/apis/user.api.js
View file @
63618602
import
axios
from
"
axios
"
;
import
axios
from
"
axios
"
;
const
getUser
=
async
(
payload
)
=>
{
const
{
data
}
=
await
axios
.
post
(
"
/api/getUser
"
,
payload
);
return
data
;
};
const
login
=
async
(
payload
)
=>
{
const
login
=
async
(
payload
)
=>
{
const
{
data
}
=
await
axios
.
post
(
"
/api/login
"
,
payload
);
const
{
data
}
=
await
axios
.
post
(
"
/api/login
"
,
payload
);
return
data
;
return
data
;
...
...
client/src/components/Header.js
View file @
63618602
import
{
Link
}
from
'
react-router-dom
'
import
{
Link
}
from
'
react-router-dom
'
import
{
handleLogout
}
from
'
../context/auth
'
const
Header
=
()
=>
{
const
Header
=
()
=>
{
return
(
return
(
<
div
>
<
div
>
...
@@ -6,11 +8,71 @@ const Header = () => {
...
@@ -6,11 +8,71 @@ const Header = () => {
style
=
{{
backgroundColor
:
'
#FCF4FF
'
}}
style
=
{{
backgroundColor
:
'
#FCF4FF
'
}}
className
=
"
flex-column align-items-center justify-content-center p-2
"
className
=
"
flex-column align-items-center justify-content-center p-2
"
>
>
<
div
className
=
"
d-flex justify-content-center
"
>
<
div
className
=
"
d-flex justify-content-end
"
>
<
Link
to
=
"
/
"
>
<
div
>
<
Link
to
=
"
/user
"
>
<
img
src
=
"
/BORA.png
"
style
=
{{
width
:
'
160px
'
}}
/
>
<
img
src
=
"
/BORA.png
"
style
=
{{
width
:
'
160px
'
}}
/
>
<
/Link
>
<
/Link
>
<
/div
>
<
/div
>
<
button
type
=
"
button
"
className
=
"
mt-3 ms-5 rounded
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
target
=
"
#logout
"
style
=
{{
height
:
'
30px
'
,
backgroundColor
:
'
#E0CEE8
'
,
color
:
'
black
'
,
border
:
'
1px #E0CEE8
'
,
}}
>
로그아웃
<
/button
>
<
div
className
=
"
modal fade
"
id
=
"
logout
"
tabIndex
=
"
-1
"
aria
-
labelledby
=
"
logoutLabel
"
aria
-
hidden
=
"
true
"
>
<
div
className
=
"
modal-dialog
"
>
<
div
className
=
"
modal-content
"
>
<
div
className
=
"
modal-header
"
>
<
button
type
=
"
button
"
className
=
"
btn-close
"
data
-
bs
-
dismiss
=
"
modal
"
aria
-
label
=
"
Close
"
><
/button
>
<
/div
>
<
div
className
=
"
modal-body d-flex justify-content-center
"
>
로그아웃
하시겠습니까
?
<
/div
>
<
div
className
=
"
row mb-3
"
>
<
div
className
=
"
d-flex justify-content-evenly
"
>
<
Link
to
=
"
/
"
className
=
"
col-2 p-1 btn btn-primary
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
onClick
=
{()
=>
handleLogout
()}
data
-
bs
-
dismiss
=
"
modal
"
>
예
<
/button
>
<
/Link
>
<
button
type
=
"
submit
"
className
=
"
col-2 p-1 btn btn-primary
"
data
-
bs
-
dismiss
=
"
modal
"
>
아니요
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/form
>
<
/form
>
<
div
<
div
style
=
{{
backgroundColor
:
'
#262626
'
,
width
:
'
auto
'
,
height
:
'
2px
'
}}
style
=
{{
backgroundColor
:
'
#262626
'
,
width
:
'
auto
'
,
height
:
'
2px
'
}}
...
...
client/src/components/Home/AddRoom.js
View file @
63618602
import
{
useEffect
,
useState
}
from
"
react
"
;
import
CreateRoom
from
"
./CreateRoom
"
;
import
axios
from
'
axios
'
import
JoinRoom
from
"
./JoinRoom
"
;
const
INIT_ROOM
=
{
roomName
:
''
,
owner
:
'
123456
'
,
member
:
'
123456
'
,
profileimg
:
[],
}
const
AddRoom
=
()
=>
{
const
AddRoom
=
()
=>
{
const
[
room
,
setRoom
]
=
useState
(
INIT_ROOM
)
const
[
error
,
setError
]
=
useState
(
""
);
const
[
success
,
setSuccess
]
=
useState
(
false
)
const
[
disabled
,
setDisabled
]
=
useState
(
true
)
useEffect
(()
=>
{
setDisabled
(
!
(
room
.
name
&&
room
.
owner
&&
room
.
member
&&
room
.
profileimg
)
);
},
[
room
]);
//LocalStorage에 user id를 저장할때 id를 owner, member에 저장하기
//const userId = localStorage.getItem('id')
// setRoom({...room, [owner]: userId})
// setRoom({...room, [member]: userId})
function
handleChange
(
event
)
{
const
{
name
,
value
}
=
event
.
target
setRoom
({
...
room
,
[
name
]:
value
})
console
.
log
(
room
)
}
async
function
handleSubmit
(
event
)
{
event
.
preventDefault
()
try
{
console
.
log
(
'
룸룸
'
,
room
)
let
res
=
await
axios
.
post
(
"
/room/create
"
,
room
)
const
Id
=
res
.
data
.
id
alert
(
`방참여코드는
${
Id
}
입니다`
)
setSuccess
(
true
)
}
catch
(
error
)
{
// catchErrors(error, setError);
}
finally
{
// setLoading(false);
}
}
if
(
success
)
{
console
.
log
(
'
success
'
,
success
)
alert
(
'
룸생성이 완료되었습니다!
'
)
//return <Redirect to='/' />
}
const
{
name
,
owner
,
member
,
profileimg
}
=
room
;
return
(
return
(
<
div
>
<
div
>
<
div
className
=
"
mx-4 my-3 d-flex justify-content-between
"
>
<
div
className
=
"
mx-4 my-3 d-flex justify-content-between
"
>
...
@@ -102,6 +45,7 @@ const AddRoom = () => {
...
@@ -102,6 +45,7 @@ const AddRoom = () => {
className
=
"
p-3
"
className
=
"
p-3
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
target
=
"
#joinModal
"
data
-
bs
-
target
=
"
#joinModal
"
// data-bs-dismiss="modal"
style
=
{{
style
=
{{
display
:
"
flex
"
,
display
:
"
flex
"
,
flexDirection
:
"
column
"
,
flexDirection
:
"
column
"
,
...
@@ -110,11 +54,19 @@ const AddRoom = () => {
...
@@ -110,11 +54,19 @@ const AddRoom = () => {
backgroundColor
:
"
#E0CEE8
"
,
backgroundColor
:
"
#E0CEE8
"
,
borderColor
:
"
#E0CEE8
"
,
borderColor
:
"
#E0CEE8
"
,
}}
}}
>
방참여하기
<
/button
>
<
div
className
=
"
modal fade
"
id
=
"
joinModal
"
tabIndex
=
"
-1
"
aria
-
labelledby
=
"
joinModalLabel
"
aria
-
hidden
=
"
true
"
>
>
<
div
style
=
{{
width
:
"
6rem
"
}}
>
<
div
className
=
"
modal-dialog
"
>
방참여하기
<
JoinRoom
/>
<
/div
>
<
/div
>
<
/div
>
<
/button
>
<
/div
>
<
/div
>
<
div
className
=
"
col-6 d-flex justify-content-center
"
>
<
div
className
=
"
col-6 d-flex justify-content-center
"
>
<
button
<
button
...
@@ -122,6 +74,7 @@ const AddRoom = () => {
...
@@ -122,6 +74,7 @@ const AddRoom = () => {
className
=
"
p-3
"
className
=
"
p-3
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
toggle
=
"
modal
"
data
-
bs
-
target
=
"
#makeModal
"
data
-
bs
-
target
=
"
#makeModal
"
// data-bs-dismiss="modal"
style
=
{{
style
=
{{
display
:
"
flex
"
,
display
:
"
flex
"
,
flexDirection
:
"
column
"
,
flexDirection
:
"
column
"
,
...
@@ -130,95 +83,19 @@ const AddRoom = () => {
...
@@ -130,95 +83,19 @@ const AddRoom = () => {
backgroundColor
:
"
#f5cfe3
"
,
backgroundColor
:
"
#f5cfe3
"
,
borderColor
:
"
#f5cfe3
"
,
borderColor
:
"
#f5cfe3
"
,
}}
}}
>
>
방생성하기
<
div
style
=
{{
width
:
"
6rem
"
}}
>
방생성하기
<
/div
>
<
/button
>
<
/button
>
<
/div
>
<
div
<
/div
>
className
=
"
modal fade
"
<
/div
>
id
=
"
makeModal
"
<
/div
>
tabIndex
=
"
-1
"
<
/div
>
aria
-
labelledby
=
"
makeModalLabel
"
<
/div
>
aria
-
hidden
=
"
true
"
>
{
/* 방참여하기 모달 */
}
<
div
className
=
"
form
"
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"
modal
"
id
=
"
joinModal
"
tabIndex
=
"
-1
"
aria
-
hidden
=
"
true
"
>
<
div
className
=
"
modal-dialog
"
>
<
div
className
=
"
modal-content
"
>
<
div
className
=
"
modal-header
"
>
<
div
>
방참여하기
<
/div
>
<
button
type
=
"
button
"
className
=
"
btn-close
"
data
-
bs
-
dismiss
=
"
modal
"
aria
-
label
=
"
Close
"
><
/button
>
<
/div
>
<
div
className
=
"
modal-body
"
>
<
div
className
=
"
input-group mb-3
"
>
<
input
type
=
"
text
"
className
=
"
form-control
"
placeholder
=
"
참여코드를 입력하세요
"
aria
-
label
=
"
참여코드를 입력하세요
"
aria
-
describedby
=
"
basic-addon1
"
/>
<
/div
>
<
div
className
=
"
modal-footer
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
>
확인
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
{
/* 방생성하기 모달 */
}
<
div
className
=
"
form
"
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"
modal
"
id
=
"
makeModal
"
tabIndex
=
"
-1
"
aria
-
hidden
=
"
true
"
>
<
div
className
=
"
modal-dialog
"
>
<
div
className
=
"
modal-dialog
"
>
<
div
className
=
"
modal-content
"
>
<
CreateRoom
/>
<
div
className
=
"
modal-header
"
>
<
div
>
방생성하기
<
/div
>
<
button
type
=
"
button
"
className
=
"
btn-close
"
data
-
bs
-
dismiss
=
"
modal
"
aria
-
label
=
"
Close
"
><
/button
>
<
/div
>
<
/div
>
<
div
className
=
"
modal-body
"
>
<
h6
>
방프로필사진
<
/h6
>
<
div
className
=
"
mb-4
"
>
<
input
type
=
"
file
"
className
=
"
upload-hidden
"
onChange
=
{
handleChange
}
name
=
"
profileimg
"
value
=
{
room
.
profileimg
}
/
>
<
/div
>
<
h6
>
방이름
<
/h6
>
<
div
className
=
"
input-group
"
>
<
input
type
=
"
text
"
className
=
"
form-control
"
placeholder
=
"
방이름을 입력해주세요
"
aria
-
label
=
"
방이름 입력해주세요
"
aria
-
describedby
=
"
basic-addon1
"
onChange
=
{
handleChange
}
name
=
"
name
"
value
=
{
room
.
name
}
/
>
<
/div
>
<
/div
>
<
div
className
=
"
modal-footer
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
>
생성
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
...
client/src/components/Home/CreateRoom.js
0 → 100644
View file @
63618602
import
{
useEffect
,
useState
}
from
"
react
"
;
import
{
Redirect
}
from
"
react-router-dom
"
;
import
roomApi
from
"
../../apis/room.api
"
;
const
userId
=
localStorage
.
getItem
(
'
user
'
);
console
.
log
(
userId
)
const
INIT_ROOM
=
{
name
:
''
,
owner
:
userId
,
member
:
userId
,
profileimg
:
''
,
}
const
CreateRoom
=
()
=>
{
const
[
room
,
setRoom
]
=
useState
(
INIT_ROOM
)
const
[
error
,
setError
]
=
useState
(
""
);
const
[
success
,
setSuccess
]
=
useState
(
false
)
const
[
disabled
,
setDisabled
]
=
useState
(
true
)
useEffect
(()
=>
{
const
isRoom
=
Object
.
values
(
roomApi
).
every
((
el
)
=>
Boolean
(
el
));
isRoom
?
setDisabled
(
false
)
:
setDisabled
(
true
);
},
[
room
]);
function
handleChange
(
event
)
{
console
.
log
(
room
)
const
{
name
,
value
}
=
event
.
target
setRoom
({
...
room
,
[
name
]:
value
})
}
console
.
log
(
room
)
async
function
handleSubmit
(
e
)
{
e
.
preventDefault
()
console
.
log
(
'
룸룸
'
,
room
)
try
{
const
res
=
await
roomApi
.
create
(
room
)
// console.log(res)
const
Id
=
res
.
id
console
.
log
(
Id
)
alert
(
`방참여코드는
${
Id
}
입니다`
)
setSuccess
(
true
)
}
catch
(
error
)
{
// catchErrors(error, setError);
}
finally
{
// setLoading(false);
}
}
if
(
success
)
{
console
.
log
(
'
success
'
,
success
)
alert
(
'
룸생성이 완료되었습니다!
'
)
return
<
Redirect
to
=
'
/user
'
/>
}
const
{
name
,
owner
,
member
,
profileimg
}
=
room
;
return
(
<
div
className
=
"
modal-content
"
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"
modal-header
"
>
<
div
className
=
"
modal-title
"
id
=
"
makeModal
"
>
방생성하기
<
/div
>
<
button
type
=
"
button
"
className
=
"
btn-close
"
data
-
bs
-
dismiss
=
"
modal
"
aria
-
label
=
"
Close
"
><
/button
>
<
/div
>
<
div
className
=
"
modal-body
"
>
<
h6
>
방프로필사진
<
/h6
>
<
div
className
=
"
mb-4
"
>
<
input
type
=
"
file
"
className
=
"
upload-hidden
"
onChange
=
{
handleChange
}
accept
=
"
image/*
"
name
=
"
profileimg
"
value
=
{
room
.
profileimg
}
/
>
<
/div
>
<
h6
>
방이름
<
/h6
>
<
div
className
=
"
input-group
"
>
<
input
type
=
"
text
"
className
=
"
form-control
"
placeholder
=
"
방이름을 입력해주세요
"
aria
-
label
=
"
방이름 입력해주세요
"
aria
-
describedby
=
"
basic-addon1
"
onChange
=
{
handleChange
}
name
=
"
name
"
value
=
{
room
.
name
}
/
>
<
/div
>
<
div
className
=
"
modal-footer
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
>
생성
<
/button
>
<
/div
>
<
/div
>
<
/form
>
<
/div
>
);
};
export
default
CreateRoom
;
\ No newline at end of file
client/src/components/Home/HomeProfile.js
View file @
63618602
import
{
Link
}
from
"
react-router-dom
"
;
import
{
Link
}
from
"
react-router-dom
"
;
import
{
useState
,
useEffect
}
from
"
react
"
;
import
userApi
from
"
../../apis/user.api
"
;
const
userprofile
=
localStorage
.
getItem
(
"
user
"
);
console
.
log
(
userprofile
)
const
INIT_USER
=
{
id
:
userprofile
,
name
:
''
,
img
:
''
,
}
const
HomeProfile
=
()
=>
{
const
HomeProfile
=
()
=>
{
const
id
=
1
;
const
[
user
,
setUser
]
=
useState
(
INIT_USER
)
async
function
getSetUser
(
userID
)
{
try
{
// `/users/${userId}`랑 userId랑 같은지 확인
console
.
log
(
'
userID
'
,
userID
)
const
data
=
await
userApi
.
getUser
({
id
:
userID
})
console
.
log
(
data
)
setUser
(
data
)
console
.
log
(
user
)
}
catch
(
error
)
{
// catchErrors(error, setError)
}
}
useEffect
(()
=>
{
console
.
log
(
'
예에에에에ㅔ에에
'
)
getSetUser
(
userprofile
)
},
[
userprofile
])
return
(
return
(
<
Link
to
=
{
`/profile/
${
id
}
`
}
className
=
"
text-decoration-none text-dark
"
>
<
Link
to
=
{
`/profile/
${
user
}
`
}
className
=
"
text-decoration-none text-dark
"
>
<
form
className
=
"
flex-column align-items-center justify-content-center m-2
"
>
<
form
className
=
"
flex-column align-items-center justify-content-center m-2
"
>
<
div
className
=
"
d-flex justify-content-center
"
>
<
div
className
=
"
d-flex justify-content-center
"
>
<
img
<
img
src
=
"
cherry.jpg
"
//
src="cherry.jpg"
className
=
"
rounded-circle
"
className
=
"
rounded-circle
"
style
=
{{
style
=
{{
width
:
"
157px
"
,
width
:
"
157px
"
,
height
:
"
157px
"
,
height
:
"
157px
"
,
}}
}}
value
=
{
user
.
img
}
/
>
/
>
<
/div
>
<
/div
>
<
h1
className
=
"
d-flex justify-content-center
"
>
CHERRY
<
/h1
>
<
h1
className
=
"
d-flex justify-content-center
"
>
{
user
.
name
}
<
/h1
>
<
h2
className
=
"
d-flex justify-content-center
"
>
#
0805
<
/h2
>
<
h2
className
=
"
d-flex justify-content-center
"
>
#
{
user
.
id
}
<
/h2
>
<
/form
>
<
/form
>
<
div
<
div
style
=
{{
backgroundColor
:
"
#262626
"
,
width
:
"
auto
"
,
height
:
"
2px
"
}}
style
=
{{
backgroundColor
:
"
#262626
"
,
width
:
"
auto
"
,
height
:
"
2px
"
}}
...
...
client/src/components/Home/JoinRoom.js
0 → 100644
View file @
63618602
import
{
useEffect
,
useState
}
from
"
react
"
;
import
{
Redirect
}
from
"
react-router-dom
"
;
import
roomApi
from
"
../../apis/room.api
"
;
const
userId
=
localStorage
.
getItem
(
'
user
'
);
const
JoinRoom
=
()
=>
{
const
[
roomId
,
setRoomId
]
=
useState
(
''
);
const
[
disabled
,
setDisabled
]
=
useState
(
true
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
useEffect
(()
=>
{
const
isRoom
=
Object
.
values
(
roomApi
).
every
((
el
)
=>
Boolean
(
el
));
isRoom
?
setDisabled
(
false
)
:
setDisabled
(
true
);
},
[
roomId
]);
function
handleChange
(
event
)
{
const
{
value
}
=
event
.
target
;
setRoomId
(
value
);
console
.
log
(
roomId
);
}
async
function
handleSubmit
(
e
)
{
e
.
preventDefault
();
try
{
// setLoading(true);
// setError("");
console
.
log
(
'
userId:
'
,
userId
)
console
.
log
(
'
roomId:
'
,
roomId
)
const
data
=
await
roomApi
.
join
({
userId
:
userId
,
roomId
:
roomId
});
console
.
log
(
data
);
setSuccess
(
true
);
}
catch
(
error
)
{
// catchErrors(error, setError);
}
finally
{
// setLoading(false);
}
}
if
(
success
)
{
return
<
Redirect
to
=
"
/user
"
/>
;
}
return
(
<
div
className
=
"
modal-content
"
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"
modal-header
"
>
<
div
className
=
"
modal-title
"
id
=
"
joinModal
"
>
방참여하기
<
/div
>
<
button
type
=
"
button
"
className
=
"
btn-close
"
data
-
bs
-
dismiss
=
"
modal
"
aria
-
label
=
"
Close
"
><
/button
>
<
/div
>
<
div
className
=
"
modal-body
"
>
<
div
className
=
"
input-group mb-3
"
>
<
input
type
=
"
text
"
className
=
"
form-control
"
placeholder
=
"
참여코드를 입력하세요
"
aria
-
label
=
"
참여코드를 입력하세요
"
aria
-
describedby
=
"
basic-addon1
"
name
=
"
roomId
"
value
=
{
roomId
}
onChange
=
{
handleChange
}
/
>
<
/div
>
<
div
className
=
"
modal-footer
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
>
확인
<
/button
>
<
/div
>
<
/div
>
<
/form
>
<
/div
>
);
};
export
default
JoinRoom
;
\ No newline at end of file
client/src/components/Login.js
View file @
63618602
import
{
useEffect
,
useState
}
from
"
react
"
;
import
{
useEffect
,
useState
}
from
'
react
'
import
{
Redirect
}
from
"
react-router-dom
"
;
import
{
Redirect
}
from
'
react-router-dom
'
import
userApi
from
"
../apis/user.api
"
;
import
userApi
from
'
../apis/user.api
'
import
catchErrors
from
"
../context/catchError
"
;
import
{
handleLogin
}
from
'
../context/auth
'
;
const
INIT_USER
=
{
const
INIT_USER
=
{
email
:
""
,
email
:
''
,
password
:
""
,
password
:
''
,
}
;
}
const
Login
=
()
=>
{
const
Login
=
()
=>
{
//
const {
error,
loading, login } = useAuth()
;
// const { loading, login
, catchErrorAuth
} = useAuth()
const
[
user
,
setUser
]
=
useState
(
INIT_USER
)
;
const
[
user
,
setUser
]
=
useState
(
INIT_USER
)
const
[
disabled
,
setDisabled
]
=
useState
(
true
)
;
const
[
disabled
,
setDisabled
]
=
useState
(
true
)
const
[
error
,
setError
]
=
useState
(
""
);
const
[
error
,
setError
]
=
useState
(
''
)
const
[
success
,
setSuccess
]
=
useState
(
false
)
;
const
[
success
,
setSuccess
]
=
useState
(
false
)
useEffect
(()
=>
{
useEffect
(()
=>
{
const
isUser
=
Object
.
values
(
user
).
every
((
el
)
=>
Boolean
(
el
))
;
const
isUser
=
Object
.
values
(
user
).
every
((
el
)
=>
Boolean
(
el
))
isUser
?
setDisabled
(
false
)
:
setDisabled
(
true
)
;
isUser
?
setDisabled
(
false
)
:
setDisabled
(
true
)
},
[
user
])
;
},
[
user
])
function
handleChange
(
event
)
{
function
handleChange
(
event
)
{
const
{
name
,
value
}
=
event
.
target
;
const
{
name
,
value
}
=
event
.
target
setUser
({
...
user
,
[
name
]:
value
})
;
setUser
({
...
user
,
[
name
]:
value
})
}
}
async
function
handleSubmit
(
e
)
{
async
function
handleSubmit
(
e
)
{
e
.
preventDefault
();
e
.
preventDefault
()
console
.
log
(
'
로그인
'
)
try
{
try
{
// setLoading(true);
// setLoading(true);
// setError("");
// setError("");
const
data
=
await
userApi
.
login
(
user
);
const
data
=
await
userApi
.
login
(
user
)
console
.
log
(
data
);
console
.
log
(
data
)
setSuccess
(
true
);
handleLogin
(
data
.
id
)
setSuccess
(
true
)
}
catch
(
error
)
{
}
catch
(
error
)
{
// catchErrors(error, setError);
console
.
log
(
'
error in login
'
,
error
)
catchErrors
(
error
,
setError
)
}
finally
{
}
finally
{
// setLoading(false);
// setLoading(false);
}
}
}
}
if
(
success
)
{
return
<
Redirect
to
=
"
/user
"
/>
;
}
if
(
success
)
{
if
(
success
)
{
alert
(
'
로그인 되었습니다
'
)
alert
(
'
로그인 되었습니다
'
)
return
<
Redirect
to
=
"
/user
"
/>
}
}
const
{
email
,
password
}
=
user
;
const
{
email
,
password
}
=
user
return
(
return
(
<
div
className
=
"
modal-content
"
>
<
div
className
=
"
modal-content
"
>
{
error
&&
<
div
className
=
"
alert alert-danger
"
>
{
error
}
<
/div>
}
<
form
onSubmit
=
{
handleSubmit
}
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"
modal-header
"
>
<
div
className
=
"
modal-header
"
>
<
h5
className
=
"
modal-title
"
id
=
"
loginModalLabel
"
>
<
h5
className
=
"
modal-title
"
id
=
"
loginModalLabel
"
>
...
@@ -88,13 +91,18 @@ const Login = () => {
...
@@ -88,13 +91,18 @@ const Login = () => {
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
className
=
"
modal-footer
"
>
<
div
className
=
"
modal-footer
"
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
disabled
=
{
disabled
}
>
<
button
type
=
"
submit
"
className
=
"
btn btn-primary
"
disabled
=
{
disabled
}
data
-
bs
-
dismiss
=
"
modal
"
>
로그인
로그인
<
/button
>
<
/button
>
<
/div
>
<
/div
>
<
/form
>
<
/form
>
<
/div
>
<
/div
>
)
;
)
}
;
}
export
default
Login
;
export
default
Login
client/src/components/Profile/InfoUpdate.js
View file @
63618602
...
@@ -44,7 +44,7 @@ const InfoUpdate = () => {
...
@@ -44,7 +44,7 @@ const InfoUpdate = () => {
type
=
"
button
"
type
=
"
button
"
className
=
"
btn btn-outline-white
"
className
=
"
btn btn-outline-white
"
style
=
{{
style
=
{{
background
:
"
#
E8B7FF
"
,
background
:
"
#
d4cafb
"
,
fontSize
:
"
13px
"
,
fontSize
:
"
13px
"
,
fontWeight
:
"
bold
"
,
fontWeight
:
"
bold
"
,
}}
}}
...
@@ -105,7 +105,7 @@ const InfoUpdate = () => {
...
@@ -105,7 +105,7 @@ const InfoUpdate = () => {
borderRight
:
"
0
"
,
borderRight
:
"
0
"
,
borderLeft
:
"
0
"
,
borderLeft
:
"
0
"
,
borderBottom
:
"
1
"
,
borderBottom
:
"
1
"
,
borderColor
:
"
#
E8B7FF
"
,
borderColor
:
"
#
d4cafb
"
,
height
:
"
38px
"
,
height
:
"
38px
"
,
width
:
"
130px
"
,
width
:
"
130px
"
,
}}
}}
...
@@ -139,7 +139,7 @@ const InfoUpdate = () => {
...
@@ -139,7 +139,7 @@ const InfoUpdate = () => {
type
=
"
button
"
type
=
"
button
"
className
=
"
btn btn-outline-white ms-2
"
className
=
"
btn btn-outline-white ms-2
"
style
=
{{
style
=
{{
background
:
"
#
E8B7FF
"
,
background
:
"
#
d4cafb
"
,
fontSize
:
"
13px
"
,
fontSize
:
"
13px
"
,
fontWeight
:
"
bold
"
,
fontWeight
:
"
bold
"
,
}}
}}
...
...
client/src/components/Profile/Profile.js
View file @
63618602
...
@@ -18,7 +18,7 @@ const Profile = () => {
...
@@ -18,7 +18,7 @@ const Profile = () => {
type
=
"
button
"
type
=
"
button
"
className
=
"
btn btn-outline-white
"
className
=
"
btn btn-outline-white
"
style
=
{{
style
=
{{
background
:
"
#
E8B7FF
"
,
background
:
"
#
d4cafb
"
,
fontSize
:
"
13px
"
,
fontSize
:
"
13px
"
,
fontWeight
:
"
bold
"
,
fontWeight
:
"
bold
"
,
}}
}}
...
...
client/src/components/Room/RightHamburger.js
View file @
63618602
...
@@ -62,9 +62,9 @@ const RightHamberger = () => {
...
@@ -62,9 +62,9 @@ const RightHamberger = () => {
style
=
{{
style
=
{{
height
:
'
30px
'
,
height
:
'
30px
'
,
fontWeight
:
'
bold
'
,
fontWeight
:
'
bold
'
,
backgroundColor
:
'
#
D64D61
'
,
backgroundColor
:
'
#
d86da6
'
,
color
:
'
black
'
,
color
:
'
black
'
,
border
:
'
1px #
D64D61
'
,
border
:
'
1px #
d86da6
'
,
}}
}}
>
>
퇴장
퇴장
...
...
client/src/components/Room/Screen.js
View file @
63618602
import
React
,
{
useState
}
from
"
react
"
;
import
io
from
"
socket.io-client
"
;
import
{
useRef
}
from
"
react
"
;
import
{
useEffect
}
from
"
react
"
;
import
Video
from
"
./Video
"
;
import
{
useParams
}
from
"
react-router-dom
"
;
const
Screen
=
()
=>
{
const
Screen
=
()
=>
{
const
user
=
'
00
'
const
[
socket
,
setSocket
]
=
useState
(
null
);
const
[
users
,
setUsers
]
=
useState
([]);
const
{
roomId
,
channelId
}
=
useParams
();
const
user
=
"
00
"
;
let
localVideoRef
=
useRef
(
null
);
let
sendPC
;
let
receivePCs
;
// 방화벽 등의 보호장치를 거쳐 ip로 연결하기 위한 설정
const
pc_config
=
{
iceServers
:
[
// {
// urls: 'stun:[STUN_IP]:[PORT]',
// 'credentials': '[YOR CREDENTIALS]',
// 'username': '[USERNAME]'
// },
{
urls
:
"
stun:stun.l.google.com:19302
"
,
},
],
};
useEffect
(()
=>
{
let
newSocket
=
io
.
connect
(
"
http://localhost:8080
"
);
let
localStream
;
// console.log("newSocket", newSocket.id);
//
newSocket
.
on
(
"
userEnter
"
,
(
data
)
=>
{
console
.
log
(
data
);
createReceivePC
(
data
.
id
,
newSocket
);
});
newSocket
.
on
(
"
allUsers
"
,
(
data
)
=>
{
let
len
=
data
.
users
.
length
;
for
(
let
i
=
0
;
i
<
len
;
i
++
)
{
createReceivePC
(
data
.
users
[
i
].
id
,
newSocket
);
}
});
newSocket
.
on
(
"
userExit
"
,
(
data
)
=>
{
receivePCs
[
data
.
id
].
close
();
delete
receivePCs
[
data
.
id
];
setUsers
((
users
)
=>
users
.
filter
((
user
)
=>
user
.
id
!==
data
.
id
));
});
newSocket
.
on
(
"
getSenderAnswer
"
,
async
(
data
)
=>
{
try
{
console
.
log
(
"
get sender answer
"
);
console
.
log
(
data
.
sdp
);
await
sendPC
.
setRemoteDescription
(
new
RTCSessionDescription
(
data
.
sdp
));
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
newSocket
.
on
(
"
getSenderCandidate
"
,
async
(
data
)
=>
{
try
{
console
.
log
(
"
get sender candidate
"
);
if
(
!
data
.
candidate
)
return
;
sendPC
.
addIceCandidate
(
new
RTCIceCandidate
(
data
.
candidate
));
console
.
log
(
"
candidate add success
"
);
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
newSocket
.
on
(
"
getReceiverAnswer
"
,
async
(
data
)
=>
{
try
{
console
.
log
(
`get socketID(
${
data
.
id
}
)'s answer`
);
let
pc
=
receivePCs
[
data
.
id
];
await
pc
.
setRemoteDescription
(
data
.
sdp
);
console
.
log
(
`socketID(
${
data
.
id
}
)'s set remote sdp success`
);
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
newSocket
.
on
(
"
getReceiverCandidate
"
,
async
(
data
)
=>
{
try
{
console
.
log
(
data
);
console
.
log
(
`get socketID(
${
data
.
id
}
)'s candidate`
);
let
pc
=
receivePCs
[
data
.
id
];
if
(
!
data
.
candidate
)
return
;
pc
.
addIceCandidate
(
new
RTCIceCandidate
(
data
.
candidate
));
console
.
log
(
`socketID(
${
data
.
id
}
)'s candidate add success`
);
}
catch
(
error
)
{
console
.
log
(
error
);
}
});
setSocket
(
newSocket
);
navigator
.
mediaDevices
.
getUserMedia
({
audio
:
true
,
video
:
{
width
:
375
,
height
:
260
,
},
})
.
then
((
stream
)
=>
{
if
(
localVideoRef
.
current
)
localVideoRef
.
current
.
srcObject
=
stream
;
localStream
=
stream
;
sendPC
=
createSenderPeerConnection
(
newSocket
,
localStream
);
createSenderOffer
(
newSocket
);
newSocket
.
emit
(
"
joinRoom
"
,
{
id
:
newSocket
.
id
,
roomID
:
roomId
,
});
})
.
catch
((
error
)
=>
{
console
.
log
(
`getUserMedia error:
${
error
}
`
);
});
},
[]);
const
createReceivePC
=
(
id
,
newSocket
)
=>
{
try
{
console
.
log
(
`socketID(
${
id
}
) user entered`
);
let
pc
=
createReceiverPeerConnection
(
id
,
newSocket
);
createReceiverOffer
(
pc
,
newSocket
,
id
);
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
const
createSenderOffer
=
async
(
newSocket
)
=>
{
try
{
let
sdp
=
await
sendPC
.
createOffer
({
offerToReceiveAudio
:
false
,
offerToReceiveVideo
:
false
,
});
console
.
log
(
"
create sender offer success
"
);
await
sendPC
.
setLocalDescription
(
new
RTCSessionDescription
(
sdp
));
console
.
log
(
sdp
,
"
안
"
,
newSocket
.
id
,
"
녕
"
,
roomId
);
newSocket
.
emit
(
"
senderOffer
"
,
{
sdp
,
senderSocketID
:
newSocket
.
id
,
roomID
:
roomId
,
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
const
createReceiverOffer
=
async
(
pc
,
newSocket
,
senderSocketID
)
=>
{
try
{
let
sdp
=
await
pc
.
createOffer
({
offerToReceiveAudio
:
true
,
offerToReceiveVideo
:
true
,
});
console
.
log
(
"
create receiver offer success
"
);
await
pc
.
setLocalDescription
(
new
RTCSessionDescription
(
sdp
));
console
.
log
(
sdp
,
newSocket
.
id
,
senderSocketID
,
roomId
);
newSocket
.
emit
(
"
receiverOffer
"
,
{
sdp
,
receiverSocketID
:
newSocket
.
id
,
senderSocketID
,
roomID
:
roomId
,
});
}
catch
(
error
)
{
console
.
log
(
error
);
}
};
const
createSenderPeerConnection
=
(
newSocket
,
localStream
)
=>
{
let
pc
=
new
RTCPeerConnection
(
pc_config
);
pc
.
onicecandidate
=
(
e
)
=>
{
if
(
e
.
candidate
)
{
console
.
log
(
"
sender PC onicecandidate
"
);
newSocket
.
emit
(
"
senderCandidate
"
,
{
candidate
:
e
.
candidate
,
senderSocketID
:
newSocket
.
id
,
});
}
};
pc
.
oniceconnectionstatechange
=
(
e
)
=>
{
console
.
log
(
e
);
};
if
(
localStream
)
{
console
.
log
(
"
localstream add
"
);
localStream
.
getTracks
().
forEach
((
track
)
=>
{
pc
.
addTrack
(
track
,
localStream
);
});
}
else
{
console
.
log
(
"
no local stream
"
);
}
// return pc
return
pc
;
};
const
createReceiverPeerConnection
=
(
socketID
,
newSocket
)
=>
{
let
pc
=
new
RTCPeerConnection
(
pc_config
);
// add pc to peerConnections object
receivePCs
=
{
...
receivePCs
,
[
socketID
]:
pc
};
pc
.
onicecandidate
=
(
e
)
=>
{
if
(
e
.
candidate
)
{
console
.
log
(
"
receiver PC onicecandidate
"
);
newSocket
.
emit
(
"
receiverCandidate
"
,
{
candidate
:
e
.
candidate
,
receiverSocketID
:
newSocket
.
id
,
senderSocketID
:
socketID
,
});
}
};
pc
.
oniceconnectionstatechange
=
(
e
)
=>
{
console
.
log
(
e
);
};
pc
.
ontrack
=
(
e
)
=>
{
console
.
log
(
"
ontrack success
"
);
setUsers
((
oldUsers
)
=>
oldUsers
.
filter
((
user
)
=>
user
.
id
!==
socketID
));
setUsers
((
oldUsers
)
=>
[
...
oldUsers
,
{
id
:
socketID
,
stream
:
e
.
streams
[
0
],
},
]);
};
// return pc
return
pc
;
};
return
(
return
(
<
div
className
=
"
container
"
>
<
div
className
=
"
container
"
>
<
div
className
=
"
row
"
>
{
/* {console.log(users)} */
}
<
div
className
=
"
col mt-3 d-flex justify-content-space-between
"
style
=
{{
backgroundColor
:
'
#FCF4FF
'
}}
>
<
div
className
=
"
mt-3
"
style
=
{{
backgroundColor
:
"
#FCF4FF
"
}}
>
<
div
className
=
"
m-2 d-flex fw-bold text-center
"
style
=
{{
color
:
"
#4A4251
"
,
fontSize
:
"
20px
"
}}
>
<
img
<
img
className
=
"
rounded-circle
"
className
=
"
rounded-circle
me-2
"
src
=
"
/cherry.jpg
"
src
=
"
/cherry.jpg
"
width
=
"
40px
"
width
=
"
40px
"
height
=
"
40px
"
height
=
"
40px
"
/>
/>
<
p
className
=
"
m-2
"
style
=
{{
fontWeight
:
'
bold
'
,
color
:
'
#4A4251
'
,
fontSize
:
'
20px
'
}}
>
{
user
}
님이
화면공유중
...
{
user
}
님이
화면공유중
...
<
br
/>
<
/p
>
<
div
className
=
"
col m-5
"
><
/div
>
<
/div
>
<
/div
>
<
video
style
=
{{
display
:
"
flex
"
,
justifyContent
:
"
center
"
,
width
:
375
,
height
:
260
,
backgroundColor
:
"
black
"
,
}}
muted
ref
=
{
localVideoRef
}
autoPlay
/>
{
/* {users.map((user, index) => {
return <Video key={index} stream={user.stream} />;
})} */
}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
)
;
}
}
;
export
default
Screen
export
default
Screen
;
client/src/components/Room/User.js
View file @
63618602
...
@@ -2,7 +2,7 @@ const User = () => {
...
@@ -2,7 +2,7 @@ const User = () => {
return
(
return
(
<
div
className
=
"
container
"
>
<
div
className
=
"
container
"
>
<
div
className
=
"
row
"
>
<
div
className
=
"
row
"
>
<
div
className
=
"
col
"
style
=
{{
backgroundColor
:
"
#
DEC7F5
"
,
position
:
'
absolute
'
,
bottom
:
'
58px
'
,
width
:
'
414px
'
}}
>
<
div
className
=
"
col
"
style
=
{{
backgroundColor
:
"
#
ded0fa
"
,
position
:
'
absolute
'
,
bottom
:
'
58px
'
,
width
:
'
414px
'
}}
>
<
p
<
p
className
=
"
m-2
"
className
=
"
m-2
"
style
=
{{
fontWeight
:
"
bold
"
,
color
:
"
#4A4251
"
,
fontSize
:
"
20px
"
}}
style
=
{{
fontWeight
:
"
bold
"
,
color
:
"
#4A4251
"
,
fontSize
:
"
20px
"
}}
...
...
client/src/components/SignUp.js
View file @
63618602
import
axios
from
"
axios
"
;
import
axios
from
"
axios
"
;
import
{
useEffect
,
useState
}
from
"
react
"
;
import
{
useEffect
,
useState
}
from
"
react
"
;
import
{
Redirect
}
from
"
react-router-dom
"
;
import
userApi
from
"
../apis/user.api
"
;
import
userApi
from
"
../apis/user.api
"
;
// import catchErrors from "../context/catchError";
// import auth from "../context/auth_context"
const
INIT_USER
=
{
const
INIT_USER
=
{
name
:
""
,
name
:
""
,
idNumber1
:
""
,
idNumber1
:
""
,
...
@@ -17,6 +19,7 @@ const Signup = () => {
...
@@ -17,6 +19,7 @@ const Signup = () => {
const
[
error
,
setError
]
=
useState
(
""
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
disabled
,
setDisabled
]
=
useState
(
false
);
const
[
disabled
,
setDisabled
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
useEffect
(()
=>
{
useEffect
(()
=>
{
setDisabled
(
setDisabled
(
...
@@ -40,11 +43,13 @@ const Signup = () => {
...
@@ -40,11 +43,13 @@ const Signup = () => {
async
function
handleSubmit
()
{
async
function
handleSubmit
()
{
try
{
try
{
const
data
=
await
userApi
.
signup
(
user
)
const
data
=
await
userApi
.
signup
(
user
)
// const data = await axios.post("https://localhost:8080/api/room/1/1",user)
setLoading
(
true
);
setLoading
(
true
);
setError
(
""
);
setError
(
""
);
// const success = await login(user.email, user.password);
// const success = await login(user.email, user.password);
// const data = await axios.post("/api/room/1/1",user)
console
.
log
(
data
);
console
.
log
(
data
);
setSuccess
(
success
);
setSuccess
(
true
);
}
catch
(
error
)
{
}
catch
(
error
)
{
// catchErrors(error, setError);
// catchErrors(error, setError);
}
finally
{
}
finally
{
...
@@ -54,6 +59,7 @@ const Signup = () => {
...
@@ -54,6 +59,7 @@ const Signup = () => {
if
(
success
)
{
if
(
success
)
{
alert
(
'
회원가입 되었습니다.
'
)
alert
(
'
회원가입 되었습니다.
'
)
return
<
Redirect
to
=
"
/
"
/>
;
}
}
...
...
client/src/context/auth.js
0 → 100644
View file @
63618602
import
axios
from
'
axios
'
export
function
handleLogin
(
userId
)
{
localStorage
.
setItem
(
"
user
"
,
userId
)
}
export
async
function
handleLogout
()
{
alert
(
"
로그아웃되었습니다.
"
)
localStorage
.
removeItem
(
"
user
"
)
await
axios
.
get
(
'
/api/auth/logout
'
)
window
.
location
.
href
=
'
/
'
}
export
function
isAuthenticated
()
{
const
userId
=
localStorage
.
getItem
(
'
loginStatus
'
)
if
(
userId
)
{
return
userId
}
else
{
return
false
}
}
client/src/context/auth_context.js
View file @
63618602
import
axios
from
"
axios
"
;
import
axios
from
"
axios
"
;
import
{
createContext
,
FC
,
useCallback
,
useContext
,
useState
}
from
"
react
"
;
import
{
createContext
,
FC
,
useCallback
,
useContext
,
useState
}
from
"
react
"
;
import
authApi
from
"
../apis/
auth
.api
"
;
import
authApi
from
"
../apis/
user
.api
"
;
import
{
getLocalUser
}
from
"
../utils/auth
"
;
import
{
getLocalUser
}
from
"
../utils/auth
"
;
import
baseUrl
from
"
../utils/baseUrl
"
;
import
baseUrl
from
"
../utils/baseUrl
"
;
import
catchErrors
from
"
../utils/catchErrors
"
;
import
catchErrors
from
"
../utils/catchErrors
"
;
...
...
client/src/context/catchError.js
0 → 100644
View file @
63618602
function
catchErrors
(
error
,
displayError
)
{
let
errorMsg
if
(
error
.
response
)
{
errorMsg
=
error
.
response
.
data
console
.
log
(
errorMsg
)
}
else
if
(
error
.
requset
)
{
errorMsg
=
error
.
requset
console
.
log
(
errorMsg
)
}
else
{
errorMsg
=
error
.
message
console
.
log
(
errorMsg
)
}
displayError
(
errorMsg
)
}
export
default
catchErrors
client/src/scss/custom.scss
View file @
63618602
$primary
:
#
e8b7ff
;
$primary
:
#
f5cfe3
;
$secondary
:
#df99ff
;
$secondary
:
#df99ff
;
$info
:
#fcf4ff
;
$info
:
#fcf4ff
;
$warning
:
#ff0000
;
$warning
:
#ff0000
;
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment