Skip to content

Commit

Permalink
Merge pull request #1328 from julien4215/socket-batch
Browse files Browse the repository at this point in the history
Add socket batch event
  • Loading branch information
veloce authored Jan 9, 2025
2 parents 1e92fa8 + df0683b commit f4ef886
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 14 deletions.
33 changes: 23 additions & 10 deletions lib/src/network/socket.dart
Original file line number Diff line number Diff line change
Expand Up @@ -330,20 +330,23 @@ class SocketClient {
void _handleEvent(SocketEvent event) {
switch (event.topic) {
case '_pong':
_handlePong(pingDelay);
case 'n':
_handlePong(pingDelay);
continue addToStream;
case 'ack':
_onServerAck(event);
}

if (event != SocketEvent.pong && event.topic != 'ack') {
if (_streamController.hasListener) {
_streamController.add(event);
}
if (_globalStreamController.hasListener &&
_globalSocketStreamAllowedTopics.contains(event.topic)) {
_globalStreamController.add(event);
}
case 'batch':
_handleBatch(event);
addToStream:
case _:
if (_streamController.hasListener) {
_streamController.add(event);
}
if (_globalStreamController.hasListener &&
_globalSocketStreamAllowedTopics.contains(event.topic)) {
_globalStreamController.add(event);
}
}
}

Expand Down Expand Up @@ -407,6 +410,16 @@ class SocketClient {
}
}
}

void _handleBatch(SocketEvent batchEvent) {
final jsonEventList = batchEvent.data as List<dynamic>;

for (final jsonEvent in jsonEventList) {
final event = SocketEvent.fromJson(jsonEvent as Map<String, dynamic>);

_streamController.add(event);
}
}
}

/// Service that manages a pool of socket clients.
Expand Down
1 change: 0 additions & 1 deletion test/network/fake_websocket_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class FakeWebSocketChannel implements WebSocketChannel {
for (final message in messages) {
_incomingController.add(message);
}
// await _incomingController.addStream(Stream<dynamic>.fromIterable(messages));
}

@override
Expand Down
80 changes: 77 additions & 3 deletions test/network/socket_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:lichess_mobile/src/model/common/socket.dart';
import 'package:lichess_mobile/src/network/socket.dart';
import 'package:package_info_plus/package_info_plus.dart';

Expand Down Expand Up @@ -175,9 +176,7 @@ void main() {
final fakeChannel = FakeWebSocketChannel();

final socketClient = makeTestSocketClient(FakeWebSocketChannelFactory((_) => fakeChannel));
socketClient.connect();

await socketClient.firstConnection;
await socketClient.connect();

// send a message that requires an ack
socketClient.send('test', {'data': 'ackable'}, ackable: true);
Expand All @@ -200,5 +199,80 @@ void main() {

socketClient.close();
});

test('handles batch message', () async {
final fakeChannel = FakeWebSocketChannel();

final socketClient = makeTestSocketClient(FakeWebSocketChannelFactory((_) => fakeChannel));
await socketClient.connect();

const serverMessage = '''
{
"t":"batch",
"d":[
{"t":"test1","d":"data"},
{"t":"test2","d":"data"},
{"t":"test3","d":"data"}
]
}
''';

const eventsToMatch = [
SocketEvent(topic: 'test1', data: 'data'),
SocketEvent(topic: 'test2', data: 'data'),
SocketEvent(topic: 'test3', data: 'data'),
];

// check that the messages in the batch were distributed
await testEventEmitted(socketClient, fakeChannel, serverMessage, eventsToMatch);

await socketClient.close();
});
});

test('should emit events', () async {
final fakeChannel = FakeWebSocketChannel();

final socketClient = makeTestSocketClient(FakeWebSocketChannelFactory((_) => fakeChannel));
await socketClient.connect();

// should not emit if _pong
await testEventEmitted(socketClient, fakeChannel, '0', []);

// should emit if n
const pongMessage = '{"t":"n","d":10,"r":3}';
const pongEvent = SocketEvent(topic: 'n', data: {'nbPlayers': 10, 'nbGames': 3});
await testEventEmitted(socketClient, fakeChannel, pongMessage, [pongEvent]);

// should not emit if ack
const ackMessage = '{"t":"n","d":10,"r":3}';
await testEventEmitted(socketClient, fakeChannel, ackMessage, []);

// should not emit if batch
const batchMessage = '{"t":"batch","d":[]}';
await testEventEmitted(socketClient, fakeChannel, batchMessage, []);

// should emit if random topic
const randomMessage = '{"t":"test","d":"data"}';
const randomEvent = SocketEvent(topic: 'test', data: 'data');
await testEventEmitted(socketClient, fakeChannel, randomMessage, [randomEvent]);

await socketClient.close();
});
}

Future<void> testEventEmitted(
SocketClient socketClient,
FakeWebSocketChannel fakeChannel,
String serverMessage,
Iterable<SocketEvent> eventsToMatch,
) async {
// start listening to the stream
final futureExpect = expectLater(socketClient.stream, emitsInOrder(eventsToMatch));

// server sends the message
fakeChannel.addIncomingMessages([serverMessage]);

// check that the socket events were emitted in order
await futureExpect;
}

0 comments on commit f4ef886

Please sign in to comment.