'Execute on_message, returning its Future if it is a coroutine.'

def _handle_message(self, opcode, data):

    if self.client_terminated:
        return
    if self._frame_compressed:
        data = self._decompressor.decompress(data)
    if (opcode == 1):
        self._message_bytes_in += len(data)
        try:
            decoded = data.decode('utf-8')
        except UnicodeDecodeError:
            self._abort()
            return
        return self._run_callback(self.handler.on_message, decoded)
    elif (opcode == 2):
        self._message_bytes_in += len(data)
        return self._run_callback(self.handler.on_message, data)
    elif (opcode == 8):
        self.client_terminated = True
        if (len(data) >= 2):
            self.handler.close_code = struct.unpack('>H', data[:2])[0]
        if (len(data) > 2):
            self.handler.close_reason = to_unicode(data[2:])
        self.close(self.handler.close_code)
    elif (opcode == 9):
        try:
            self._write_frame(True, 10, data)
        except StreamClosedError:
            self._abort()
        self._run_callback(self.handler.on_ping, data)
    elif (opcode == 10):
        self.last_pong = IOLoop.current().time()
        return self._run_callback(self.handler.on_pong, data)
    else:
        self._abort()
