Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebSocket: call close() won't trigger onclose handler?

I am reading Andrew Lombardi's book "WebSocket", it said that

You can manually trigger calling the onclose event by exe‐ cuting the close() method on a WebSocket object,

page 15

but when I call close() method, it didn't trigger onclose event...

on Chrome: when call close(), server stop sending frames, and after a few seconds (6-7 seconds maybe), my onclose handler was invoked.

on iOS 11: when call close(), server stop sending frames, but onclose handler never invoked.

So, what's the truth of websocket close event?

my demo app code in React

import React, { Component } from 'react'
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      log: [],
    }
    this.ws = null
  }

  render() {
    return (
      <div>
        <button type="button" onClick={this._open}>
          open
        </button>
        <button type="button" onClick={this._close}>
          close
        </button>

        <div
          style={{
            padding: 10,
            backgroundColor: '#ddd'
          }}
        >
          {this.state.log.map((item, index) => {
            return <div key={index}>{item}</div>
          })}
        </div>
      </div>
    )
  }

  _open = () => {
    this.ws = new WebSocket('wss://cmb.100jc.net/answer/ws')
    this.ws.onopen = () => {
      alert('open')
      this.setState(prevState => {
        return {
          log: prevState.log.concat('open')
        }
      })
    }
    this.ws.onclose = () => {
      alert('close')
      this.setState(prevState => {
        return {
          log: prevState.log.concat('close')
        }
      })
    }
    this.ws.onerror = () => {
      this.setState(prevState => {
        return {
          log: prevState.log.concat('error')
        }
      })
    }
  }

  _close = () => {
    this.ws.close()
  }
}

export default App
like image 893
Littlee Avatar asked Nov 18 '22 21:11

Littlee


1 Answers

the close() method attempts to perform graceful shutdown of the websocket. It waits closeTimeout seconds (default is 30 seconds) before actually shutting down the socket, during which the other peer can sand a close frame. After this period, the socket closes and the event is emitted. You can read more on this in this great stack overflow answer.

like image 193
omer Avatar answered Feb 12 '23 20:02

omer