VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/3.1-bolt-factory-and-protocol-negotiation

⇱ Bolt Factory and Protocol Negotiation | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Bolt Factory and Protocol Negotiation

Purpose and Scope

This document explains the Bolt factory class and the protocol negotiation mechanism that occurs during connection establishment. The factory is responsible for:

  • Establishing TCP connections to Neo4j/Memgraph databases
  • Performing the Bolt protocol handshake
  • Negotiating protocol versions with the server
  • Instantiating the appropriate AProtocol subclass based on negotiated version
  • Managing persistent connection recovery via cache

For details on individual protocol versions and their features, see Protocol Versions. For connection implementations, see Connection Management. For server state transitions after negotiation, see Server State Management.

Sources: src/Bolt.php1-262


Factory Pattern Overview

The Bolt class implements the factory pattern to abstract protocol version selection from the client application. It accepts an IConnection implementation and returns a configured AProtocol instance after successful negotiation.

Key Responsibilities

ResponsibilityImplementation
Connection establishmentDelegates to IConnection::connect()
Protocol handshakeSends magic bytes and version preferences
Version negotiationReads server's selected version from handshake response
Protocol instantiationCreates V1, V3, V4, V4_3, V5, or V6 instance
Persistent connection recoveryUses FileCache to restore interrupted sessions
Analytics trackingOptional usage telemetry (opt-out via BOLT_ANALYTICS_OPTOUT)

Sources: src/Bolt.php12-39


Protocol Negotiation Sequence


Sources: src/Bolt.php120-143 src/Bolt.php145-157 src/Bolt.php159-185 src/Bolt.php205-220


Handshake Protocol

The handshake follows the Bolt specification with a fixed structure:

Magic Bytes and Version Packing

The client sends 20 bytes total:

  • Bytes 0-3: Magic bytes 0x6060B017 (identifies Bolt protocol)
  • Bytes 4-19: Four 4-byte protocol version specifications (in preference order)

Version Encoding

Protocol versions are encoded as 4 bytes in little-endian order:

Version StringByte 3Byte 2Byte 1Byte 0Example Hex
1000100 00 00 01
3000300 00 00 03
4.4004400 00 04 04
5.8005800 00 05 08
6000600 00 00 06

Sources: src/Bolt.php240-261 src/Bolt.php223-238


Core Factory Methods

Building Protocol Instances

The build() method orchestrates the entire negotiation process:


Sources: src/Bolt.php120-143

Protocol Version Configuration

The setProtocolVersions() method accepts up to 4 version specifications:


The method ensures exactly 4 versions are sent (padding with 0 for unused slots):

Sources: src/Bolt.php37 src/Bolt.php187-193

Class Naming Convention

Protocol classes follow the naming pattern \Bolt\protocol\V{version} where dots in version numbers are replaced with underscores:

Server ResponseProtocol ClassFile Path
1\Bolt\protocol\V1src/protocol/V1.php
3\Bolt\protocol\V3src/protocol/V3.php
4.3\Bolt\protocol\V4_3src/protocol/V4_3.php
5.2\Bolt\protocol\V5_2src/protocol/V5_2.php
6\Bolt\protocol\V6src/protocol/V6.php

Sources: src/Bolt.php149-154 src/Bolt.php167-171


Initial Server State Assignment

After instantiation, the factory sets the initial serverState based on protocol version:


The determination logic:

  • V5.1+: ServerState::NEGOTIATION (requires separate LOGON message after HELLO)
  • V1-V4: ServerState::CONNECTED (authentication included in INIT or HELLO)
  • Persistent connections: ServerState::INTERRUPTED (requires RESET to resume)

Sources: src/Bolt.php155-156 src/Bolt.php174


Persistent Connection Recovery

For PStreamSocket connections, the factory implements an optimized path that avoids full handshake:

Cache-Based Recovery Flow


The cache key is the connection identifier from PStreamSocket::getIdentifier(), and the cached value is the protocol version string (e.g., "5.2"). The TTL is 15 minutes from last successful use.

Sources: src/Bolt.php138-140 src/Bolt.php159-185 src/connection/PStreamSocket.php1-50


Error Handling

The factory handles several error conditions during negotiation:

Connection Failures


All exceptions trigger disconnection via $this->connection->disconnect() before rethrowing.

Sources: src/Bolt.php124-136 src/Bolt.php213-217 src/Bolt.php216-218 src/Bolt.php150-152


Debug Mode

When Bolt::$debug is enabled, the factory outputs handshake diagnostics:


This static property affects all Bolt instances and can be used for troubleshooting connection issues.

Sources: src/Bolt.php26 src/Bolt.php207-208


Analytics Tracking Integration

The factory optionally tracks usage metrics unless opted out via the BOLT_ANALYTICS_OPTOUT environment variable:

Analytics Data Structure

The factory interacts with analytics in two places:

  1. Constructor: Triggers track() method to send pending analytics
  2. Cache updates: Reads/writes to analytics cache key

The cached analytics structure:


Analytics are transmitted to Mixpanel when data from previous days exists. The factory cleans transmitted data from the cache.

Sources: src/Bolt.php30-36 src/Bolt.php40-114


Usage Example


Sources: src/Bolt.php28 src/Bolt.php187-193 src/Bolt.php195-199 src/Bolt.php120


Related Components

Dependencies

The Bolt factory depends on:

ComponentPurposeReference
IConnectionTCP transport abstractionConnection Management
AProtocolProtocol message handlingAProtocol Base Class
CacheProviderPersistent connection cacheCaching and Analytics
ServerStateState machine enumServer State Management
SignatureMessage signature enumMessage Reference

Protocol Implementations

After negotiation, one of these classes is instantiated:

Sources: src/Bolt.php1-11 src/protocol/V1.php1-23 src/protocol/V3.php1-28 src/protocol/V4.php1-29 src/protocol/V4_3.php1-32