@@ -6,8 +6,10 @@ import { SocketTopics } from "../sockets/topics";
6
6
import { MessageType , MessageTypes } from "../types/messages.types" ;
7
7
import { ConnectionName } from "../sockets/connection.name" ;
8
8
9
- const sendHandshake = ( devtoolsAppConnection : WebSocket , connectionName : string ) => {
10
- devtoolsAppConnection . send (
9
+ // TODO - handle message with info about lostConnection for a given app when connection is lost on frontend side.
10
+
11
+ const initializeFrontendForConnection = ( devtoolsAppConnection : WebSocket , connectionName : string ) => {
12
+ devtoolsAppConnection ?. send (
11
13
JSON . stringify ( {
12
14
...{
13
15
topic : SocketTopics . DEVTOOLS_APP_MAIN_LISTENER ,
@@ -17,26 +19,38 @@ const sendHandshake = (devtoolsAppConnection: WebSocket, connectionName: string)
17
19
) ;
18
20
} ;
19
21
20
- // TODO - add heartbeat + cleanup of hangup connections.
22
+ const getConnectionName = ( requestUrl : string ) => {
23
+ const queryParams = url . parse ( requestUrl , true ) . query ;
24
+ const { connectionName } = ( queryParams || { } ) as { connectionName : string } ;
25
+ return connectionName ;
26
+ } ;
21
27
22
- const connections : Record < string , { ws : WebSocket ; handshake : "pending" | "sent" | "confirmed" ; events : any [ ] } > = { } ;
28
+ const connections : Record <
29
+ string ,
30
+ {
31
+ ws : WebSocket | null ;
32
+ frontendStatus : "pending" | "sent" | "initialized" ;
33
+ events : any [ ] ;
34
+ status : "connected" | "hangup" ;
35
+ }
36
+ > = { } ;
23
37
const addConnection = ( devtoolsAppConnection : WebSocket | null , connectionName : string , connection : WebSocket ) => {
24
38
if ( ! connections [ connectionName ] ) {
25
- connections [ connectionName ] = { ws : connection , handshake : "pending" , events : [ ] } ;
39
+ connections [ connectionName ] = { ws : connection , frontendStatus : "pending" , events : [ ] , status : "connected" } ;
26
40
} else {
27
41
connections [ connectionName ] . ws = connection ;
28
42
}
29
43
if ( devtoolsAppConnection ) {
30
- sendHandshake ( devtoolsAppConnection , connectionName ) ;
31
- connections [ connectionName ] . handshake = "sent" ;
44
+ initializeFrontendForConnection ( devtoolsAppConnection , connectionName ) ;
45
+ connections [ connectionName ] . frontendStatus = "sent" ;
32
46
}
33
47
} ;
34
48
35
- const sendPendingHandshakes = ( devtoolsAppConnection : WebSocket ) => {
49
+ const initializePendingFrontends = ( devtoolsAppConnection : WebSocket ) => {
36
50
Object . keys ( connections ) . forEach ( ( connectionName ) => {
37
- if ( connections [ connectionName ] . handshake === "pending" ) {
38
- sendHandshake ( devtoolsAppConnection , connectionName ) ;
39
- connections [ connectionName ] . handshake = "sent" ;
51
+ if ( connections [ connectionName ] . frontendStatus === "pending" ) {
52
+ initializeFrontendForConnection ( devtoolsAppConnection , connectionName ) ;
53
+ connections [ connectionName ] . frontendStatus = "sent" ;
40
54
}
41
55
} ) ;
42
56
} ;
@@ -53,22 +67,45 @@ export const startServer = async (port = 1234) => {
53
67
let DEVTOOLS_FRONTEND_WS_CONNECTION : WebSocket | null = null ;
54
68
55
69
wss . on ( "connection" , ( wsConn , request ) => {
56
- const queryParams = url . parse ( request . url ! , true ) . query ;
57
- const { connectionName } = queryParams as { connectionName : string } ;
70
+ const connectionName = getConnectionName ( request . url || "" ) ;
58
71
if ( ! connectionName ) {
59
72
console . error ( "MISSING CONNECTION NAME" , request . url ) ;
60
73
return ;
61
74
}
62
- // TODO HANDLE REFRESHING CONNECTION AND HANGUP
63
75
if ( connectionName && connectionName === ConnectionName . HF_DEVTOOLS_APP ) {
64
76
DEVTOOLS_FRONTEND_WS_CONNECTION = wsConn ;
65
- sendPendingHandshakes ( DEVTOOLS_FRONTEND_WS_CONNECTION ) ;
77
+ initializePendingFrontends ( DEVTOOLS_FRONTEND_WS_CONNECTION ) ;
66
78
}
67
79
if ( connectionName && ! Array . isArray ( connectionName ) && connectionName . startsWith ( "HF_DEVTOOLS_CLIENT" ) ) {
68
80
addConnection ( DEVTOOLS_FRONTEND_WS_CONNECTION , connectionName , wsConn ) ;
69
81
}
70
82
wsConn . on ( "error" , console . error ) ;
71
-
83
+ wsConn . on ( "close" , ( ) => {
84
+ const closedConnectionName = getConnectionName ( request . url || "" ) ;
85
+ if ( ! closedConnectionName ) {
86
+ return ;
87
+ }
88
+ if ( closedConnectionName === ConnectionName . HF_DEVTOOLS_APP ) {
89
+ DEVTOOLS_FRONTEND_WS_CONNECTION = null ;
90
+ }
91
+ if ( connections [ connectionName ] ) {
92
+ const hangupConnection = connections [ connectionName ] ;
93
+ hangupConnection . ws = null ;
94
+ hangupConnection . status = "hangup" ;
95
+ if ( ! DEVTOOLS_FRONTEND_WS_CONNECTION ) {
96
+ console . error ( `Something went wrong. Connection to devtools frontend and devtools plugin lost.` ) ;
97
+ return ;
98
+ }
99
+ DEVTOOLS_FRONTEND_WS_CONNECTION . send (
100
+ JSON . stringify ( {
101
+ ...{
102
+ topic : SocketTopics . DEVTOOLS_APP_MAIN_LISTENER ,
103
+ data : { messageType : MessageType . DEVTOOLS_CLIENT_HANGUP , connectionName } ,
104
+ } ,
105
+ } ) ,
106
+ ) ;
107
+ }
108
+ } ) ;
72
109
wsConn . on ( "message" , ( msg : MessageTypes ) => {
73
110
const message = JSON . parse ( msg . toString ( ) ) as MessageTypes ;
74
111
if ( ! DEVTOOLS_FRONTEND_WS_CONNECTION ) {
@@ -80,7 +117,7 @@ export const startServer = async (port = 1234) => {
80
117
case MessageType . HF_DEVTOOLS_EVENT : {
81
118
const { connectionName } = message . data ;
82
119
console . log ( "RECEIVED EVENT FROM DEVTOOLS" , message ) ;
83
- if ( connections [ connectionName ] ) {
120
+ if ( connections [ connectionName ] ?. ws ) {
84
121
connections [ connectionName ] . ws . send (
85
122
JSON . stringify ( { ...message , topic : SocketTopics . DEVTOOLS_PLUGIN_LISTENER } ) ,
86
123
) ;
@@ -93,15 +130,15 @@ export const startServer = async (port = 1234) => {
93
130
return ;
94
131
}
95
132
96
- connections [ message . data . connectionName ] . handshake = "confirmed " ;
133
+ connections [ message . data . connectionName ] . frontendStatus = "initialized " ;
97
134
const connectionEvents = connections [ message . data . connectionName ] ?. events ;
98
135
sendStoredEvents ( DEVTOOLS_FRONTEND_WS_CONNECTION , connectionEvents ) ;
99
136
100
137
return ;
101
138
}
102
139
case MessageType . HF_APP_EVENT : {
103
140
const conn = message . data . connectionName ;
104
- if ( connections [ conn ] ?. handshake && DEVTOOLS_FRONTEND_WS_CONNECTION ) {
141
+ if ( connections [ conn ] ?. frontendStatus && DEVTOOLS_FRONTEND_WS_CONNECTION ) {
105
142
DEVTOOLS_FRONTEND_WS_CONNECTION . send (
106
143
JSON . stringify ( { ...message , topic : SocketTopics . DEVTOOLS_APP_CLIENT_LISTENER } ) ,
107
144
) ;
0 commit comments