@@ -21,6 +21,8 @@ func WebsocketInject(ctx core.FilterContext, jsCtx *goja.Runtime, w http.Respons
2121 if err != nil {
2222 return nil , err
2323 }
24+ zap .L ().Debug ("websocket upgrader created" )
25+ closers .AddCloser (conn .Close )
2426 go func () {
2527 ticker := time .NewTicker (15 * time .Second )
2628 defer ticker .Stop ()
@@ -37,28 +39,7 @@ func WebsocketInject(ctx core.FilterContext, jsCtx *goja.Runtime, w http.Respons
3739 }
3840 }
3941 }()
40- zap .L ().Debug ("websocket upgrader created" )
41- closers .AddCloser (conn .Close )
4242 return map [string ]interface {}{
43- "on" : func (f func (mType int , message string )) {
44- go func () {
45- z:
46- for {
47- select {
48- case <- ctx .Done ():
49- break z
50- default :
51- messageType , p , err := conn .ReadMessage ()
52- if err != nil {
53- break z
54- }
55- f (messageType , string (p ))
56- }
57-
58- }
59-
60- }()
61- },
6243 "TypeTextMessage" : websocket .TextMessage ,
6344 "TypeBinaryMessage" : websocket .BinaryMessage ,
6445 "readText" : func () * goja.Promise {
@@ -91,36 +72,115 @@ func WebsocketInject(ctx core.FilterContext, jsCtx *goja.Runtime, w http.Respons
9172 }()
9273 return promise
9374 },
94- "read" : func () (any , error ) {
95- messageType , p , err := conn .ReadMessage ()
96- if err != nil {
97- return nil , err
98- }
99- return map [string ]interface {}{
100- "type" : messageType ,
101- "data" : p ,
102- }, nil
103- },
104- "writeText" : func (data string ) error {
105- return conn .WriteMessage (websocket .TextMessage , []byte (data ))
75+ "read" : func () * goja.Promise {
76+ promise , resolve , reject := jsCtx .NewPromise ()
77+ go func () {
78+ select {
79+ case <- ctx .Done ():
80+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
81+ _ = reject (runtime .ToValue (ctx .Err ()))
82+ })
83+ return
84+ default :
85+ }
86+ defer func () {
87+ if r := recover (); r != nil {
88+ zap .L ().Debug ("websocket panic" , zap .Any ("panic" , r ))
89+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
90+ _ = reject (runtime .ToValue (r ))
91+ })
92+ }
93+ }()
94+ messageType , p , err := conn .ReadMessage ()
95+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
96+ if err != nil {
97+ _ = reject (runtime .ToValue (err ))
98+ } else {
99+ _ = resolve (runtime .ToValue (map [string ]interface {}{
100+ "type" : messageType ,
101+ "data" : p ,
102+ }))
103+ }
104+ })
105+ }()
106+ return promise
106107 },
107- "write" : func (mType int , data any ) error {
108- if item , ok := data .(goja.Value ); ok {
109- data = item .Export ()
110- }
111- var dataRaw []byte
112- switch it := data .(type ) {
113- case []byte :
114- dataRaw = it
115- case string :
116- dataRaw = []byte (it )
117- default :
118- return errors .Errorf ("invalid type for websocket text: %T" , data )
119- }
120- return conn .WriteMessage (mType , dataRaw )
108+ "writeText" : func (data string ) * goja.Promise {
109+ promise , resolve , reject := jsCtx .NewPromise ()
110+ go func () {
111+ select {
112+ case <- ctx .Done ():
113+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
114+ _ = reject (runtime .ToValue (ctx .Err ()))
115+ })
116+ return
117+ default :
118+ }
119+ defer func () {
120+ if r := recover (); r != nil {
121+ zap .L ().Debug ("websocket panic" , zap .Any ("panic" , r ))
122+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
123+ _ = reject (runtime .ToValue (r ))
124+ })
125+ }
126+ }()
127+ err := conn .WriteMessage (websocket .TextMessage , []byte (data ))
128+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
129+ if err != nil {
130+ _ = reject (runtime .ToValue (err ))
131+ } else {
132+ _ = resolve (runtime .ToValue (nil ))
133+ }
134+ })
135+ }()
136+ return promise
121137 },
122- "ping" : func () error {
123- return conn .WriteControl (websocket .PingMessage , []byte {}, time .Now ().Add (1 * time .Second ))
138+ "write" : func (mType int , data any ) * goja.Promise {
139+ promise , resolve , reject := jsCtx .NewPromise ()
140+ go func () {
141+ select {
142+ case <- ctx .Done ():
143+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
144+ _ = reject (runtime .ToValue (ctx .Err ()))
145+ })
146+ return
147+ default :
148+ }
149+ defer func () {
150+ if r := recover (); r != nil {
151+ zap .L ().Debug ("websocket panic" , zap .Any ("panic" , r ))
152+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
153+ _ = reject (runtime .ToValue (r ))
154+ })
155+ }
156+ }()
157+
158+ if item , ok := data .(goja.Value ); ok {
159+ data = item .Export ()
160+ }
161+ var dataRaw []byte
162+ switch it := data .(type ) {
163+ case []byte :
164+ dataRaw = it
165+ case string :
166+ dataRaw = []byte (it )
167+ default :
168+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
169+ _ = reject (runtime .ToValue (errors .Errorf ("invalid type for websocket text: %T" , data )))
170+ })
171+ return
172+ }
173+
174+ err := conn .WriteMessage (mType , dataRaw )
175+ loop .RunOnLoop (func (runtime * goja.Runtime ) {
176+ if err != nil {
177+ _ = reject (runtime .ToValue (err ))
178+ } else {
179+ _ = resolve (goja .Undefined ())
180+ }
181+ })
182+ }()
183+ return promise
124184 },
125185 }, nil
126186 })
0 commit comments