Fix event listener lifecycle and add more debugging

This commit is contained in:
Robert Long 2021-07-23 14:50:33 -07:00
parent 7010120c11
commit 2b84adccc3
2 changed files with 69 additions and 32 deletions

View file

@ -358,17 +358,24 @@ function JoinOrCreateRoom({ client }) {
} }
function useVideoRoom(client, roomId, timeout = 5000) { function useVideoRoom(client, roomId, timeout = 5000) {
const [{ loading, joined, room, participants, error }, setState] = useState({ const [
{ loading, joined, room, conferenceCall, participants, error },
setState,
] = useState({
loading: true, loading: true,
joined: false, joined: false,
room: undefined, room: undefined,
participants: [], participants: [],
error: undefined, error: undefined,
conferenceCall: null,
}); });
useEffect(() => { useEffect(() => {
const conferenceCall = new ConferenceCall(client, roomId);
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
conferenceCall,
loading: true, loading: true,
room: undefined, room: undefined,
error: undefined, error: undefined,
@ -424,17 +431,6 @@ function useVideoRoom(client, roomId, timeout = 5000) {
}, [roomId]); }, [roomId]);
const joinCall = useCallback(() => { const joinCall = useCallback(() => {
const conferenceCall = new ConferenceCall(client, roomId);
const onJoined = () => {
setState((prevState) => ({
...prevState,
joined: true,
}));
};
conferenceCall.on("joined", onJoined);
const onParticipantsChanged = () => { const onParticipantsChanged = () => {
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
@ -446,13 +442,16 @@ function useVideoRoom(client, roomId, timeout = 5000) {
conferenceCall.join(); conferenceCall.join();
setState((prevState) => ({
...prevState,
joined: true,
}));
return () => { return () => {
conferenceCall.removeListener("joined", onJoined);
conferenceCall.removeListener( conferenceCall.removeListener(
"participants_changed", "participants_changed",
onParticipantsChanged onParticipantsChanged
); );
conferenceCall.leave();
setState((prevState) => ({ setState((prevState) => ({
...prevState, ...prevState,
@ -460,7 +459,7 @@ function useVideoRoom(client, roomId, timeout = 5000) {
participants: [], participants: [],
})); }));
}; };
}, [client, roomId]); }, [client, conferenceCall, roomId]);
return { loading, joined, room, participants, error, joinCall }; return { loading, joined, room, participants, error, joinCall };
} }
@ -513,9 +512,26 @@ function Participant({ participant }) {
}, [participant.feed]); }, [participant.feed]);
return ( return (
<div> <li>
{participant.userId} <h3>
User ID:{participant.userId} {participant.local && "(Local)"}
</h3>
{!participant.local && (
<>
<h3>Calls:</h3>
<ul>
{participant.calls.map((call) => (
<li key={call.callId}>
<p>Call ID: {call.callId}</p>
<p>Direction: {call.direction}</p>
<p>State: {call.state}</p>
<p>Hangup Reason: {call.hangupReason}</p>
</li>
))}
</ul>
</>
)}
<video ref={videoRef}></video> <video ref={videoRef}></video>
</div> </li>
); );
} }

View file

@ -2,33 +2,31 @@ import EventEmitter from "events";
const CONF_ROOM = "me.robertlong.conf"; const CONF_ROOM = "me.robertlong.conf";
const CONF_PARTICIPANT = "me.robertlong.conf.participant"; const CONF_PARTICIPANT = "me.robertlong.conf.participant";
const PARTICIPANT_TIMEOUT = 1000 * 30; const PARTICIPANT_TIMEOUT = 1000 * 5;
export class ConferenceCall extends EventEmitter { export class ConferenceCall extends EventEmitter {
constructor(client, roomId) { constructor(client, roomId) {
super(); super();
this.client = client; this.client = client;
this.roomId = roomId; this.roomId = roomId;
this.confId = null; this.joined = false;
this.room = client.getRoom(roomId); this.room = client.getRoom(roomId);
this.localParticipant = { this.localParticipant = {
local: true,
userId: client.getUserId(), userId: client.getUserId(),
feed: null, feed: null,
call: null, call: null,
muted: true, muted: true,
calls: [],
}; };
this.participants = [this.localParticipant]; this.participants = [this.localParticipant];
client.on("Room.timeline", function (event, room, toStartOfTimeline) { this.client.on("RoomState.members", this._onMemberChanged);
console.debug(event.event); this.client.on("Call.incoming", this._onIncomingCall);
});
} }
join() { join() {
this.client.on("RoomState.members", this._onMemberChanged); this.joined = true;
this.client.on("Call.incoming", this._onIncomingCall);
this.emit("joined");
const activeConf = this.room.currentState const activeConf = this.room.currentState
.getStateEvents(CONF_ROOM, "") .getStateEvents(CONF_ROOM, "")
@ -69,11 +67,18 @@ export class ConferenceCall extends EventEmitter {
}; };
_onMemberChanged = (_event, _state, member) => { _onMemberChanged = (_event, _state, member) => {
if (!this.joined) {
console.debug("_onMemberChanged", member, "not joined");
return;
}
this._processMember(member.userId); this._processMember(member.userId);
}; };
_processMember(userId) { _processMember(userId) {
if (userId === this.client.getUserId()) { const localUserId = this.client.getUserId();
if (userId === localUserId || userId < localUserId) {
return; return;
} }
@ -85,13 +90,18 @@ export class ConferenceCall extends EventEmitter {
); );
const participantTimeout = memberStateEvent.getContent()[CONF_PARTICIPANT]; const participantTimeout = memberStateEvent.getContent()[CONF_PARTICIPANT];
console.debug(
"_processMember",
new Date().getTime() - participantTimeout > PARTICIPANT_TIMEOUT
);
if ( if (
typeof participantTimeout === "number" && typeof participantTimeout === "number" &&
new Date().getTime() - participantTimeout > PARTICIPANT_TIMEOUT * 1.5 new Date().getTime() - participantTimeout > PARTICIPANT_TIMEOUT
) { ) {
if (participant && participant.call) { // if (participant && participant.call) {
participant.call.hangup("user_hangup"); // participant.call.hangup("user_hangup");
} // }
return; return;
} }
@ -102,6 +112,15 @@ export class ConferenceCall extends EventEmitter {
} }
_onIncomingCall = (call) => { _onIncomingCall = (call) => {
if (!this.joined) {
console.debug(
"_onIncomingCall",
"Member hasn't joined yet. Not answering."
);
//call.hangup();
return;
}
console.debug("_onIncomingCall", call); console.debug("_onIncomingCall", call);
this._addCall(call); this._addCall(call);
call.answer(); call.answer();
@ -129,6 +148,7 @@ export class ConferenceCall extends EventEmitter {
userId, userId,
feed: null, feed: null,
call, call,
calls: [call],
}); });
call.on("feeds_changed", () => this._onCallFeedsChanged(call)); call.on("feeds_changed", () => this._onCallFeedsChanged(call));
@ -196,6 +216,7 @@ export class ConferenceCall extends EventEmitter {
const remoteParticipant = this.participants.find((p) => p.call === call); const remoteParticipant = this.participants.find((p) => p.call === call);
remoteParticipant.call = newCall; remoteParticipant.call = newCall;
remoteParticipant.calls.push(newCall);
newCall.on("feeds_changed", () => this._onCallFeedsChanged(newCall)); newCall.on("feeds_changed", () => this._onCallFeedsChanged(newCall));
newCall.on("hangup", () => this._onCallHangup(newCall)); newCall.on("hangup", () => this._onCallHangup(newCall));