Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

Commit d162e54

Browse filesBrowse files
committed
Change ServiceBrowser interface experimentally
1 parent 7cad7a4 commit d162e54
Copy full SHA for d162e54

File tree

Expand file treeCollapse file tree

2 files changed

+63
-20
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+63
-20
lines changed

‎examples/browser.py

Copy file name to clipboardExpand all lines: examples/browser.py
+7-12Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,14 @@
77
import socket
88
from time import sleep
99

10-
from zeroconf import ServiceBrowser, Zeroconf
10+
from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf
1111

1212

13-
class MyListener(object):
13+
def on_service_state_change(zeroconf, service_type, name, state_change):
14+
print("Service %s of type %s state changed: %s" % (name, service_type, state_change))
1415

15-
def remove_service(self, zeroconf, type, name):
16-
print("Service %s removed" % (name,))
17-
print('\n')
18-
19-
def add_service(self, zeroconf, type, name):
20-
print("Service %s added" % (name,))
21-
print(" Type is %s" % (type,))
22-
info = zeroconf.get_service_info(type, name)
16+
if state_change is ServiceStateChange.Added:
17+
info = zeroconf.get_service_info(service_type, name)
2318
if info:
2419
print(" Address is %s:%d" % (socket.inet_ntoa(info.address),
2520
info.port))
@@ -40,8 +35,8 @@ def add_service(self, zeroconf, type, name):
4035

4136
zeroconf = Zeroconf()
4237
print("\nBrowsing services, press Ctrl-C to exit...\n")
43-
listener = MyListener()
44-
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
38+
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", handlers=[on_service_state_change])
39+
4540
try:
4641
while True:
4742
sleep(0.1)

‎zeroconf.py

Copy file name to clipboardExpand all lines: zeroconf.py
+56-8Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def emit(self, record):
5353

5454
__all__ = [
5555
"Zeroconf", "ServiceInfo", "ServiceBrowser",
56-
"Error", "InterfaceChoice",
56+
"Error", "InterfaceChoice", "ServiceStateChange",
5757
]
5858

5959

@@ -921,6 +921,33 @@ def run(self):
921921
self.zc.cache.remove(record)
922922

923923

924+
class Signal(object):
925+
def __init__(self):
926+
self._handlers = []
927+
928+
def fire(self, **kwargs):
929+
for h in list(self._handlers):
930+
h(**kwargs)
931+
932+
@property
933+
def registration_interface(self):
934+
return SignalRegistrationInterface(self._handlers)
935+
936+
937+
class SignalRegistrationInterface(object):
938+
939+
def __init__(self, handlers):
940+
self._handlers = handlers
941+
942+
def register_handler(self, handler):
943+
self._handlers.append(handler)
944+
return self
945+
946+
def unregister_handler(self, handler):
947+
self._handlers.remove(handler)
948+
return self
949+
950+
924951
class ServiceBrowser(threading.Thread):
925952

926953
"""Used to browse for a service of a specific type.
@@ -929,13 +956,12 @@ class ServiceBrowser(threading.Thread):
929956
remove_service() methods called when this browser
930957
discovers changes in the services availability."""
931958

932-
def __init__(self, zc, type, listener):
959+
def __init__(self, zc, type_, handlers):
933960
"""Creates a browser for a specific type"""
934961
threading.Thread.__init__(self)
935962
self.daemon = True
936963
self.zc = zc
937-
self.type = type
938-
self.listener = listener
964+
self.type = type_
939965
self.services = {}
940966
self.next_time = current_time_millis()
941967
self.delay = _BROWSER_TIME
@@ -946,10 +972,28 @@ def __init__(self, zc, type, listener):
946972
self.zc.add_listener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
947973
self.start()
948974

975+
self._service_state_changed = Signal()
976+
for h in handlers:
977+
self.service_state_changed.register_handler(h)
978+
979+
@property
980+
def service_state_changed(self):
981+
return self._service_state_changed.registration_interface
982+
949983
def update_record(self, zc, now, record):
950984
"""Callback invoked by Zeroconf when new information arrives.
951985
952986
Updates information required by browser in the Zeroconf cache."""
987+
988+
def enqueue_callback(state_change, name):
989+
self._handlers_to_call.append(
990+
lambda zeroconf: self._service_state_changed.fire(
991+
zeroconf=zeroconf,
992+
service_type=self.type,
993+
name=name,
994+
state_change=state_change,
995+
))
996+
953997
if record.type == _TYPE_PTR and record.name == self.type:
954998
expired = record.is_expired(now)
955999
service_key = record.alias.lower()
@@ -958,15 +1002,13 @@ def update_record(self, zc, now, record):
9581002
except KeyError:
9591003
if not expired:
9601004
self.services[service_key] = record
961-
self._handlers_to_call.append(
962-
lambda x: self.listener.add_service(x, self.type, record.alias))
1005+
enqueue_callback(ServiceStateChange.Added, record.alias)
9631006
else:
9641007
if not expired:
9651008
old_record.reset_ttl(record)
9661009
else:
9671010
del self.services[service_key]
968-
self._handlers_to_call.append(
969-
lambda x: self.listener.remove_service(x, self.type, record.alias))
1011+
enqueue_callback(ServiceStateChange.Removed, record.alias)
9701012
return
9711013

9721014
expires = record.get_expiration_time(75)
@@ -1197,6 +1239,12 @@ class InterfaceChoice(enum.Enum):
11971239
All = 2
11981240

11991241

1242+
@enum.unique
1243+
class ServiceStateChange(enum.Enum):
1244+
Added = 1
1245+
Removed = 2
1246+
1247+
12001248
HOST_ONLY_NETWORK_MASK = '255.255.255.255'
12011249

12021250

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.