1717struct Client {
1818 conn : @socket .Tcp
1919 rand : @random .Rand
20- mut closed : CloseCode ?
20+ mut closed : WebSocketError ?
2121}
2222
2323///|
@@ -139,39 +139,44 @@ pub async fn Client::connect(
139139pub fn Client ::close (self : Client ) -> Unit {
140140 if self .closed is None {
141141 self .conn.close ()
142- self .closed = Some (Normal )
142+ self .closed = Some (ConnectionClosed ( Normal , None ) )
143143 }
144144}
145145
146146///|
147147pub async fn Client ::send_close (
148148 self : Client ,
149149 code ? : CloseCode = Normal ,
150- reason ? : BytesView = "" ,
150+ reason ? : String ,
151151) -> Unit {
152152 if self .closed is Some (_ ) {
153153 return
154154 }
155155 let mut payload = FixedArray ::make (0 , b '\x00 ' )
156156 let code_int = code .to_int ()
157- payload = FixedArray ::make (2 + reason .length (), b '\x00 ' )
157+ let reason_bytes = if reason is Some (r ) {
158+ @encoding/utf8 .encode (r )
159+ } else {
160+ b ""
161+ }
162+ payload = FixedArray ::make (2 + reason_bytes .length (), b '\x00 ' )
158163 payload .unsafe_write_uint16_be (0 , code_int .to_uint16 ())
159- payload .blit_from_bytesview (2 , reason )
164+ payload .blit_from_bytesview (2 , reason_bytes )
160165 write_frame (
161166 self .conn,
162167 true ,
163168 OpCode ::Close ,
164169 payload .unsafe_reinterpret_as_bytes (),
165170 self .rand.int ().to_be_bytes (),
166171 )
167- self .closed = Some (code )
172+ self .closed = Some (ConnectionClosed ( code , reason ) )
168173}
169174
170175///|
171176/// Send a text message
172177pub async fn Client ::send_text (self : Client , text : String ) -> Unit {
173178 if self .closed is Some (code ) {
174- raise ConnectionClosed ( code )
179+ raise code
175180 }
176181 let payload = @encoding/utf8 .encode (text )
177182 write_frame (
@@ -187,7 +192,7 @@ pub async fn Client::send_text(self : Client, text : String) -> Unit {
187192/// Send a binary message
188193pub async fn Client ::send_binary (self : Client , data : Bytes ) -> Unit {
189194 if self .closed is Some (code ) {
190- raise ConnectionClosed ( code )
195+ raise code
191196 }
192197 write_frame (
193198 self .conn,
@@ -205,7 +210,7 @@ pub async fn Client::send_binary(self : Client, data : Bytes) -> Unit {
205210/// indicating if a pong was received within a timeout
206211async fn Client ::_ping (self : Client , data ? : Bytes = Bytes ::new (0 )) -> Unit {
207212 if self .closed is Some (code ) {
208- raise ConnectionClosed ( code )
213+ raise code
209214 }
210215 write_frame (
211216 self .conn,
@@ -222,7 +227,7 @@ async fn Client::_ping(self : Client, data? : Bytes = Bytes::new(0)) -> Unit {
222227/// This is done automatically, so it is not exposed in the public API
223228async fn Client ::pong (self : Client , data ? : Bytes = Bytes ::new (0 )) -> Unit {
224229 if self .closed is Some (code ) {
225- raise ConnectionClosed ( code )
230+ raise code
226231 }
227232 write_frame (
228233 self .conn,
@@ -238,7 +243,7 @@ async fn Client::pong(self : Client, data? : Bytes = Bytes::new(0)) -> Unit {
238243/// Returns the complete message after assembling all frames
239244pub async fn Client ::receive (self : Client ) -> Message {
240245 if self .closed is Some (code ) {
241- raise ConnectionClosed ( code )
246+ raise code
242247 }
243248 let frames : Array [Frame ] = []
244249 let mut first_opcode : OpCode? = None
@@ -250,18 +255,20 @@ pub async fn Client::receive(self : Client) -> Message {
250255 OpCode ::Close => {
251256 // Parse close code and reason
252257 let mut close_code = Normal
253- if frame .payload.length () >= 2 {
254- let payload_arr = frame .payload.to_fixedarray ()
255- let code_int = (payload_arr [0 ].to_int () << 8 ) |
256- payload_arr [1 ].to_int ()
257- close_code = CloseCode ::from_int (code_int ) catch {
258- FrameError =>
259- // Invalid close code, use ProtocolError
260- ProtocolError
261- }
258+ let mut reason : String? = None
259+ if frame .payload is [u16be (code ), .. data ] {
260+ close_code = CloseCode ::from_int (code .reinterpret_as_int ())
261+ reason = Some (
262+ @encoding/utf8 .decode (data ) catch {
263+ _ => {
264+ close_code = ProtocolError
265+ ""
266+ }
267+ },
268+ )
262269 }
263- self .closed = Some (close_code )
264- raise ConnectionClosed (close_code )
270+ self .closed = Some (ConnectionClosed ( close_code , reason ) )
271+ raise ConnectionClosed (close_code , reason )
265272 }
266273 OpCode ::Ping => {
267274 // Auto-respond to ping with pong
0 commit comments