Improve signalR protocol compatibility

This commit is contained in:
Nutcake 2023-09-29 13:17:17 +02:00
parent 04ae0687f8
commit f305fcd23c
5 changed files with 58 additions and 105 deletions

View file

@ -7,7 +7,7 @@ import 'package:contacts_plus_plus/models/users/user.dart';
import 'package:contacts_plus_plus/models/users/user_profile.dart';
import 'package:contacts_plus_plus/models/users/user_status.dart';
class FriendApi {
class ContactApi {
static Future<List<Friend>> getFriendsList(ApiClient client, {DateTime? lastStatusUpdate}) async {
final response = await client.get("/users/${client.userId}/contacts${lastStatusUpdate != null ? "?lastStatusUpdate=${lastStatusUpdate.toUtc().toIso8601String()}" : ""}");
client.checkResponse(response);

View file

@ -7,7 +7,7 @@ import 'package:flutter/widgets.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:logging/logging.dart';
import 'package:contacts_plus_plus/apis/friend_api.dart';
import 'package:contacts_plus_plus/apis/contact_api.dart';
import 'package:contacts_plus_plus/apis/message_api.dart';
import 'package:contacts_plus_plus/apis/user_api.dart';
import 'package:contacts_plus_plus/clients/notification_client.dart';
@ -15,16 +15,17 @@ import 'package:contacts_plus_plus/models/users/friend.dart';
import 'package:contacts_plus_plus/clients/api_client.dart';
import 'package:contacts_plus_plus/config.dart';
import 'package:contacts_plus_plus/models/message.dart';
import 'package:uuid/uuid.dart';
enum EventType {
unknown,
message,
unknown1,
unknown2,
unknown3,
unknown4,
keepAlive,
error;
undefined,
invocation,
streamItem,
completion,
streamInvocation,
cancelInvocation,
ping,
close;
}
enum EventTarget {
@ -32,7 +33,9 @@ enum EventTarget {
messageSent,
receiveMessage,
messagesRead,
receiveSessionUpdate;
receiveSessionUpdate,
removeSession,
receiveStatusUpdate;
factory EventTarget.parse(String? text) {
if (text == null) return EventTarget.unknown;
@ -127,7 +130,7 @@ class MessagingClient extends ChangeNotifier {
_autoRefresh?.cancel();
_autoRefresh = Timer(_autoRefreshDuration, () => refreshFriendsList());
final friends = await FriendApi.getFriendsList(_apiClient, lastStatusUpdate: lastUpdateUtc);
final friends = await ContactApi.getFriendsList(_apiClient, lastStatusUpdate: lastUpdateUtc);
for (final friend in friends) {
await _updateFriend(friend);
}
@ -136,16 +139,9 @@ class MessagingClient extends ChangeNotifier {
notifyListeners();
}
void sendMessage(Message message) async {
void sendMessage(Message message) {
final msgBody = message.toMap();
final data = {
"type": EventType.message.index,
"target": "SendMessage",
"arguments": [
msgBody
],
};
_sendData(data);
_send("SendMessage", body: msgBody);
final cache = getUserMessageCache(message.recipientId) ?? _createUserMessageCache(message.recipientId);
cache.addMessage(message);
notifyListeners();
@ -153,14 +149,7 @@ class MessagingClient extends ChangeNotifier {
void markMessagesRead(MarkReadBatch batch) {
final msgBody = batch.toMap();
final data = {
"type": EventType.message.index,
"target": "MarkMessagesRead",
"arguments": [
msgBody
],
};
_sendData(data);
_send("MarkMessagesRead", body: msgBody);
clearUnreadsForUser(batch.senderId);
}
@ -281,6 +270,7 @@ class MessagingClient extends ChangeNotifier {
_wsChannel!.done.then((error) => _onDisconnected(error));
_wsChannel!.listen(_handleEvent, onDone: () => _onDisconnected("Connection closed."), onError: _onDisconnected);
_wsChannel!.add(_negotiationPacket);
_send("InitializeStatus");
}
Future<WebSocket> _tryConnect() async {
@ -301,34 +291,38 @@ class MessagingClient extends ChangeNotifier {
void _handleEvent(event) {
final body = jsonDecode((event.toString().replaceAll(_eofChar, "")));
final int rawType = body["type"] ?? 0;
final int? rawType = body["type"];
if (rawType == null) {
_logger.warning("Received empty event, content was $event");
return;
}
if (rawType > EventType.values.length) {
_logger.info("Unhandled event type $rawType: $body");
return;
}
switch (EventType.values[rawType]) {
case EventType.unknown1:
case EventType.unknown2:
case EventType.unknown3:
case EventType.unknown4:
case EventType.unknown:
_logger.info("Received unknown event: $rawType: $body");
case EventType.streamItem:
case EventType.completion:
case EventType.streamInvocation:
case EventType.cancelInvocation:
case EventType.undefined:
_logger.info("Received unhandled event: $rawType: $body");
break;
case EventType.message:
_logger.info("Received message-event.");
_handleMessageEvent(body);
case EventType.invocation:
_logger.info("Received invocation-event.");
_handleInvocation(body);
break;
case EventType.keepAlive:
case EventType.ping:
_logger.info("Received keep-alive.");
break;
case EventType.error:
_logger.severe("Received error-event: ${body["error"]}");
case EventType.close:
_logger.severe("Received close-event: ${body["error"]}");
// Should we trigger a manual reconnect here or just let the remote service close the connection?
break;
}
}
void _handleMessageEvent(body) async {
void _handleInvocation(body) async {
final target = EventTarget.parse(body["target"]);
final args = body["arguments"];
switch (target) {
@ -366,15 +360,31 @@ class MessagingClient extends ChangeNotifier {
}
notifyListeners();
break;
case EventTarget.receiveStatusUpdate:
break;
case EventTarget.removeSession:
case EventTarget.receiveSessionUpdate:
// TODO: Handle session updates
_logger.info("Received session update");
_logger.info("Received unhandled invocation event.");
break;
}
}
void _sendData(data) {
String _send(String target, {Map? body}) {
final invocationId = const Uuid().v4();
final data = {
"type": EventType.invocation.index,
"invocationId": invocationId,
"target": target,
"arguments": [
if (body != null)
body
],
};
if (_wsChannel == null) throw "Neos Hub is not connected";
_wsChannel!.add(jsonEncode(data)+_eofChar);
return invocationId;
}
}

View file

@ -1,4 +1,4 @@
import 'package:contacts_plus_plus/apis/friend_api.dart';
import 'package:contacts_plus_plus/apis/contact_api.dart';
import 'package:contacts_plus_plus/auxiliary.dart';
import 'package:contacts_plus_plus/client_holder.dart';
import 'package:contacts_plus_plus/models/users/user.dart';
@ -55,11 +55,11 @@ class _UserListTileState extends State<UserListTile> {
});
try {
if (_localAdded) {
await FriendApi.removeUserAsFriend(ClientHolder
await ContactApi.removeUserAsFriend(ClientHolder
.of(context)
.apiClient, user: widget.user);
} else {
await FriendApi.addUserAsFriend(ClientHolder
await ContactApi.addUserAsFriend(ClientHolder
.of(context)
.apiClient, user: widget.user);
}

View file

@ -504,14 +504,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.0"
message_pack_dart:
dependency: transitive
description:
name: message_pack_dart
sha256: "71b9f0ff60e5896e60b337960bb535380d7dba3297b457ac763ccae807385b59"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
meta:
dependency: transitive
description:
@ -688,14 +680,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pool:
dependency: transitive
description:
name: pool
sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
url: "https://pub.dev"
source: hosted
version: "1.5.1"
process:
dependency: transitive
description:
@ -776,22 +760,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.27.7"
shelf:
dependency: transitive
description:
name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
url: "https://pub.dev"
source: hosted
version: "1.4.1"
signalr_netcore:
dependency: "direct main"
description:
name: signalr_netcore
sha256: "8f84b4b516c03f3a6872f94e9729d1441d5d223a77c81d0a7d7dae5dd0ce1f2f"
url: "https://pub.dev"
source: hosted
version: "1.3.6"
sky_engine:
dependency: transitive
description: flutter
@ -821,22 +789,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.5"
sse:
dependency: transitive
description:
name: sse
sha256: "3ff9088cac3f45aa8b91336f1962e3ea6c81baaba0bbba361c05f8aa7fb59442"
url: "https://pub.dev"
source: hosted
version: "4.1.2"
sse_channel:
dependency: transitive
description:
name: sse_channel
sha256: ba2b1382b9423c58fa83e1f01a3a40fbaa16a0594aa984870c88bad0b45d4ca4
url: "https://pub.dev"
source: hosted
version: "0.0.3"
stack_trace:
dependency: transitive
description:
@ -901,14 +853,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.9.2"
tuple:
dependency: transitive
description:
name: tuple
sha256: a97ce2013f240b2f3807bcbaf218765b6f301c3eff91092bcfa23a039e7dd151
url: "https://pub.dev"
source: hosted
version: "2.0.2"
typed_data:
dependency: transitive
description:

View file

@ -38,7 +38,6 @@ dependencies:
flutter_secure_storage: ^8.0.0
intl: ^0.18.1
path: ^1.8.2
signalr_netcore: ^1.3.6
logging: ^1.1.1
cached_network_image: ^3.2.3
web_socket_channel: ^2.4.0