1
1
import { Socket } from "socket.io" ;
2
- import {
3
- REMATCH_REQUEST ,
4
- MATCH_REQUEST ,
5
- SOCKET_DISCONNECT ,
6
- USER_CONNECTED ,
7
- USER_DISCONNECTED ,
8
- MATCH_DECLINE_REQUEST ,
9
- MATCH_UNSUCCESSFUL ,
10
- MATCH_SUCCESSFUL ,
11
- MATCH_END_REQUEST ,
12
- MATCH_ENDED ,
13
- MATCH_ACCEPT_REQUEST ,
14
- MATCH_FOUND ,
15
- MATCH_REQUEST_EXISTS ,
16
- MATCH_REQUEST_ERROR ,
17
- CANCEL_MATCH_REQUEST ,
18
- } from "../utils/constants" ;
19
2
import {
20
3
sendMatchRequest ,
21
4
handleMatchAccept ,
22
5
MatchRequest ,
23
6
handleMatchDelete ,
24
- MatchRequestItem ,
25
7
getMatchIdByUid ,
8
+ MatchUser ,
9
+ getMatchByUid ,
26
10
} from "./matchHandler" ;
27
11
import { io } from "../../server" ;
28
12
13
+ enum MatchEvents {
14
+ // Receive
15
+ MATCH_REQUEST = "match_request" ,
16
+ CANCEL_MATCH_REQUEST = "cancel_match_request" ,
17
+ MATCH_ACCEPT_REQUEST = "match_accept_request" ,
18
+ MATCH_DECLINE_REQUEST = "match_decline_request" ,
19
+ REMATCH_REQUEST = "rematch_request" ,
20
+ MATCH_END_REQUEST = "match_end_request" ,
21
+ MATCH_STATUS_REQUEST = "match_status_request" ,
22
+
23
+ USER_CONNECTED = "user_connected" ,
24
+ USER_DISCONNECTED = "user_disconnected" ,
25
+ SOCKET_DISCONNECT = "disconnect" ,
26
+ SOCKET_CLIENT_DISCONNECT = "client namespace disconnect" ,
27
+
28
+ // Send
29
+ MATCH_FOUND = "match_found" ,
30
+ MATCH_SUCCESSFUL = "match_successful" ,
31
+ MATCH_UNSUCCESSFUL = "match_unsuccessful" ,
32
+ MATCH_ENDED = "match_ended" ,
33
+ MATCH_REQUEST_EXISTS = "match_request_exists" ,
34
+ MATCH_REQUEST_ERROR = "match_request_error" ,
35
+ }
36
+
29
37
interface UserConnection {
30
38
socket : Socket ;
31
39
connectionTimeout ?: NodeJS . Timeout ;
40
+ isDisconnecting : boolean ;
32
41
}
33
42
34
- // TODO: do a match lost due to poor connection?
35
43
const connectionDelay = 3000 ; // time window to allow for page navigation / refresh
36
44
const userConnections = new Map < string , UserConnection > ( ) ;
37
45
38
46
export const handleWebsocketMatchEvents = ( socket : Socket ) => {
39
47
socket . removeAllListeners ( ) ;
40
48
41
- socket . on ( USER_CONNECTED , ( uid : string ) => {
49
+ socket . on ( MatchEvents . USER_CONNECTED , ( uid : string ) => {
50
+ console . log ( `uid: ${ uid } and socket id: ${ socket . id } ` ) ;
42
51
clearTimeout ( userConnections . get ( uid ) ?. connectionTimeout ) ;
43
- userConnections . set ( uid , { socket : socket } ) ;
44
- console . log ( `socket: ${ socket . id } ` ) ;
52
+ if ( userConnections . has ( uid ) ) {
53
+ const matchId = getMatchIdByUid ( uid ) ;
54
+ if ( matchId ) {
55
+ socket . join ( matchId ) ;
56
+ }
57
+ }
58
+ userConnections . set ( uid , { socket : socket , isDisconnecting : false } ) ;
45
59
} ) ;
46
60
47
- socket . on ( USER_DISCONNECTED , ( uid : string , matchId : string | null ) => {
61
+ socket . on ( MatchEvents . USER_DISCONNECTED , ( uid : string ) => {
48
62
if ( ! userConnections . has ( uid ) ) {
49
63
return ;
50
64
}
51
65
52
66
clearTimeout ( userConnections . get ( uid ) ?. connectionTimeout ) ;
53
67
54
68
const connectionTimeout = setTimeout ( ( ) => {
55
- endMatchOnUserDisconnect ( socket , uid , matchId ) ;
56
- console . log ( `server disconnect connection: ${ uid } ` ) ;
69
+ endMatchOnUserDisconnect ( socket , uid ) ;
57
70
socket . disconnect ( ) ;
58
- } , connectionDelay ) ; // TODO: Clearing up your previous match (in case user immediately sends a new match request)
71
+ } , connectionDelay ) ;
59
72
60
73
userConnections . set ( uid , {
61
74
socket : socket ,
62
75
connectionTimeout : connectionTimeout ,
76
+ isDisconnecting : true ,
63
77
} ) ;
64
78
} ) ;
65
79
66
80
socket . on (
67
- MATCH_REQUEST ,
81
+ MatchEvents . MATCH_REQUEST ,
68
82
async (
69
83
matchRequest : MatchRequest ,
70
84
callback : ( requested : boolean ) => void
71
85
) => {
72
86
const uid = matchRequest . user . id ;
73
- if ( isUserConnected ( uid ) ) {
74
- socket . emit ( MATCH_REQUEST_EXISTS ) ;
87
+ if ( isUserConnected ( uid ) && ! userConnections . get ( uid ) ?. isDisconnecting ) {
88
+ socket . emit ( MatchEvents . MATCH_REQUEST_EXISTS ) ;
75
89
callback ( false ) ;
76
90
return ;
77
91
}
78
92
79
- userConnections . set ( uid , { socket : socket } ) ;
93
+ userConnections . set ( uid , { socket : socket , isDisconnecting : false } ) ;
80
94
81
95
const sent = await sendMatchRequest ( matchRequest ) ;
82
96
if ( ! sent ) {
83
- socket . emit ( MATCH_REQUEST_ERROR ) ;
97
+ socket . emit ( MatchEvents . MATCH_REQUEST_ERROR ) ;
84
98
userConnections . delete ( uid ) ;
85
99
socket . disconnect ( ) ;
86
100
}
87
101
callback ( sent ) ;
88
102
}
89
103
) ;
90
104
91
- socket . on ( CANCEL_MATCH_REQUEST , ( uid : string ) => {
105
+ socket . on ( MatchEvents . CANCEL_MATCH_REQUEST , ( uid : string ) => {
92
106
userConnections . delete ( uid ) ;
93
107
} ) ;
94
108
95
- socket . on ( MATCH_ACCEPT_REQUEST , ( matchId : string ) => {
109
+ socket . on ( MatchEvents . MATCH_ACCEPT_REQUEST , ( matchId : string ) => {
96
110
const partnerAccepted = handleMatchAccept ( matchId ) ;
97
111
if ( partnerAccepted ) {
98
- io . to ( matchId ) . emit ( MATCH_SUCCESSFUL ) ;
112
+ io . to ( matchId ) . emit ( MatchEvents . MATCH_SUCCESSFUL ) ;
99
113
}
100
114
} ) ;
101
115
102
116
socket . on (
103
- MATCH_DECLINE_REQUEST ,
117
+ MatchEvents . MATCH_DECLINE_REQUEST ,
104
118
( uid : string , matchId : string , isTimeout : boolean ) => {
105
119
userConnections . delete ( uid ) ;
106
120
const matchDeleted = handleMatchDelete ( matchId ) ;
107
121
if ( matchDeleted && ! isTimeout ) {
108
- socket . to ( matchId ) . emit ( MATCH_UNSUCCESSFUL ) ;
122
+ socket . to ( matchId ) . emit ( MatchEvents . MATCH_UNSUCCESSFUL ) ;
109
123
}
110
124
}
111
125
) ;
112
126
113
127
socket . on (
114
- REMATCH_REQUEST ,
128
+ MatchEvents . REMATCH_REQUEST ,
115
129
async (
116
130
matchId : string ,
117
131
rematchRequest : MatchRequest ,
118
132
callback : ( result : boolean ) => void
119
133
) => {
120
134
const matchDeleted = handleMatchDelete ( matchId ) ;
121
135
if ( matchDeleted ) {
122
- socket . to ( matchId ) . emit ( MATCH_UNSUCCESSFUL ) ;
136
+ socket . to ( matchId ) . emit ( MatchEvents . MATCH_UNSUCCESSFUL ) ;
123
137
}
124
138
125
139
const sent = await sendMatchRequest ( rematchRequest ) ;
126
140
if ( ! sent ) {
127
- socket . emit ( MATCH_REQUEST_ERROR ) ;
141
+ socket . emit ( MatchEvents . MATCH_REQUEST_ERROR ) ;
128
142
}
129
143
callback ( sent ) ;
130
144
}
131
145
) ;
132
146
133
- socket . on ( MATCH_END_REQUEST , ( uid : string , matchId : string ) => {
147
+ socket . on ( MatchEvents . MATCH_END_REQUEST , ( uid : string , matchId : string ) => {
134
148
userConnections . delete ( uid ) ;
135
149
const matchDeleted = handleMatchDelete ( matchId ) ;
136
150
if ( matchDeleted ) {
137
- socket . to ( matchId ) . emit ( MATCH_ENDED ) ;
151
+ socket . to ( matchId ) . emit ( MatchEvents . MATCH_ENDED ) ;
138
152
}
139
153
} ) ;
140
154
141
- // TODO: handle client reconnect failure
142
- socket . on ( SOCKET_DISCONNECT , ( ) => {
155
+ socket . on (
156
+ MatchEvents . MATCH_STATUS_REQUEST ,
157
+ (
158
+ uid : string ,
159
+ callback : ( match : { matchId : string ; partner : MatchUser } | null ) => void
160
+ ) => {
161
+ const match = getMatchByUid ( uid ) ;
162
+ callback ( match ) ;
163
+ }
164
+ ) ;
165
+
166
+ socket . on ( MatchEvents . SOCKET_DISCONNECT , ( ) => {
143
167
for ( const [ uid , userConnection ] of userConnections ) {
144
168
if ( userConnection . socket . id === socket . id ) {
145
169
if ( ! userConnections . get ( uid ) ?. connectionTimeout ) {
146
- const matchId = getMatchIdByUid ( uid ) ;
147
- endMatchOnUserDisconnect ( socket , uid , matchId ) ;
148
- console . log ( `force delete connection: ${ uid } ` ) ;
170
+ endMatchOnUserDisconnect ( socket , uid ) ;
149
171
}
150
172
break ;
151
173
}
@@ -155,33 +177,30 @@ export const handleWebsocketMatchEvents = (socket: Socket) => {
155
177
156
178
export const sendMatchFound = (
157
179
matchId : string ,
158
- requestItem1 : MatchRequestItem ,
159
- requestItem2 : MatchRequestItem
180
+ matchUser1 : MatchUser ,
181
+ matchUser2 : MatchUser
160
182
) => {
161
- userConnections . get ( requestItem1 . user . id ) ?. socket . join ( matchId ) ;
162
- userConnections . get ( requestItem2 . user . id ) ?. socket . join ( matchId ) ;
163
- io . to ( matchId ) . emit ( MATCH_FOUND , {
183
+ userConnections . get ( matchUser1 . id ) ?. socket . join ( matchId ) ;
184
+ userConnections . get ( matchUser2 . id ) ?. socket . join ( matchId ) ;
185
+ io . to ( matchId ) . emit ( MatchEvents . MATCH_FOUND , {
164
186
matchId : matchId ,
165
- user1 : requestItem1 . user ,
166
- user2 : requestItem2 . user ,
187
+ user1 : matchUser1 ,
188
+ user2 : matchUser2 ,
167
189
} ) ;
168
190
} ;
169
191
170
192
export const isUserConnected = ( uid : string ) => {
171
193
return userConnections . has ( uid ) ;
172
194
} ;
173
195
174
- const endMatchOnUserDisconnect = (
175
- socket : Socket ,
176
- uid : string ,
177
- matchId : string | null
178
- ) => {
196
+ const endMatchOnUserDisconnect = ( socket : Socket , uid : string ) => {
179
197
userConnections . delete ( uid ) ;
198
+ const matchId = getMatchIdByUid ( uid ) ;
180
199
if ( matchId ) {
181
200
const matchDeleted = handleMatchDelete ( matchId ) ;
182
201
if ( matchDeleted ) {
183
- socket . to ( matchId ) . emit ( MATCH_UNSUCCESSFUL ) ; // on matching page
184
- socket . to ( matchId ) . emit ( MATCH_ENDED ) ; // on collab page
202
+ socket . to ( matchId ) . emit ( MatchEvents . MATCH_UNSUCCESSFUL ) ; // on matching page
203
+ socket . to ( matchId ) . emit ( MatchEvents . MATCH_ENDED ) ; // on collab page
185
204
}
186
205
}
187
206
} ;
0 commit comments