You’ve read our documentation and built a fantastic cloud queue implementation. You’ve got your contexts and queue versions all set up. You fire up the cloud queue (CQ) server, point
loadCloudQueue at it, and… nothing. The music doesn’t play. What next?
The first step to seeing what’s going on is to understand what the player is asking for from the cloud queue server, and what the server is telling it. Now, you could build all kinds of logging in to your server (you should probably be doing that anyway!), but it’s often a very iterative, time consuming process to arrive at exactly what kind of logging you need. And even then, it’s difficult to display all logged data in a way that’s easily digestible.
Wireshark is a robust app, but with that extensive capability comes some complexity, at least for those of us who aren’t networking savants. But if we can arrive at the right settings, Wireshark is a fantastic tool for looking at cloud queue traffic.
The techniques we’re about to talk about here will be really valuable for debugging cloud queue implementations, but they’re predicated on observing traffic over insecure HTTP. If you try to observe the traffic over secure connections, you can’t see what’s being sent and received. So: develop on insecure endpoints, deploy to production after you’ve debugged, and with secure endpoints.
Wireshark can most easily examine network traffic to and from the local machine, so you’ll have to run your cloud queue server locally. There are some tricks we can employ that’ll let us look at traffic between a player and a remote server. We’ll look at those a bit later.
I’ve got our cloud queue sample server running on my dev machine, along with Wireshark. This machine is connected via Wi-Fi to the same network as my Play:5. Hardwired Ethernet would be fine, too.
Once we’ve gotten the IP addresses for the two devices, we can begin to configure Wireshark to examine CQ traffic. I’ll leave it to you to get the IP address of your computer, but to get that of your target Sonos speaker, simply open the “About My Sonos System” section of the Sonos App.
In the above setup, we can see that the Sonos player is at IP address 192.168.55.190. That means we’ll want to tell Wireshark to look at all traffic to and from this address. To do this, we want to “Capture …using this filter” on the opening screen of Wireshark.
First, select the network interface you’ve connected to your Wi-Fi network. It’s usually pretty easy to figure out which one to select, as the active interface will have a small activity waveform after its entry in the list.
In the filter text field, we’ve specified that we want to examine traffic from a “host” with an IP address of 192.168.55.190. If we wanted to only examine traffic in one direction, we could prepend the above input with either “src” or “dest”. We want it all, so we’ll leave those off.
Once you’ve got everything the way you want it, hit “Enter” to be taken to the Wireshark Capture screen.
We’re capturing cloud queue packets between the player and the server! That’s great, but the problem is, we’re capturing a bunch of other, distracting stuff as well. (This stuff is useful information, but not when you’re looking to debug your CQ server.) Things are just really hard to sort, so we’re going to apply a display filter.
First, let’s talk about what we’re interested in capturing. We know that the cloud queue server receives HTTP callouts from the player, things like
GET /itemWindow or
POST /timePlayed. And we know the CQ server responds with JSON bodies. So those are the two things we’re really interested in here. Luckily Wireshark has some display filters that meet our needs.
Let’s start with our first type of captured data: HTTP requests from the player. It turns out that Wireshark has a display filter called, simply,
http. We could just use that, and we’d get all the HTTP callouts, both from the player and from the CQ server (though we know the server won’t be making any callouts). The problem with simply using
http by itself is that the player makes a lot of other HTTP callouts that are unrelated to cloud queue activity. All this extra information clutters our results.
So let’s drill in a bit on that http display filter. It turns out we can do things like look at the URL, or even the path. That last part is interesting to us. As I noted, I’m using our CQ sample server, which has a default path of
http://ip.address/musicqueue/1.0. We can reference that “musicqueue” part when we specify an HTTP URL path to examine.
The second type of data we’re looking for is the JSON responses from the CQ server to the player. You won’t be surprised to find out that Wireshark has a
json display filter. It also has a bunch of neat filters, like the ability to filter by keys. We pretty much want all the JSON data going back and forth between our two devices under observation, so we’ll just stick with
Putting the two together, using the boolean operator support in Wireshark, we come up with something like
http.url.path contains "musicqueue" || json. Once we put that in the display filters text box, our traffic becomes more readable.
Examining Cloud Queue Traffic
Taking a look at the example image below, the first thing we can see is an HTTP callout, as noted in the “Protocol” column. This callout is from 192.168.55.190, our player IP address, to 192.168.55.174, our CQ server. Looking at the “Info” column, you can see that it was a callout to the
GET /itemWindow endpoint, with various itemWindow request variables, like
itemId, included as URL parameters. You can click on the image to open a bigger version in a new window.
The very next line is the response from the server. This request/response relationship is noted by Wireshark in the far left column with the light grey outgoing and incoming arrows. If you click on the response entry, as I’ve done in the image, you can examine specifics about the HTTP response. What we’re interested in is the JSON response body, which I’ve expanded. In there, you can see many of the expected
GET /itemWindow response values, like our
items array, and the individual
item objects inside.
Congratulations! Now go fix that cloud queue bug, and bring the joy of music to your listeners’ homes.
Cloud Queue Debugging Extra Credit
Remember above where I mentioned that we were limited to running the CQ server on the same machine as Wireshark, due to the fact that only traffic to and from the local machine is visible on a network interface? Well, that’s not exactly true. There’s a technique we can use to examine traffic between a player and a remote server. Doing so requires just a little bit of network understanding.
Modern networks are switched, which means that a network interface (like the ethernet port on your computer) will only get traffic that is meant for that IP address. Stuff happening elsewhere never makes it to that ethernet port. Routers and switches take care of all that stuff for us, and our networks are vastly better off for their efforts.
But we want ALL the traffic, right? It turns out, we can get it all. Back in the early days of networking, a lot of intranets were built with simple ethernet “hubs”, which basically just broadcast anything coming into the hub out to everything connected to the hub. Packet chaos, sure, but a “feature” that we can exploit, if we configure our network correctly.
Both the Sonos player you want to examine and the computer running Wireshark will need to be wired via an Ethernet connection to the hub. Your setup will look something like the image below.
As you can see, the player and the CQ server are free to communicate as usual. The difference is that the Wireshark machine is able to “spy” on all that traffic. To do that, we’ll want to set up Wireshark to gather the appropriate communications. Using what we learned, above, we can either target all traffic coming from and going to the player, or the server. In this case, it’s actually easier to target the traffic to and from the server, as it’s pretty certain that we’re interested in all of it.
So we set up the Capture page in Wireshark with “host server.ip.address.or.hostname”. Below, I’ve substituted the fake IP address “w.x.y.z” for the real one I was using. (Security through obscurity!)
Once we’ve got this set up, and then apply our display filters on the capture page, we can easily see traffic between a cloud queue server and a player.
Wireshark can be a valuable tool in your Sonos Platform dev toolkit. It provides the ability to not just see data in context, but to save an entire capture to a Wireshark format to distribute for education or support purposes.