Skip to content

Commit

Permalink
Merge pull request soernt#6 from kattalo/master
Browse files Browse the repository at this point in the history
Adding support for flutter for web and fixing bug with connectionToken in url query
  • Loading branch information
sefidgaran authored Jun 27, 2021
2 parents 0279ffa + 669084f commit e0a44a7
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 185 deletions.
18 changes: 13 additions & 5 deletions example/lib/chatPageViewModel.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:io';

import 'package:http/http.dart';
import 'package:signalr_netcore/signalr_client.dart';

import 'main.dart';
Expand Down Expand Up @@ -73,17 +73,16 @@ class ChatPageViewModel extends ViewModel {
print(msg.message);
}

void _httpClientCreateCallback(HttpClient httpClient) {
httpClient.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
void _httpClientCreateCallback(Client httpClient) {
HttpOverrides.global = HttpOverrideCertificateVerificationInDev();
}

Future<void> openChatConnection() async {
final logger = _logger;

if (_hubConnection == null) {
final httpConnectionOptions = new HttpConnectionOptions(
httpClient: DartIOHttpClient(logger,
httpClient: WebSupportingHttpClient(logger,
httpClientCreateCallback: _httpClientCreateCallback),
logger: logger,
logMessageContent: true);
Expand Down Expand Up @@ -141,3 +140,12 @@ class ChatPageViewModelProvider extends ViewModelProvider<ChatPageViewModel> {
.viewModel;
}
}

class HttpOverrideCertificateVerificationInDev extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
5 changes: 2 additions & 3 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ dependencies:

signalr_netcore:
path: ../

logging: ^1.0.1
w3c_event_source: ^1.0.0
rxdart : ^0.18.1
rxdart : ^0.18.1

# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
Expand Down
3 changes: 3 additions & 0 deletions lib/clients/http_client_browser.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'package:http/browser_client.dart';

final clientWithWebSupport = BrowserClient()..withCredentials = true;
3 changes: 3 additions & 0 deletions lib/clients/http_client_default.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import 'package:http/http.dart';

final clientWithWebSupport = Client();
116 changes: 0 additions & 116 deletions lib/dartio_http_client.dart

This file was deleted.

2 changes: 1 addition & 1 deletion lib/handshake_protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class HandshakeProtocol {

// Handshake request is always JSON
String writeHandshakeRequest(HandshakeRequestMessage handshakeRequest) {
return TextMessageFormat.write(json.encode(handshakeRequest));
return TextMessageFormat.write(json.encode(handshakeRequest.toJson()));
}

/// Parse the handshake reponse
Expand Down
20 changes: 11 additions & 9 deletions lib/http_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'dart:typed_data';

import 'package:logging/logging.dart';

import 'dartio_http_client.dart';
import 'web_supporting_http_client.dart';
import 'errors.dart';
import 'http_connection_options.dart';
import 'iconnection.dart';
Expand Down Expand Up @@ -133,7 +133,7 @@ class TransportSendQueue {

Future<void> stop() {
_executing = false;
_sendBufferedData.complete();
if (!_sendBufferedData.isCompleted) _sendBufferedData.complete();
return _sendLoopPromise;
}

Expand All @@ -149,7 +149,7 @@ class TransportSendQueue {
}

_buffer.add(data);
_sendBufferedData.complete();
if (!_sendBufferedData.isCompleted) _sendBufferedData.complete();
}

Future<void> _sendLoop() async {
Expand All @@ -158,7 +158,9 @@ class TransportSendQueue {

if (!_executing) {
if (_transportResult != null) {
_transportResult.completeError("Connection stopped.");
if (!_transportResult.isCompleted) {
_transportResult.completeError('Connection stopped.');
}
}

break;
Expand All @@ -177,9 +179,9 @@ class TransportSendQueue {

try {
await this.transport.send(data);
transportResult.complete();
if (!transportResult.isCompleted) transportResult.complete();
} catch (error) {
transportResult.completeError(error);
if (!transportResult.isCompleted) transportResult.completeError(error);
}
}
}
Expand Down Expand Up @@ -237,7 +239,7 @@ class HttpConnection implements IConnection {
baseUrl = url;

_options = options ?? HttpConnectionOptions();
_httpClient = options.httpClient ?? DartIOHttpClient(_logger);
_httpClient = options.httpClient ?? WebSupportingHttpClient(_logger);
_connectionState = ConnectionState.Disconnected;
_connectionStarted = false;
}
Expand Down Expand Up @@ -486,7 +488,7 @@ class HttpConnection implements IConnection {
}

String _createConnectUrl(String url, String connectionToken) {
if (connectionToken != null) {
if (connectionToken == null) {
return url;
}

Expand Down Expand Up @@ -646,7 +648,7 @@ class HttpConnection implements IConnection {
if (_connectionState == ConnectionState.Disconnecting) {
// A call to stop() induced this call to stopConnection and needs to be completed.
// Any stop() awaiters will be scheduled to continue after the onclose callback fires.
_stopPromiseCompleter.complete();
if (!_stopPromiseCompleter.isCompleted) _stopPromiseCompleter.complete();
}

if (error != null) {
Expand Down
36 changes: 23 additions & 13 deletions lib/hub_connection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -397,25 +397,31 @@ class HubConnection {
_callbacks[invocationDescriptor.invocationId] =
(HubMessageBase invocationEvent, Exception error) {
if (error != null) {
completer.completeError(error);
if (!completer.isCompleted) completer.completeError(error);
return;
} else if (invocationEvent != null) {
if (invocationEvent is CompletionMessage) {
if (invocationEvent.error != null) {
completer.completeError(new GeneralError(invocationEvent.error));
if (!completer.isCompleted) {
completer.completeError(new GeneralError(invocationEvent.error));
}
} else {
completer.complete(invocationEvent.result);
if (!completer.isCompleted) {
completer.complete(invocationEvent.result);
}
}
} else {
completer.completeError(new GeneralError(
"Unexpected message type: ${invocationEvent.type}"));
if (!completer.isCompleted) {
completer.completeError(new GeneralError(
"Unexpected message type: ${invocationEvent.type}"));
}
}
}
};

final promiseQueue =
_sendWithProtocol(invocationDescriptor).catchError((e) {
completer.completeError(e);
if (!completer.isCompleted) completer.completeError(e);
// invocationId will always have a value for a non-blocking invocation
_callbacks.remove(invocationDescriptor.invocationId);
});
Expand Down Expand Up @@ -548,7 +554,7 @@ class HubConnection {
_logger?.info("Close message received from server.");
final closeMessage = message as CloseMessage;

final error = closeMessage.error != null
final Exception error = closeMessage.error != null
? GeneralError(
"Server returned an error on close: " + closeMessage.error)
: null;
Expand Down Expand Up @@ -586,7 +592,9 @@ class HubConnection {

final error = GeneralError(message);

_handshakeCompleter?.completeError(error);
if (!_handshakeCompleter.isCompleted) {
_handshakeCompleter?.completeError(error);
}
_handshakeCompleter = null;
throw error;
}
Expand All @@ -597,14 +605,16 @@ class HubConnection {

final error = GeneralError(message);

_handshakeCompleter?.completeError(error);
if (!_handshakeCompleter.isCompleted) {
_handshakeCompleter?.completeError(error);
}
_handshakeCompleter = null;
throw error;
} else {
_logger?.finer("Server handshake complete.");
}

_handshakeCompleter?.complete();
if (!_handshakeCompleter.isCompleted) _handshakeCompleter?.complete();
_handshakeCompleter = null;
return handshakeResult.remainingData;
}
Expand Down Expand Up @@ -656,7 +666,7 @@ class HubConnection {
_logger?.severe(message);

// We don't need to wait on this Promise.
_stopPromise = _stopInternal(error: new GeneralError(message));
_stopPromise = _stopInternal(error: GeneralError(message));
}
} else {
_logger?.warning(
Expand All @@ -677,7 +687,7 @@ class HubConnection {
// If the handshake is in progress, start will be waiting for the handshake promise, so we complete it.
// If it has already completed, this should just noop.
if (_handshakeCompleter != null) {
_handshakeCompleter.complete();
if (!_handshakeCompleter.isCompleted) _handshakeCompleter.complete();
}

_cancelCallbacksWithError(error ??
Expand Down Expand Up @@ -720,7 +730,7 @@ class HubConnection {
_reconnect({Exception error}) async {
final reconnectStartTime = DateTime.now();
var previousReconnectAttempts = 0;
var retryError = error != null
Exception retryError = error != null
? error
: GeneralError("Attempting to reconnect due to a unknown error.");

Expand Down
14 changes: 14 additions & 0 deletions lib/ihub_protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class MessageHeaders {
HashMap<String, String> _headers;

Iterable<String> get names => _headers.keys;
HashMap<String, String> get asMap => _headers;

bool get isEmtpy => _headers.length == 0;

Expand All @@ -89,6 +90,19 @@ class MessageHeaders {
_headers.remove(name);
}
}

@override
String toString() {
if (isEmtpy) return '(no headers)';

String str = '';
for (var name in names) {
if (str.isNotEmpty) str += ', ';
str += '{ $name: ${_headers[name]} }';
}

return str;
}
}

/// Defines properties common to all Hub messages.
Expand Down
Loading

0 comments on commit e0a44a7

Please sign in to comment.