or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdregular-adapter.mdsharded-adapter.mdutilities.md

sharded-adapter.mddocs/

0

# Sharded Redis Adapter

1

2

Advanced Redis adapter implementation utilizing Redis 7.0+ sharded pub/sub features for improved scalability and performance. Sharded pub/sub helps scale Socket.IO applications by distributing channel load across Redis cluster nodes.

3

4

## Capabilities

5

6

### Create Sharded Adapter

7

8

Creates a sharded Redis adapter factory function optimized for Redis 7.0+ sharded pub/sub.

9

10

```typescript { .api }

11

/**

12

* Creates a sharded Redis adapter factory using Redis 7.0+ sharded pub/sub

13

* @param pubClient - Redis client used to publish (from the 'redis' package)

14

* @param subClient - Redis client used to subscribe (from the 'redis' package)

15

* @param opts - Optional configuration options

16

* @returns Function that creates ShardedRedisAdapter instances for namespaces

17

*/

18

function createShardedAdapter(

19

pubClient: any,

20

subClient: any,

21

opts?: ShardedRedisAdapterOptions

22

): (nsp: any) => ShardedRedisAdapter;

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

import { Server } from "socket.io";

29

import { createClient } from "redis";

30

import { createShardedAdapter } from "@socket.io/redis-adapter";

31

32

// Basic sharded adapter setup

33

const pubClient = createClient({ host: "localhost", port: 6379 });

34

const subClient = pubClient.duplicate();

35

36

await Promise.all([

37

pubClient.connect(),

38

subClient.connect()

39

]);

40

41

const io = new Server({

42

adapter: createShardedAdapter(pubClient, subClient)

43

});

44

45

io.listen(3000);

46

47

// With custom options

48

const io2 = new Server({

49

adapter: createShardedAdapter(pubClient, subClient, {

50

channelPrefix: "my-app",

51

subscriptionMode: "dynamic-private"

52

})

53

});

54

```

55

56

### ShardedRedisAdapter Class

57

58

Main sharded adapter implementation that extends ClusterAdapter with Redis sharded pub/sub functionality.

59

60

```typescript { .api }

61

/**

62

* Sharded Redis adapter class using Redis 7.0+ sharded pub/sub features

63

* Extends ClusterAdapter from socket.io-adapter

64

*/

65

class ShardedRedisAdapter extends ClusterAdapter {

66

/**

67

* Create a new ShardedRedisAdapter instance

68

* @param nsp - Socket.IO namespace

69

* @param pubClient - Redis client for publishing

70

* @param subClient - Redis client for subscribing

71

* @param opts - Configuration options

72

*/

73

constructor(

74

nsp: any,

75

pubClient: any,

76

subClient: any,

77

opts?: ShardedRedisAdapterOptions

78

);

79

}

80

```

81

82

### Publishing Methods

83

84

Methods for publishing messages through sharded channels.

85

86

```typescript { .api }

87

/**

88

* Publishes a cluster message to appropriate sharded channel

89

* @param message - Message to publish

90

* @returns Promise resolving to offset (empty string for Redis)

91

*/

92

doPublish(message: ClusterMessage): Promise<Offset>;

93

94

/**

95

* Publishes a response to the requesting server's specific channel

96

* @param requesterUid - Unique ID of the requesting server

97

* @param response - Response message to send

98

* @returns Promise that resolves when message is published

99

*/

100

doPublishResponse(

101

requesterUid: string,

102

response: ClusterResponse

103

): Promise<void>;

104

```

105

106

### Server Management

107

108

Methods for managing server connections and counts.

109

110

```typescript { .api }

111

/**

112

* Gets the count of servers using sharded pub/sub

113

* Uses SHARDNUMSUB command for accurate server counting

114

* @returns Promise resolving to number of connected servers

115

*/

116

serverCount(): Promise<number>;

117

```

118

119

### Lifecycle Management

120

121

Methods for managing the sharded adapter lifecycle.

122

123

```typescript { .api }

124

/**

125

* Closes the sharded adapter and cleans up all subscriptions

126

* Unsubscribes from base channels and dynamic room channels

127

* @returns Promise that resolves when cleanup is complete

128

*/

129

close(): Promise<void>;

130

```

131

132

## Configuration Options

133

134

```typescript { .api }

135

interface ShardedRedisAdapterOptions {

136

/**

137

* The prefix for Redis Pub/Sub channels

138

* @default "socket.io"

139

*/

140

channelPrefix?: string;

141

142

/**

143

* Subscription mode that impacts the number of channels used:

144

*

145

* - "static": 2 channels per namespace

146

* Useful with dynamic namespaces

147

*

148

* - "dynamic": (2 + 1 per public room) channels per namespace

149

* Default value, optimal when some rooms have few clients

150

* Only creates channels for public rooms (not Socket IDs)

151

*

152

* - "dynamic-private": Like "dynamic" but includes private rooms

153

* Creates separate channels for Socket ID rooms

154

* Useful for lots of 1:1 communication via socket.emit()

155

*

156

* @default "dynamic"

157

*/

158

subscriptionMode?: "static" | "dynamic" | "dynamic-private";

159

}

160

```

161

162

## Subscription Modes Explained

163

164

### Static Mode

165

- **Channels**: 2 per namespace

166

- **Use Case**: Dynamic namespaces with unpredictable room patterns

167

- **Pros**: Predictable channel count, simple setup

168

- **Cons**: All messages go through same channels, less optimization

169

170

### Dynamic Mode (Default)

171

- **Channels**: 2 base + 1 per public room

172

- **Use Case**: Applications with some rooms having few clients

173

- **Pros**: Optimized delivery, servers only get relevant room messages

174

- **Cons**: More channels to manage

175

- **Note**: Only public rooms get separate channels, not Socket ID rooms

176

177

### Dynamic Private Mode

178

- **Channels**: 2 base + 1 per room (including private/Socket ID rooms)

179

- **Use Case**: Heavy 1:1 communication patterns

180

- **Pros**: Maximum optimization for direct socket communication

181

- **Cons**: Highest channel count, more subscription overhead

182

183

## Usage Examples

184

185

### Basic Sharded Setup

186

187

```typescript

188

import { createClient } from "redis";

189

import { Server } from "socket.io";

190

import { createShardedAdapter } from "@socket.io/redis-adapter";

191

192

const pubClient = createClient({ url: "redis://localhost:6379" });

193

const subClient = pubClient.duplicate();

194

195

await Promise.all([

196

pubClient.connect(),

197

subClient.connect()

198

]);

199

200

const io = new Server({

201

adapter: createShardedAdapter(pubClient, subClient)

202

});

203

204

// All Socket.IO operations work the same

205

io.emit("broadcast", "Hello everyone!");

206

io.to("room1").emit("room-message", "Hello room1!");

207

```

208

209

### Advanced Configuration

210

211

```typescript

212

const io = new Server({

213

adapter: createShardedAdapter(pubClient, subClient, {

214

channelPrefix: "my-game",

215

subscriptionMode: "dynamic-private" // Optimize for 1:1 messaging

216

})

217

});

218

219

// Efficient for direct socket communication

220

io.to(socketId).emit("private-message", "Hello specific user!");

221

```

222

223

### Room-based Broadcasting

224

225

```typescript

226

// With dynamic mode, each room gets its own optimized channel

227

io.to("lobby").emit("player-joined", { playerId: 123 });

228

io.to("game-room-1").emit("game-update", gameState);

229

230

// Servers not subscribed to these specific rooms won't receive these messages

231

```

232

233

## Requirements and Limitations

234

235

### Minimum Requirements

236

- **Redis**: Version 7.0 or higher

237

- **redis package**: Version 4.6.0 or higher

238

- **Node.js**: Version 10.0.0 or higher

239

240

### Limitations

241

- **ioredis with Redis Cluster**: Not currently supported for sharded adapter

242

- **Redis Clients**: Only the `redis` package is supported, not `ioredis`

243

- **Backward Compatibility**: Cannot mix sharded and regular adapters in same deployment

244

245

### Redis Commands Used

246

- **SPUBLISH**: For publishing to sharded channels

247

- **SSUBSCRIBE/SUNSUBSCRIBE**: For managing sharded subscriptions

248

- **SHARDNUMSUB**: For counting subscribers to sharded channels

249

250

## Migration from Regular Adapter

251

252

When migrating from the regular Redis adapter to the sharded adapter:

253

254

1. **Ensure Redis 7.0+**: Verify your Redis version supports sharded pub/sub

255

2. **Update Redis Client**: Use `redis` package v4.6.0+

256

3. **Change Import**: Switch from `createAdapter` to `createShardedAdapter`

257

4. **Update Configuration**: Review subscription mode for your use case

258

5. **Test Thoroughly**: Sharded pub/sub has different delivery patterns

259

260

```typescript

261

// Before (regular adapter)

262

import { createAdapter } from "@socket.io/redis-adapter";

263

const adapter = createAdapter(pubClient, subClient, {

264

key: "my-app"

265

});

266

267

// After (sharded adapter)

268

import { createShardedAdapter } from "@socket.io/redis-adapter";

269

const adapter = createShardedAdapter(pubClient, subClient, {

270

channelPrefix: "my-app",

271

subscriptionMode: "dynamic"

272

});

273

```