Skip to content

Commit 8a4c4f1

Browse files
authored
Merge pull request #70 from wpyoga/repeat-count
Allow user to customize Unicast and Multicast message repeat counts
2 parents 71fc01f + f8f3c63 commit 8a4c4f1

File tree

4 files changed

+77
-37
lines changed

4 files changed

+77
-37
lines changed

wsdiscovery/cmdline.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
from contextlib import contextmanager
44
from urllib.parse import urlparse
55
import click
6+
67
from wsdiscovery.discovery import ThreadedWSDiscovery as WSDiscovery
78
from wsdiscovery.publishing import ThreadedWSPublishing as WSPublishing
89
from wsdiscovery.scope import Scope
910
from wsdiscovery.qname import QName
1011
from wsdiscovery.discovery import DEFAULT_DISCOVERY_TIMEOUT
12+
from wsdiscovery.udp import UNICAST_UDP_REPEAT, MULTICAST_UDP_REPEAT
1113

1214
DEFAULT_LOGLEVEL = "INFO"
1315

1416
@contextmanager
15-
def discovery(capture=None):
16-
wsd = WSDiscovery(capture=capture)
17+
def discovery(capture=None, unicast_num=UNICAST_UDP_REPEAT,
18+
multicast_num=MULTICAST_UDP_REPEAT):
19+
wsd = WSDiscovery(capture=capture, unicast_num=unicast_num,
20+
multicast_num=multicast_num)
1721
wsd.start()
1822
yield wsd
1923
wsd.stop()
@@ -46,12 +50,17 @@ def setup_logger(name, loglevel):
4650
@click.option('--capture', '-c', nargs=1, type=click.File('w'), help='Capture messages to a file')
4751
@click.option('--timeout', '-t', default=DEFAULT_DISCOVERY_TIMEOUT, show_default=True,
4852
type=int, help='Discovery timeout in seconds')
49-
def discover(scope, address, port, loglevel, capture, timeout):
53+
@click.option('--unicast-num', '-un', type=int, default=UNICAST_UDP_REPEAT,
54+
show_default=True, help='Number of Unicast messages to send')
55+
@click.option('--multicast-num', '-mn', type=int, default=MULTICAST_UDP_REPEAT,
56+
show_default=True, help='Number of Multicast messages to send')
57+
def discover(scope, address, port, loglevel, capture, timeout, unicast_num,
58+
multicast_num):
5059
"Discover services using WS-Discovery"
5160

5261
logger = setup_logger("ws-discovery", loglevel)
5362

54-
with discovery(capture) as wsd:
63+
with discovery(capture, unicast_num, multicast_num) as wsd:
5564
scopes = [Scope(scope)] if scope else []
5665
svcs = wsd.searchServices(scopes=scopes, address=address, port=port,
5766
timeout=timeout)
@@ -71,7 +80,12 @@ def discover(scope, address, port, loglevel, capture, timeout):
7180
type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]),
7281
help='Log level')
7382
@click.option('--capture', '-c', nargs=1, type=click.File('w'), help='Capture messages to a file')
74-
def publish(scope, typename, address, port, loglevel, capture):
83+
@click.option('--unicast-num', '-un', type=int, default=UNICAST_UDP_REPEAT,
84+
show_default=True, help='Number of Unicast messages to send')
85+
@click.option('--multicast-num', '-mn', type=int, default=MULTICAST_UDP_REPEAT,
86+
show_default=True, help='Number of Multicast messages to send')
87+
def publish(scope, typename, address, port, loglevel, capture, unicast_num,
88+
multicast_num):
7589
"Publish services using WS-Discovery"
7690

7791
logger = setup_logger("ws-publishing", loglevel)
@@ -89,4 +103,3 @@ def publish(scope, typename, address, port, loglevel, capture):
89103

90104
xAddrs = ["%s:%i" % (address, port)] if address else ['127.0.0.1']
91105
svc = wsp.publishService(types, scopes, xAddrs)
92-

wsdiscovery/daemon.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from .uri import URI
1010
from .service import Service
1111
from .envelope import SoapEnvelope
12-
12+
from .udp import UNICAST_UDP_REPEAT, MULTICAST_UDP_REPEAT
1313

1414
APP_MAX_DELAY = 500 # miliseconds
1515

@@ -33,6 +33,8 @@ def __init__(self, uuid_=None, capture=None, ttl=1, **kwargs):
3333

3434
self._capture = capture
3535
self.ttl = ttl
36+
self._unicast_num = kwargs.get('unicast_num', UNICAST_UDP_REPEAT)
37+
self._multicast_num = kwargs.get('multicast_num', MULTICAST_UDP_REPEAT)
3638

3739
super().__init__(**kwargs)
3840

@@ -48,35 +50,39 @@ def envReceived(self, env, addr):
4850

4951
def _sendResolveMatch(self, service, relatesTo, addr):
5052
env = constructResolveMatch(service, relatesTo)
51-
self.sendUnicastMessage(env, addr[0], addr[1])
53+
self.sendUnicastMessage(env, addr[0], addr[1], unicast_num=self._unicast_num)
5254

5355
def _sendProbeMatch(self, services, relatesTo, addr):
5456
env = constructProbeMatch(services, relatesTo)
55-
self.sendUnicastMessage(env, addr[0], addr[1], random.randint(0, APP_MAX_DELAY))
57+
self.sendUnicastMessage(env, addr[0], addr[1], random.randint(0, APP_MAX_DELAY),
58+
unicast_num=self._unicast_num)
5659

5760
def _sendProbe(self, types=None, scopes=None, address=None, port=None):
5861
env = constructProbe(types, scopes)
5962
if self._dpActive:
60-
self.sendUnicastMessage(env, self._dpAddr[0], self._dpAddr[1])
63+
self.sendUnicastMessage(env, self._dpAddr[0], self._dpAddr[1],
64+
unicast_num=self._unicast_num)
6165
elif address and port:
62-
self.sendUnicastMessage(env, address, port)
66+
self.sendUnicastMessage(env, address, port,
67+
unicast_num=self._unicast_num)
6368
else:
64-
self.sendMulticastMessage(env)
69+
self.sendMulticastMessage(env, multicast_num=self._multicast_num)
6570

6671
def _sendResolve(self, epr):
6772
env = constructResolve(epr)
6873
if self._dpActive:
69-
self.sendUnicastMessage(env, self._dpAddr[0], self._dpAddr[1])
74+
self.sendUnicastMessage(env, self._dpAddr[0], self._dpAddr[1],
75+
unicast_num=self._unicast_num)
7076
else:
71-
self.sendMulticastMessage(env)
77+
self.sendMulticastMessage(env, multicast_num=self._multicast_num)
7278

7379
def _sendHello(self, service):
7480
env = constructHello(service)
7581
random.seed((int)(time.time() * 1000000))
76-
self.sendMulticastMessage(env,initialDelay=random.randint(0, APP_MAX_DELAY))
82+
self.sendMulticastMessage(env,initialDelay=random.randint(0, APP_MAX_DELAY),
83+
multicast_num=self._multicast_num)
7784

7885
def _sendBye(self, service):
7986
env = constructBye(service)
8087
service.incrementMessageNumber()
81-
self.sendMulticastMessage(env)
82-
88+
self.sendMulticastMessage(env, multicast_num=self._multicast_num)

wsdiscovery/threaded.py

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
from .message import createSOAPMessage, parseSOAPMessage
1414
from .udp import UDPMessage
1515
from .util import _getNetworkAddrs, dom2Str
16-
17-
logger = logging.getLogger("threading")
16+
from .udp import UNICAST_UDP_REPEAT, MULTICAST_UDP_REPEAT
1817

1918
BUFFER_SIZE = 0xffff
2019
NETWORK_ADDRESSES_CHECK_TIMEOUT = 5
2120
MULTICAST_PORT = 3702
2221
MULTICAST_IPV4_ADDRESS = "239.255.255.250"
2322
MULTICAST_IPV6_ADDRESS = "FF02::C"
2423

24+
logger = logging.getLogger("threading")
25+
2526

2627
class _StoppableDaemonThread(threading.Thread):
2728
"""Stoppable daemon thread.
@@ -157,14 +158,18 @@ def removeSourceAddr(self, addr):
157158
sock.close()
158159
del self._multiOutUniInSockets[addr]
159160

160-
def addUnicastMessage(self, env, addr, port, initialDelay=0):
161-
msg = UDPMessage(env, addr, port, UDPMessage.UNICAST, initialDelay)
161+
def addUnicastMessage(self, env, addr, port, initialDelay=0,
162+
unicast_num=UNICAST_UDP_REPEAT):
163+
msg = UDPMessage(env, addr, port, UDPMessage.UNICAST, initialDelay,
164+
unicast_num=unicast_num)
162165

163166
self._queue.append(msg)
164167
self._knownMessageIds.add(env.getMessageId())
165168

166-
def addMulticastMessage(self, env, addr, port, initialDelay=0):
167-
msg = UDPMessage(env, addr, port, UDPMessage.MULTICAST, initialDelay)
169+
def addMulticastMessage(self, env, addr, port, initialDelay=0,
170+
multicast_num=MULTICAST_UDP_REPEAT):
171+
msg = UDPMessage(env, addr, port, UDPMessage.MULTICAST, initialDelay,
172+
multicast_num=multicast_num)
168173

169174
self._queue.append(msg)
170175
self._knownMessageIds.add(env.getMessageId())
@@ -358,12 +363,16 @@ def _get_multicast_ttl(self):
358363
class ThreadedNetworking:
359364
"handle threaded networking start & stop, address add/remove & message sending"
360365

361-
def __init__(self, **kwargs):
366+
def __init__(self,
367+
unicast_num=UNICAST_UDP_REPEAT,
368+
multicast_num=MULTICAST_UDP_REPEAT, **kwargs):
362369
self._networkingThread_v4 = None
363370
self._networkingThread_v6 = None
364371
self._addrsMonitorThread_v4 = None
365372
self._addrsMonitorThread_v6 = None
366373
self._serverStarted = False
374+
self._unicast_num = unicast_num
375+
self._multicast_num = multicast_num
367376
super().__init__(**kwargs)
368377

369378
def _startThreads(self):
@@ -423,12 +432,24 @@ def removeSourceAddr(self, addr):
423432
elif version == 6:
424433
self._networkingThread_v6.removeSourceAddr(addr)
425434

426-
def sendUnicastMessage(self, env, host, port, initialDelay=0):
435+
def sendUnicastMessage(self, env, host, port, initialDelay=0,
436+
unicast_num=UNICAST_UDP_REPEAT):
427437
"handle unicast message sending"
428-
self._networkingThread_v4.addUnicastMessage(env, host, port, initialDelay)
429-
self._networkingThread_v6.addUnicastMessage(env, host, port, initialDelay)
438+
self._networkingThread_v4.addUnicastMessage(env, host, port,
439+
initialDelay, unicast_num)
440+
self._networkingThread_v6.addUnicastMessage(env, host, port,
441+
initialDelay, unicast_num)
430442

431-
def sendMulticastMessage(self, env, initialDelay=0):
443+
def sendMulticastMessage(self, env, initialDelay=0,
444+
multicast_num=MULTICAST_UDP_REPEAT):
432445
"handle multicast message sending"
433-
self._networkingThread_v4.addMulticastMessage(env, MULTICAST_IPV4_ADDRESS, MULTICAST_PORT, initialDelay)
434-
self._networkingThread_v6.addMulticastMessage(env, MULTICAST_IPV6_ADDRESS, MULTICAST_PORT, initialDelay)
446+
self._networkingThread_v4.addMulticastMessage(env,
447+
MULTICAST_IPV4_ADDRESS,
448+
MULTICAST_PORT,
449+
initialDelay,
450+
multicast_num)
451+
self._networkingThread_v6.addMulticastMessage(env,
452+
MULTICAST_IPV6_ADDRESS,
453+
MULTICAST_PORT,
454+
initialDelay,
455+
multicast_num)

wsdiscovery/udp.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,27 @@
2626
class UDPMessage:
2727
"UDP message management implementation"
2828

29-
MULTICAST = 'multicast'
3029
UNICAST = 'unicast'
30+
MULTICAST = 'multicast'
3131

32-
def __init__(self, env, addr, port, msgType, initialDelay=0):
33-
"""msgType shall be UDPMessage.MULTICAST or UDPMessage.UNICAST"""
32+
def __init__(self, env, addr, port, msgType, initialDelay=0,
33+
unicast_num=UNICAST_UDP_REPEAT,
34+
multicast_num=MULTICAST_UDP_REPEAT):
35+
"""msgType shall be UDPMessage.UNICAST or UDPMessage.MULTICAST"""
3436
self._env = env
3537
self._addr = addr
3638
self._port = port
3739
self._msgType = msgType
3840

3941
if msgType == self.UNICAST:
4042
udpRepeat, udpMinDelay, udpMaxDelay, udpUpperDelay = \
41-
UNICAST_UDP_REPEAT, \
43+
unicast_num, \
4244
UNICAST_UDP_MIN_DELAY, \
4345
UNICAST_UDP_MAX_DELAY, \
4446
UNICAST_UDP_UPPER_DELAY
4547
else:
4648
udpRepeat, udpMinDelay, udpMaxDelay, udpUpperDelay = \
47-
MULTICAST_UDP_REPEAT, \
49+
multicast_num, \
4850
MULTICAST_UDP_MIN_DELAY, \
4951
MULTICAST_UDP_MAX_DELAY, \
5052
MULTICAST_UDP_UPPER_DELAY
@@ -79,5 +81,3 @@ def refresh(self):
7981
self._t = self._udpUpperDelay
8082
self._nextTime = int(time.time() * 1000) + self._t
8183
self._udpRepeat = self._udpRepeat - 1
82-
83-

0 commit comments

Comments
 (0)