mdns icon indicating copy to clipboard operation
mdns copied to clipboard

How to browse services ?

Open titilambert opened this issue 10 years ago • 24 comments

Hello ! I'm trying to use your beautiful lib ! I succeed to register my service using issue #3 . Now I'm trying to use the Service Browser. Could you give me an example of it ? After I finish my tests, I could submit a pull request with some basic examples if you want.

titilambert avatar May 27 '14 23:05 titilambert

# start mdns
In [1]: from mdns.zeroconf import *
In [2]: from socket import *
In [3]: r = Zeroconf(("127.0.0.1",))

# register own service, just as example
In [4]: desc = {'version':'0.10','a':'test value', 'b':'another value'}
In [5]: n = "vala._workstation._tcp.local."
In [6]: d = "_workstation._tcp.local."
In [7]: info = ServiceInfo(d, n, inet_aton("127.0.0.6"), 1234)
In [8]: r.register_service(info)

# browse own services
In [9]: r.services
Out[9]: {'vala._workstation._tcp.local.': service[vala._workstation._tcp.local.,['127.0.0.6']:1234,]}

# browse cache entries
In [10]: r.cache.entries()
Out[10]: 
[record[txt,in,iPhone._device-info._tcp.local.,4500/4481.0,'\x0bmodel=N53AP'],
 record[txt,in-unique,linux-4 [28:d2:44:3f:f6:58]._workstation._tcp.local.,4500/4461.0,'\x00'],
 record[srv,in-unique,linux-4 [28:d2:44:3f:f6:58]._workstation._tcp.local.,120/81.0,linux-4.local.:9],
 record[ptr,in,_workstation._tcp.local.,4500/4461.0,linux-4 [28:d2:44:3f:f6:58]._workstation._tcp.local.],
 record[ptr,in,_workstation._tcp.local.,4500/4461.0,linux [a0:48:1c:15:87:ab]._workstation._tcp.local.],
 record[ptr,in,_workstation._tcp.local.,3600/3562.0,vala._workstation._tcp.local.],
 fe:80:0:0:0:0:0:0:50:54:0:ff:fe:e4:ee:29 (reachable),
 fe:80:0:0:0:0:0:0:12:dd:b1:ff:fe:b9:5b:be (reachable),
 192.168.1.68 (reachable),
 fe:80:0:0:0:0:0:0:a2:48:1c:ff:fe:15:87:ab (reachable),
 192.168.1.178 (reachable),
 fe:80:0:0:0:0:0:0:2a:d2:44:ff:fe:3f:f6:58 (reachable),
 192.168.1.179 (reachable),
 fe:80:0:0:0:0:0:0:22:c9:d0:ff:fe:7b:2e:a3 (reachable),
 192.168.1.182 (reachable),
 record[srv,in-unique,linux [a0:48:1c:15:87:ab]._workstation._tcp.local.,120/81.0,linux.local.:9],
 record[srv,in,vala._workstation._tcp.local.,3600/3562.0,vala._workstation._tcp.local.:1234],
 record[txt,in,vala._workstation._tcp.local.,3600/3562.0,''],
 127.0.0.6 (reachable)]

# match by name
In [11]: r.cache.entries_with_name('vala._workstation._tcp.local.')
Out[11]: 
[record[srv,in,vala._workstation._tcp.local.,3600/3508.0,vala._workstation._tcp.local.:1234],
 record[txt,in,vala._workstation._tcp.local.,3600/3508.0,''],
 127.0.0.6 (reachable)]

You can also play around with structures in ipython.

And thanks for heads-up, this library needs some refactoring.

svinota avatar May 28 '14 08:05 svinota

Thanks ! Do you plan to support python3 ?

titilambert avatar Jun 08 '14 19:06 titilambert

I have to :) So if it doesn't work with python3 now, it should be fixed soon. I didn't touch this package for too long, actually. Maybe, time to revive it.

svinota avatar Jun 08 '14 19:06 svinota

Oki, I will to try to do it ! One more question: In fact, I want to discovert all bonjour user inthe network. When I run your example, I have to launch my pidgin after I create the "r" object... Which function do I need to relaunch the discovering ?

Thanks !

titilambert avatar Jun 08 '14 20:06 titilambert

If you have a service record in the cache, you can use request() method to update it. Beside of that, all updates are done asynchronously, so, when something changes, you'll see it in the cache.

svinota avatar Jun 08 '14 20:06 svinota

oki but at the beginning I don't have any services, and pidgin seems resend registration only on login ...

titilambert avatar Jun 08 '14 20:06 titilambert

Ahha... Right now I can not check it -- but tomorrow for sure will provide you the code (and/or fix the library, depends)

svinota avatar Jun 08 '14 20:06 svinota

Your libs seems python 3.4 compatible :) I manage to remove the dependency to crypto

titilambert avatar Jun 08 '14 20:06 titilambert

Thanks !

titilambert avatar Jun 08 '14 20:06 titilambert

Actually, crypto is required by DNSSEC extensions. So I have just to make this dependency optional.

svinota avatar Jun 08 '14 20:06 svinota

Not for python 3.4 :(, I get :

.... ..../mdns/zeroconf.py", line 829, in read_name len = ord(self.data[off]) TypeError: ord() expected string of length 1, but int found

I just opened an other issue for this subject...

titilambert avatar Jun 08 '14 21:06 titilambert

Yep. Thanks a lot! Will fix it.

svinota avatar Jun 08 '14 21:06 svinota

So, about pidgin records.

If you start pidgin, then mdns: you can use r.get_service_info('record.name', 'full.pidgin.record.name.') (just replace strings with what pidgin uses)

If you start mdns, then pidgin: pidgin on login will send a notification and you will get it in the cache automatically.

svinota avatar Jun 09 '14 18:06 svinota

Thanks ! I will try to test it to night (EST time)

titilambert avatar Jun 09 '14 18:06 titilambert

There is a possibility, that the record can be short-term, and will be expired soon. For this short-term records one can use listeners as callbacks: https://github.com/svinota/mdns/blob/master/mdns/zeroconf.py#L1888

svinota avatar Jun 09 '14 18:06 svinota

Hello ! I just don't get the get_service_info function. I get this from cache.entries() from pidgin:

Out[46]: 
[record[ptr,in,_presence._tcp.local.,4500/4499.0,Me_on_my_computer@absol._presence._tcp.local.],
 fe:80:0:0:0:0:0:0:4a:5b:39:ff:fe:70:34:aa (reachable),
 192.168.2.11 (reachable),
 <repr(<mdns.zeroconf.DNSText at 0x7f0b773f18d0>) failed: TypeError: can't concat bytes to str>,
 record[srv,in-unique,Me_on_my_computer@absol._presence._tcp.local.,120/119.0,absol.local.:5298],
 record[ptr,in,_services._dns-sd._udp.local.,4500/4499.0,_presence._tcp.local.]]

I just fail to refetch pidgin informations. I tried: get_service_info('_presence._tcp.local.', '._presence._tcp.local.') get_service_info('_presence._tcp.local.', 'Me_on_my_computer@absol._presence._tcp.local.')

But nothing seems work...

Thanks !

titilambert avatar Jun 10 '14 01:06 titilambert

Actually, it should return appropriate service record from cache after update. But, obviously, doesn't. Investigating.

svinota avatar Jun 10 '14 07:06 svinota

No, it does :)

Look, it return services, not pointers:

$ avahi-browse -r -a -t
+ virbr0 IPv4 linux-4 [fe:54:00:91:f7:e6]                   Workstation          local
+ wlp3s0 IPv4 linux-4 [5c:51:4f:fa:9f:65]                   Workstation          local
= virbr0 IPv4 linux-4 [fe:54:00:91:f7:e6]                   Workstation          local
   hostname = [linux-4.local]
   address = [192.168.122.1]
   port = [9]
   txt = []
= wlp3s0 IPv4 linux-4 [5c:51:4f:fa:9f:65]                   Workstation          local
   hostname = [linux-4.local]
   address = [10.0.0.205]
   port = [9]
   txt = []
In [20]: r.get_service_info('local.', 'linux-4.local.')
Out[20]: service[linux-4.local.,['10.0.0.205', '192.168.122.1']:None,]

But in your case, probably, a record is required, not a service. So, looking, how to get it (working with services, never needed this before, so can be not implemented yet)

svinota avatar Jun 10 '14 07:06 svinota

Could you pls tell how to set up pidgin to provide these mdns records? I have pidgin 2.10.9 on Fedora 20, but see no such «presence» records in avahi database.

svinota avatar Jun 10 '14 07:06 svinota

you have to add a "Bonjour" account in your configuration. Accounts -> Manage Accounts -> Add... -> Protocol: Bonjour

titilambert avatar Jun 13 '14 01:06 titilambert

Great. What I did: started Pidgin with my name (svinota), after that launched mdns:

In [13]: r.get_service_info('local.', 'svinota@linux._presence._tcp.local.')

In [14]: r.cache.cache['svinota@linux._presence._tcp.local.']
Out[14]: 
[record[txt,in-unique,svinota@linux._presence._tcp.local.,4500/4010.0,'\x04vc=!\nver=2.10.9\x0enode=libpu...'],
 record[srv,in-unique,svinota@linux._presence._tcp.local.,120/105.0,linux.local.:5298]]

In [15]: p = r.cache.cache['svinota@linux._presence._tcp.local.'][0]

In [16]: p.properties
Out[16]: 
{'1st': 'svinota',
 'last': 0,
 'node': 'libpurple',
 'port.p2pj': '5298',
 'status': 'avail',
 'txtvers': '1',
 'vc': '!',
 'ver': '2.10.9'}

This is a bit weird way to get info, yep, but it is usable right now; more convenient way you wait or propose as a patchset.

svinota avatar Jun 13 '14 10:06 svinota

I know this repository it's not updated since 2014, but maybe you may help me.

I'm developing a plugin for sublime text and I need to browse/discover Arduino/ESP devices. I was using zeroconf with _arduino._tcp.local. and it works fine. But zeroconf works with netifaces and I can't make run that package in the sublime text environment because it's written in C. So I'm looking for an alternative and this repository seems to work without the netifaces dependence.

I tried with the examples you wrote above but I didn't have luck, can you tell me how should I do it with the arduino service?

gepd avatar Jun 18 '17 10:06 gepd

Actually I had a plan to write an implementation completely from scratch, possibly based on pyroute2, so didn't pay attention to this repo, sorry, it may be in a broken state. Give me some time to review the repo and possibly fix it enough to launch samples at least.

svinota avatar Jun 18 '17 11:06 svinota

Thanks @svinota , I'll really appreciate your help, I'm a little lost with this subject and this it's an important feature to work with that kind of hardware.

gepd avatar Jun 19 '17 04:06 gepd