[GH-ISSUE #676] Librespot device does not disappear when exiting #387

Open
opened 2026-02-27 19:30:20 +03:00 by kerem · 11 comments
Owner

Originally created by @Johannesd3 on GitHub (Mar 20, 2021).
Original GitHub issue: https://github.com/librespot-org/librespot/issues/676

The official Spotify clients disappear immediately from the list of available devices in other Spotify clients when they are exitted. Librespot does not disappear.

First I thought it has something to do with the kMessageTypeGoodbye that is sent on shutdown. It doesn't seem to reach another Librespot instance (with log level debug so I can see the incoming messages). But only the web player's goodbye shows up. When I close the desktop client, no goodbye message is shown in Librespot, but it disappears from the web player's device list nevertheless.

I don't really understand what's going on, so maybe someone else can take a look.

This applies to the dev branch as well as to tokio_migration.

Originally created by @Johannesd3 on GitHub (Mar 20, 2021). Original GitHub issue: https://github.com/librespot-org/librespot/issues/676 The official Spotify clients disappear immediately from the list of available devices in other Spotify clients when they are exitted. Librespot does not disappear. First I thought it has something to do with the `kMessageTypeGoodbye` that is sent on shutdown. It doesn't seem to reach another Librespot instance (with log level debug so I can see the incoming messages). But only the web player's goodbye shows up. When I close the desktop client, no goodbye message is shown in Librespot, but it disappears from the web player's device list nevertheless. I don't really understand what's going on, so maybe someone else can take a look. This applies to the `dev` branch as well as to `tokio_migration`.
Author
Owner

@roderickvd commented on GitHub (Mar 21, 2021):

Maybe the official clients keep a particular port alive to a Spotify server, that librespot doesn't?

<!-- gh-comment-id:803667815 --> @roderickvd commented on GitHub (Mar 21, 2021): Maybe the official clients keep a particular port alive to a Spotify server, that librespot doesn't?
Author
Owner

@Johannesd3 commented on GitHub (Mar 23, 2021):

Maybe the official clients keep a particular port alive to a Spotify server, that librespot doesn't?

I believe you understood it the other way round. But the librespot device does not disappear although it should.

<!-- gh-comment-id:805138249 --> @Johannesd3 commented on GitHub (Mar 23, 2021): > Maybe the official clients keep a particular port alive to a Spotify server, that librespot doesn't? I believe you understood it the other way round. But the librespot device does _not_ disappear although it should.
Author
Owner

@roderickvd commented on GitHub (Mar 23, 2021):

No I do mean what I said. Perhaps there’s no messaging mechanism but just an established keep-alive connection by which the official clients signal they are available. And on shutdown when they close the connection, that’s their offline signal. Just theorizing here.

<!-- gh-comment-id:805148864 --> @roderickvd commented on GitHub (Mar 23, 2021): No I do mean what I said. Perhaps there’s no messaging mechanism but just an established keep-alive connection by which the official clients signal they are available. And on shutdown when they close the connection, that’s their offline signal. Just theorizing here.
Author
Owner

@Johannesd3 commented on GitHub (Mar 23, 2021):

Ah ok. Would seem odd to use an extra connection to signal shutdown, but maybe it's related to the new api.

@devgianlu Does the same issue exist for librespot-java?

<!-- gh-comment-id:805182461 --> @Johannesd3 commented on GitHub (Mar 23, 2021): Ah ok. Would seem odd to use an extra connection to signal shutdown, but maybe it's related to the new api. @devgianlu Does the same issue exist for librespot-java?
Author
Owner

@devgianlu commented on GitHub (Mar 23, 2021):

The new API doesn't seem to have a command to signal shutdown. All it has is these, but I am not having any issue with it not disappearing. I suppose they are detecting the websocket connection closing.

<!-- gh-comment-id:805188815 --> @devgianlu commented on GitHub (Mar 23, 2021): The new API doesn't seem to have a command to signal shutdown. All it has is [these](https://github.com/librespot-org/librespot-java/blob/103fabcddc1845a894003b19ae77e983cfc68972/lib/src/main/proto/connect.proto#L129-L138), but I am not having any issue with it not disappearing. I suppose they are detecting the websocket connection closing.
Author
Owner

@roderickvd commented on GitHub (Mar 23, 2021):

Here's a quick and abbreviated comparison of lsof -i.

Official Spotify client on macOS, controlling librespot on another host:

UDP *:57621
TCP *:57621 (LISTEN)
TCP *:59237 (LISTEN)
TCP xxx.xxx.xxx.xxx:59242->132.242.190.35.bc.googleusercontent.com:4070 (ESTABLISHED)
UDP *:mdns
UDP *:ssdp
UDP *:62204
xxx.xxx.xxx.xxx:59247->47.224.186.35.bc.googleusercontent.com:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59309->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59246->25.224.186.35.bc.googleusercontent.com:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59265->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59280->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59310->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59273->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59263->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59264->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59266->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59267->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59268->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59276->yyy.yyy.yyy.yyy:8009 (ESTABLISHED)
xxx.xxx.xxx.xxx:59279->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59269->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59278->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59271->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59270->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59272->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59307->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59308->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59274->151.101.38.248:https (ESTABLISHED)
xxx.xxx.xxx.xxx:59275->151.101.38.248:https (ESTABLISHED)

And on the librespot host it is controlling:

TCP *:42597 (LISTEN)
UDP *:mdns 
UDP *:mdns 
TCP zzz.zzz.zzz.zzz:59558->232.65.199.104.bc.googleusercontent.com:4070 (ESTABLISHED)

Where xxx.xxx.xxx.xxx is the macOS host, yyy.yyy.yyy.yyy some other Spotify Connect-capable host, and zzz.zzz.zzz.zzz the host running librespot.

<!-- gh-comment-id:805228115 --> @roderickvd commented on GitHub (Mar 23, 2021): Here's a quick and abbreviated comparison of `lsof -i`. Official Spotify client on macOS, controlling librespot on another host: ``` UDP *:57621 TCP *:57621 (LISTEN) TCP *:59237 (LISTEN) TCP xxx.xxx.xxx.xxx:59242->132.242.190.35.bc.googleusercontent.com:4070 (ESTABLISHED) UDP *:mdns UDP *:ssdp UDP *:62204 xxx.xxx.xxx.xxx:59247->47.224.186.35.bc.googleusercontent.com:https (ESTABLISHED) xxx.xxx.xxx.xxx:59309->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59246->25.224.186.35.bc.googleusercontent.com:https (ESTABLISHED) xxx.xxx.xxx.xxx:59265->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59280->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59310->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59273->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59263->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59264->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59266->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59267->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59268->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59276->yyy.yyy.yyy.yyy:8009 (ESTABLISHED) xxx.xxx.xxx.xxx:59279->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59269->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59278->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59271->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59270->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59272->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59307->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59308->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59274->151.101.38.248:https (ESTABLISHED) xxx.xxx.xxx.xxx:59275->151.101.38.248:https (ESTABLISHED) ``` And on the librespot host it is controlling: ``` TCP *:42597 (LISTEN) UDP *:mdns UDP *:mdns TCP zzz.zzz.zzz.zzz:59558->232.65.199.104.bc.googleusercontent.com:4070 (ESTABLISHED) ``` Where `xxx.xxx.xxx.xxx` is the macOS host, `yyy.yyy.yyy.yyy` some other Spotify Connect-capable host, and `zzz.zzz.zzz.zzz` the host running librespot.
Author
Owner

@kingosticks commented on GitHub (Mar 24, 2021):

I've noticed two things while controlling with my Android client and stopping the librespot process:

  1. librespot remains shown as the active playing device for a while.
  2. librespot lingers in the in the "select a device" list for a while.

I think it's just the second issue you are discussing here, correct? Doesn't this sound like an mDNS problem? I've found my build using --feature with-dns-sd behaves correctly and librespot is removed from the list straight away. Have you tried that? I tried to hack about with libmdns but I got a load of tokio build problems when trying to build librespot (master) using my checkout of libmdns (master) and so I've lost interest in that. Comparing Wireshark traces of both discovery libraries would probably reveal the problem.

So potentially off topic... but for the first issue I described I found the following hack works better, but I don't understand why!

diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs
index 5e3ba38..f8a71cb 100644
--- a/connect/src/spirc.rs
+++ b/connect/src/spirc.rs
@@ -544,6 +544,7 @@ impl SpircTask {
                 }
             }
             SpircCommand::Shutdown => {
+                self.notify(None, true);
-                 CommandSender::new(self, MessageType::kMessageTypeGoodbye).send();
                 self.shutdown = true;
                 self.commands.close();
<!-- gh-comment-id:805782387 --> @kingosticks commented on GitHub (Mar 24, 2021): I've noticed two things while controlling with my Android client and stopping the librespot process: 1. librespot remains shown as the active playing device for a while. 2. librespot lingers in the in the "select a device" list for a while. I think it's just the second issue you are discussing here, correct? Doesn't this sound like an mDNS problem? I've found my build using `--feature with-dns-sd` behaves correctly and librespot is removed from the list straight away. Have you tried that? I tried to hack about with [libmdns](https://github.com/librespot-org/libmdns/) but I got a load of tokio build problems when trying to build librespot (master) using my checkout of libmdns (master) and so I've lost interest in that. Comparing Wireshark traces of both discovery libraries would probably reveal the problem. So potentially off topic... but for the first issue I described I found the following hack works better, but I don't understand why! ``` diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 5e3ba38..f8a71cb 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -544,6 +544,7 @@ impl SpircTask { } } SpircCommand::Shutdown => { + self.notify(None, true); - CommandSender::new(self, MessageType::kMessageTypeGoodbye).send(); self.shutdown = true; self.commands.close(); ```
Author
Owner

@kingosticks commented on GitHub (Mar 24, 2021):

Just to add, I did the Wireshark trace and I see when stopping librespot with dns-sd there is a goodbye message sent but not when using libmdns. libmdns seems to create a goodbye message but it doesn't make it out onto the wire. This looks pretty suspicious!

<!-- gh-comment-id:805836671 --> @kingosticks commented on GitHub (Mar 24, 2021): Just to add, I did the Wireshark trace and I see when stopping librespot with dns-sd there is a [goodbye message](https://tools.ietf.org/html/rfc6762#section-10.1) sent but not when using libmdns. libmdns seems to [create a goodbye message](https://github.com/librespot-org/libmdns/blob/acd405604d2fb589e9848d1292ce9404bd206d91/src/lib.rs#L195) but it doesn't make it out onto the wire. [This](https://github.com/librespot-org/libmdns/blob/acd405604d2fb589e9848d1292ce9404bd206d91/src/lib.rs#L205) looks pretty suspicious!
Author
Owner

@roderickvd commented on GitHub (May 24, 2021):

I'm tagging this with new-api because this might be fixed when we introduce web socket support.

<!-- gh-comment-id:847340803 --> @roderickvd commented on GitHub (May 24, 2021): I'm tagging this with `new-api` because this might be fixed when we introduce web socket support.
Author
Owner

@kingosticks commented on GitHub (May 24, 2021):

No, it's a bug in libmdns as per the proposed fix in https://github.com/librespot-org/libmdns/pull/28. I don't believe this has anything to do with how librespot works, new-api or otherwise.

<!-- gh-comment-id:847412996 --> @kingosticks commented on GitHub (May 24, 2021): No, it's a bug in libmdns as per the proposed fix in https://github.com/librespot-org/libmdns/pull/28. I don't believe this has anything to do with how librespot works, new-api or otherwise.
Author
Owner

@roderickvd commented on GitHub (May 25, 2021):

Ah I see, I was thrown off by @devgianlu earlier https://github.com/librespot-org/librespot/issues/676#issuecomment-805188815

<!-- gh-comment-id:847582387 --> @roderickvd commented on GitHub (May 25, 2021): Ah I see, I was thrown off by @devgianlu earlier https://github.com/librespot-org/librespot/issues/676#issuecomment-805188815
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/librespot#387
No description provided.