1
1
import { v4 } from 'https://deno.land/std@0.76.0/uuid/mod.ts' ;
2
- import {
3
- isWebSocketCloseEvent ,
4
- isWebSocketPingEvent ,
5
- WebSocket ,
6
- } from 'https://deno.land/std@0.76.0/ws/mod.ts' ;
2
+ import { isWebSocketCloseEvent , WebSocket } from '../common/Dependency.ts' ;
7
3
8
4
import {
9
5
GetConnections ,
@@ -18,12 +14,21 @@ import { UPPERCASE_USERNAMES } from './Configuration.ts';
18
14
19
15
type FileInfo = { data : string ; name : string } ;
20
16
const UserFiles : Map < string , FileInfo > = new Map ( ) ;
17
+ const enum MsgStatus {
18
+ OK = 'OK' ,
19
+ NOK = 'NOK' ,
20
+ INVALID = 'INVALID' ,
21
+ USERNAME_INVALID = 'USERNAME_INVALID' ,
22
+ USERNAME_IN_USE = 'USERNAME_IN_USE' ,
23
+ NOT_IN_CHAT = 'NOT_IN_CHAT' ,
24
+ ALREADY_IN_CHAT = 'ALREADY_IN_CHAT' ,
25
+ }
21
26
22
27
/**
23
28
* h: Handler
24
29
* s: Sender
25
30
* d: Data
26
- * r: Response status
31
+ * r: Message status
27
32
*/
28
33
type WSMsgJoin = { h : 'join' ; d : string } ;
29
34
type WSMsgLeave = { h : 'leave' ; d : string } ;
@@ -40,13 +45,14 @@ type WSMessageClient =
40
45
| WSMsgGetUsers
41
46
| WSMsgSendFiles ;
42
47
43
- type WSMsgConnectResp = { h : 'connectResp' ; d : string ; r : string } ;
44
- type WSMsgJoinResp = { h : 'joinResp' ; s : string ; r : string } ;
45
- type WSMsgLeaveResp = { h : 'leaveResp' ; r : string } ;
46
- type WSMsgChatResp = { h : 'chatResp' ; d : string ; r : string } ;
48
+ type WSMsgConnectResp = { h : 'connectResp' ; d : string ; r : MsgStatus } ;
49
+ type WSMsgJoinResp = { h : 'joinResp' ; s : string ; r : MsgStatus } ;
50
+ type WSMsgLeaveResp = { h : 'leaveResp' ; r : MsgStatus } ;
51
+ type WSMsgChatResp = { h : 'chatResp' ; d : string ; r : MsgStatus } ;
47
52
type WSMsgGetUsersResp = {
48
53
h : 'getUsersResp' ;
49
54
userList : Array < string > ;
55
+ r : MsgStatus ;
50
56
} ;
51
57
type WSMsgSendFilesResp = {
52
58
h : 'sendFilesResp' ;
@@ -67,48 +73,88 @@ export async function HandleWSConn(pWebSocket: WebSocket): Promise<void> {
67
73
const { id : _connId , conn : _conn } = _connInfo ;
68
74
console . log ( `Socket connected! :: ${ _connId } ` ) ;
69
75
try {
70
- await RespondeConnect ( _connInfo , 'OK' ) ;
76
+ await RespondeConnect ( _connInfo , MsgStatus . OK ) ;
71
77
for await ( const event of pWebSocket ) {
72
78
if ( typeof event === 'string' ) {
73
79
const objEvent : WSMessage = JSON . parse ( event ) ;
74
80
switch ( objEvent . h ) {
75
81
case 'join' : {
76
- const _name = UPPERCASE_USERNAMES
77
- ? objEvent . d . toUpperCase ( )
78
- : objEvent . d ;
79
- if ( ! / ^ [ a - z A - Z 0 - 9 ] + $ / i. test ( _name ) ) {
80
- await RespondJoin ( _connInfo , 'Invalid username' ) ;
81
- } else if ( await FindConnByName ( _name ) ) {
82
+ if ( ! _conn . state ) {
83
+ const _name = UPPERCASE_USERNAMES
84
+ ? objEvent . d . toUpperCase ( )
85
+ : objEvent . d ;
86
+ if ( ! / ^ [ a - z A - Z 0 - 9 ] + $ / i. test ( _name ) ) {
87
+ await RespondJoin (
88
+ _connInfo ,
89
+ MsgStatus . USERNAME_INVALID
90
+ ) ;
91
+ } else if ( await FindConnByName ( _name ) ) {
92
+ await RespondJoin (
93
+ _connInfo ,
94
+ MsgStatus . USERNAME_IN_USE
95
+ ) ;
96
+ } else {
97
+ _conn . state = true ;
98
+ _conn . name = _name ;
99
+ await BroadcastJoin ( _connInfo ) ;
100
+ await RespondJoin ( _connInfo , MsgStatus . OK ) ;
101
+ }
102
+ } else {
82
103
await RespondJoin (
83
104
_connInfo ,
84
- 'Username already in use'
105
+ MsgStatus . ALREADY_IN_CHAT
85
106
) ;
86
- } else {
87
- _conn . state = true ;
88
- _conn . name = _name ;
89
- await BroadcastJoin ( _connInfo ) ;
90
- await RespondJoin ( _connInfo , 'OK' ) ;
91
107
}
92
108
break ;
93
109
}
94
110
case 'leave' : {
95
- await BroadcastLeave ( _connInfo ) ;
96
- _conn . name = '' ;
97
- _conn . state = false ;
98
- await RespondLeave ( _connInfo , 'OK' ) ;
111
+ if ( _conn . state ) {
112
+ await BroadcastLeave ( _connInfo ) ;
113
+ _conn . name = '' ;
114
+ _conn . state = false ;
115
+ await RespondLeave ( _connInfo , MsgStatus . OK ) ;
116
+ } else {
117
+ await RespondLeave (
118
+ _connInfo ,
119
+ MsgStatus . NOT_IN_CHAT
120
+ ) ;
121
+ }
99
122
break ;
100
123
}
101
124
case 'chat' : {
102
- if ( _connInfo . conn . state ) {
125
+ if ( _conn . state ) {
103
126
await BroadcastChat ( _connInfo , objEvent . d ) ;
104
- await RespondChat ( _connInfo , 'OK' , objEvent . d ) ;
127
+ await RespondChat (
128
+ _connInfo ,
129
+ MsgStatus . OK ,
130
+ objEvent . d
131
+ ) ;
105
132
} else {
106
- await RespondChat ( _connInfo , 'Invalid' , objEvent . d ) ;
133
+ await RespondChat (
134
+ _connInfo ,
135
+ MsgStatus . NOT_IN_CHAT ,
136
+ objEvent . d
137
+ ) ;
107
138
}
108
139
break ;
109
140
}
110
141
case 'getUsers' : {
111
- await RespondGetUsers ( _connInfo ) ;
142
+ if ( _conn . state ) {
143
+ const lUser = ( await GetConnections ( ) ) . map (
144
+ ( pConnection ) => pConnection . conn . name
145
+ ) ;
146
+ await RespondGetUsers (
147
+ _connInfo ,
148
+ lUser ,
149
+ MsgStatus . OK
150
+ ) ;
151
+ } else {
152
+ await RespondGetUsers (
153
+ _connInfo ,
154
+ [ ] ,
155
+ MsgStatus . NOT_IN_CHAT
156
+ ) ;
157
+ }
112
158
break ;
113
159
}
114
160
case 'sendFiles' : {
@@ -123,7 +169,7 @@ export async function HandleWSConn(pWebSocket: WebSocket): Promise<void> {
123
169
}
124
170
} else if ( isWebSocketCloseEvent ( event ) ) {
125
171
console . log ( `Socket disconnected! :: ${ _connId } ` ) ;
126
- if ( _connInfo . conn . state ) {
172
+ if ( _conn . state ) {
127
173
await BroadcastLeave ( _connInfo ) ;
128
174
}
129
175
await RemoveConnById ( _connId ) ;
@@ -139,7 +185,7 @@ export async function HandleWSConn(pWebSocket: WebSocket): Promise<void> {
139
185
}
140
186
}
141
187
142
- async function RespondeConnect ( pConnInfo : ConnInfo , pStatus : string ) {
188
+ async function RespondeConnect ( pConnInfo : ConnInfo , pStatus : MsgStatus ) {
143
189
const { id : _Id } = pConnInfo ;
144
190
return Respond ( pConnInfo , {
145
191
h : 'connectResp' ,
@@ -148,7 +194,7 @@ async function RespondeConnect(pConnInfo: ConnInfo, pStatus: string) {
148
194
} ) ;
149
195
}
150
196
151
- async function RespondJoin ( pConnInfo : ConnInfo , pStatus : string ) {
197
+ async function RespondJoin ( pConnInfo : ConnInfo , pStatus : MsgStatus ) {
152
198
const { id : _Id , conn : _Conn } = pConnInfo ;
153
199
const { name : _Name } = _Conn ;
154
200
return Respond ( pConnInfo , {
@@ -158,7 +204,7 @@ async function RespondJoin(pConnInfo: ConnInfo, pStatus: string) {
158
204
} ) ;
159
205
}
160
206
161
- async function RespondLeave ( pConnInfo : ConnInfo , pStatus : string ) {
207
+ async function RespondLeave ( pConnInfo : ConnInfo , pStatus : MsgStatus ) {
162
208
return Respond ( pConnInfo , {
163
209
h : 'leaveResp' ,
164
210
r : pStatus ,
@@ -167,7 +213,7 @@ async function RespondLeave(pConnInfo: ConnInfo, pStatus: string) {
167
213
168
214
async function RespondChat (
169
215
pConnInfo : ConnInfo ,
170
- pStatus : string ,
216
+ pStatus : MsgStatus ,
171
217
pChatMsg : string
172
218
) {
173
219
return Respond ( pConnInfo , {
@@ -177,12 +223,15 @@ async function RespondChat(
177
223
} ) ;
178
224
}
179
225
180
- async function RespondGetUsers ( pConnInfo : ConnInfo ) {
226
+ async function RespondGetUsers (
227
+ pConnInfo : ConnInfo ,
228
+ pListUser : Array < string > ,
229
+ pStatus : MsgStatus
230
+ ) {
181
231
return Respond ( pConnInfo , {
182
232
h : 'getUsersResp' ,
183
- userList : ( await GetConnections ( ) ) . map (
184
- ( pConnection ) => pConnection . conn . name
185
- ) ,
233
+ userList : pListUser ,
234
+ r : pStatus ,
186
235
} ) ;
187
236
}
188
237
0 commit comments