'Close Websocket object
status: status code to send. see STATUS_XXX.
reason: the reason to close. This must be string.'

def close(self, status=STATUS_NORMAL, reason=six.b('')):

    if self.connected:
        if ((status < 0) or (status >= ABNF.LENGTH_16)):
            raise ValueError('code    is    invalid    range')
        try:
            self.connected = False
            self.send((struct.pack('!H', status) + reason), ABNF.OPCODE_CLOSE)
            timeout = self.sock.gettimeout()
            self.sock.settimeout(3)
            try:
                frame = self.recv_frame()
                if isEnabledForError():
                    recv_status = struct.unpack('!H', frame.data)[0]
                    if (recv_status != STATUS_NORMAL):
                        error(('close    status:    ' + repr(recv_status)))
            except:
                pass
            self.sock.settimeout(timeout)
            self.sock.shutdown(socket.SHUT_RDWR)
        except:
            pass
    self.shutdown()
