mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Ensure Simulator publishes mDNS records (#6696)
* Ensure Simulator publishes mDNS records on loopback interface.
This commit is contained in:
parent
d9c2b215ab
commit
d8672baaa2
@ -4,6 +4,16 @@
|
||||
|
||||
#define FML_USED_ON_EMBEDDER
|
||||
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
// NSNetService works fine on physical devices, but doesn't expose the services to regular mDNS
|
||||
// queries on the Simulator. We can work around this by using the lower level C API, but that's
|
||||
// only available from iOS 9.3+/macOS 10.11.4+.
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
#include <dns_sd.h> // nogncheck
|
||||
#include <net/if.h> // nogncheck
|
||||
#endif // TARGET_IPHONE_SIMLUATOR
|
||||
|
||||
#import "FlutterObservatoryPublisher.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
@ -26,7 +36,11 @@
|
||||
@end
|
||||
|
||||
@implementation FlutterObservatoryPublisher {
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
DNSServiceRef _dnsServiceRef;
|
||||
#else // TARGET_IPHONE_SIMULATOR
|
||||
fml::scoped_nsobject<NSNetService> _netService;
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
|
||||
blink::DartServiceIsolate::CallbackHandle _callbackHandle;
|
||||
std::unique_ptr<fml::WeakPtrFactory<FlutterObservatoryPublisher>> _weakFactory;
|
||||
@ -54,14 +68,29 @@
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
if (_dnsServiceRef) {
|
||||
DNSServiceRefDeallocate(_dnsServiceRef);
|
||||
_dnsServiceRef = NULL;
|
||||
}
|
||||
#else // TARGET_IPHONE_SIMULATOR
|
||||
[_netService.get() stop];
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
|
||||
blink::DartServiceIsolate::RemoveServerStatusCallback(std::move(_callbackHandle));
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)publishServiceProtocolPort:(std::string)uri {
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
if (_dnsServiceRef) {
|
||||
DNSServiceRefDeallocate(_dnsServiceRef);
|
||||
_dnsServiceRef = NULL;
|
||||
}
|
||||
#else // TARGET_IPHONE_SIMULATOR
|
||||
[_netService.get() stop];
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
if (uri.empty()) {
|
||||
[_netService.get() stop];
|
||||
return;
|
||||
}
|
||||
// uri comes in as something like 'http://127.0.0.1:XXXXX/' where XXXXX is the port
|
||||
@ -69,28 +98,37 @@
|
||||
NSURL* url =
|
||||
[[[NSURL alloc] initWithString:[NSString stringWithUTF8String:uri.c_str()]] autorelease];
|
||||
|
||||
// DNS name has to be a max of 63 bytes. Prefer to cut off the app name rather than
|
||||
// the device hostName. e.g. 'io.flutter.example@someones-iphone', or
|
||||
// 'ongAppNameBecauseThisCouldHappenAtSomePoint@somelongname-iphone'
|
||||
NSString* serviceName = [NSString
|
||||
stringWithFormat:@"%@@%@",
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"],
|
||||
[NSProcessInfo processInfo].hostName];
|
||||
if ([serviceName length] > 63) {
|
||||
serviceName = [serviceName substringFromIndex:[serviceName length] - 63];
|
||||
}
|
||||
NSString* serviceName =
|
||||
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
DNSServiceFlags flags = kDNSServiceFlagsDefault;
|
||||
uint32_t interfaceIndex = if_nametoindex("lo0");
|
||||
const char* registrationType = "_dartobservatory._tcp";
|
||||
const char* domain = "local."; // default domain
|
||||
uint16_t port = [[url port] intValue];
|
||||
|
||||
int err = DNSServiceRegister(&_dnsServiceRef, flags, interfaceIndex, [serviceName UTF8String],
|
||||
registrationType, domain, NULL, htons(port), 0, NULL,
|
||||
registrationCallback, NULL);
|
||||
|
||||
if (err != 0) {
|
||||
FML_LOG(ERROR) << "Failed to register observatory port with mDNS.";
|
||||
} else {
|
||||
DNSServiceProcessResult(_dnsServiceRef);
|
||||
}
|
||||
#else // TARGET_IPHONE_SIMULATOR
|
||||
_netService.reset([[NSNetService alloc] initWithDomain:@"local."
|
||||
type:@"_dartobservatory._tcp."
|
||||
name:serviceName
|
||||
port:[[url port] intValue]]);
|
||||
|
||||
[_netService.get() setDelegate:self];
|
||||
[_netService.get() publish];
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
}
|
||||
|
||||
- (void)netServiceDidPublish:(NSNetService*)sender {
|
||||
FML_DLOG(INFO) << "FlutterObservatoryPublisher is ready!";
|
||||
FML_LOG(INFO) << "FlutterObservatoryPublisher is ready!";
|
||||
}
|
||||
|
||||
- (void)netService:(NSNetService*)sender didNotPublish:(NSDictionary*)errorDict {
|
||||
@ -98,6 +136,23 @@
|
||||
"network settings and relaunch the application.";
|
||||
}
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
static void DNSSD_API registrationCallback(DNSServiceRef sdRef,
|
||||
DNSServiceFlags flags,
|
||||
DNSServiceErrorType errorCode,
|
||||
const char* name,
|
||||
const char* regType,
|
||||
const char* domain,
|
||||
void* context) {
|
||||
if (errorCode == kDNSServiceErr_NoError) {
|
||||
FML_LOG(ERROR) << "FlutterObservatoryPublisher is ready!";
|
||||
} else {
|
||||
FML_LOG(ERROR) << "Could not register as server for FlutterObservatoryPublisher. Check your "
|
||||
"network settings and relaunch the application.";
|
||||
}
|
||||
}
|
||||
#endif // TARGET_IPHONE_SIMULATOR
|
||||
|
||||
#endif // FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE && FLUTTER_RUNTIME_MODE !=
|
||||
// FLUTTER_RUNTIME_MODE_DYNAMIC_RELEASE
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user