xmpp: Make stream resumption send the last h value
This commit is contained in:
parent
d3bc449ced
commit
af89387b3b
@ -89,6 +89,7 @@ class XmppConnection {
|
||||
// final List<String> _serverFeatures = List.empty(growable: true);
|
||||
late RoutingState _routingState;
|
||||
late String _resource;
|
||||
late String _dataBuffer;
|
||||
|
||||
// Negotiators
|
||||
late final AuthenticationNegotiator _authenticator;
|
||||
@ -106,6 +107,7 @@ class XmppConnection {
|
||||
|
||||
this._eventStreamController = StreamController();
|
||||
this._resource = "";
|
||||
this._dataBuffer = "";
|
||||
}
|
||||
|
||||
// Returns true if the stream supports the XMLNS @feature.
|
||||
@ -169,22 +171,33 @@ class XmppConnection {
|
||||
}
|
||||
|
||||
void _filterOutStreamBegin(data, EventSink sink) {
|
||||
if (data.startsWith("<?xml version='1.0'?>")) {
|
||||
data = data.substring(21);
|
||||
String toParse = this._dataBuffer + data;
|
||||
if (toParse.startsWith("<?xml version='1.0'?>")) {
|
||||
toParse = toParse.substring(21);
|
||||
}
|
||||
|
||||
if (data.startsWith("<stream:stream")) {
|
||||
data = data + "</stream:stream>";
|
||||
if (toParse.startsWith("<stream:stream")) {
|
||||
toParse = toParse + "</stream:stream>";
|
||||
} else {
|
||||
if (data.endsWith("</stream:stream>")) {
|
||||
if (toParse.endsWith("</stream:stream>")) {
|
||||
// TODO: Maybe destroy the stream
|
||||
data = data.substring(0, data.length - 16);
|
||||
toParse = toParse.substring(0, toParse.length - 16);
|
||||
}
|
||||
}
|
||||
|
||||
XmlDocument
|
||||
.parse("<root>$data</root>")
|
||||
.getElement("root")!
|
||||
// TODO: Test this
|
||||
final document;
|
||||
try {
|
||||
document = XmlDocument.parse("<root>$toParse</root>");
|
||||
this._dataBuffer = "";
|
||||
} catch (ex) {
|
||||
// TODO: Maybe don't just assume that we haven't received everything, i.e. check the
|
||||
// error message
|
||||
this._dataBuffer = this._dataBuffer + data;
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElement("root")!
|
||||
.childElements
|
||||
.forEach((element) => sink.add(XMLNode.fromXmlElement(element)));
|
||||
}
|
||||
@ -344,7 +357,7 @@ class XmppConnection {
|
||||
// Try to resume the last stream
|
||||
// TODO
|
||||
this._routingState = RoutingState.PERFORM_STREAM_RESUMPTION;
|
||||
this.sendRawXML(StreamManagementResumeNonza(this.settings.streamResumptionId!, 0 /*TODO*/));
|
||||
this.sendRawXML(StreamManagementResumeNonza(this.settings.streamResumptionId!, this.settings.lasth!));
|
||||
} else {
|
||||
// Try to enable SM
|
||||
this._routingState = RoutingState.BIND_RESOURCE_PRE_SM;
|
||||
@ -368,6 +381,7 @@ class XmppConnection {
|
||||
// TODO: Synchronize the h values
|
||||
if (node.tag == "resumed") {
|
||||
print("Stream Resumption successful!");
|
||||
this.sendEvent(StreamManagementResumptionSuccessfulEvent());
|
||||
this._resource = this.settings.resource!;
|
||||
this._routingState = RoutingState.HANDLE_STANZAS;
|
||||
this._setConnectionState(ConnectionState.CONNECTED);
|
||||
@ -390,7 +404,7 @@ class XmppConnection {
|
||||
final id = node.attributes["id"];
|
||||
if (id != null && [ "true", "1" ].indexOf(node.attributes["resume"]) != -1) {
|
||||
print("Stream resumption possible!");
|
||||
this.sendEvent(StreamResumptionEvent(id: id, resource: this._resource));
|
||||
this.sendEvent(StreamManagementEnabledEvent(id: id, resource: this._resource));
|
||||
}
|
||||
|
||||
this.streamManager = StreamManager(connection: this, streamResumptionId: id);
|
||||
|
@ -33,9 +33,20 @@ class ChatMarkerEvent extends XmppEvent {
|
||||
}
|
||||
|
||||
// Triggered when we received a Stream resumption ID
|
||||
class StreamResumptionEvent extends XmppEvent {
|
||||
// TODO: Make the id optional since a server doesn't have to support resumption
|
||||
class StreamManagementEnabledEvent extends XmppEvent {
|
||||
final String resource;
|
||||
final String id;
|
||||
|
||||
StreamResumptionEvent({ required this.id, required this.resource });
|
||||
StreamManagementEnabledEvent({ required this.id, required this.resource });
|
||||
}
|
||||
|
||||
// Triggered when we send out an ack
|
||||
class StreamManagementAckSentEvent extends XmppEvent {
|
||||
final int h;
|
||||
|
||||
StreamManagementAckSentEvent({ required this.h });
|
||||
}
|
||||
|
||||
// Triggered when we were able to successfully resume a stream
|
||||
class StreamManagementResumptionSuccessfulEvent extends XmppEvent {}
|
||||
|
@ -6,7 +6,8 @@ class ConnectionSettings {
|
||||
final bool useDirectTLS;
|
||||
final bool allowPlainAuth;
|
||||
final String? streamResumptionId;
|
||||
final int? lasth;
|
||||
final String? resource;
|
||||
|
||||
ConnectionSettings({ required this.jid, required this.password, required this.useDirectTLS, required this.allowPlainAuth, this.streamResumptionId, this.resource });
|
||||
ConnectionSettings({ required this.jid, required this.password, required this.useDirectTLS, required this.allowPlainAuth, this.streamResumptionId, this.resource, this.lasth });
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import "dart:collection";
|
||||
import "dart:math";
|
||||
|
||||
import "package:moxxyv2/xmpp/events.dart";
|
||||
import "package:moxxyv2/xmpp/stanzas/stanza.dart";
|
||||
import "package:moxxyv2/xmpp/nonzas/sm.dart";
|
||||
import "package:moxxyv2/xmpp/connection.dart";
|
||||
@ -21,6 +22,7 @@ class StreamManager {
|
||||
bool canResume() => this.streamResumptionId != "";
|
||||
|
||||
void handleAckRequest() {
|
||||
this.connection.sendEvent(StreamManagementAckSentEvent(h: this._serverStanzaSeq - 1));
|
||||
this.connection.sendRawXML(StreamManagementAckNonza(this._serverStanzaSeq - 1));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user