{"id":1711,"date":"2022-03-12T20:05:52","date_gmt":"2022-03-12T19:05:52","guid":{"rendered":"https:\/\/hannes.enjoys.it\/blog\/?p=1711"},"modified":"2022-07-22T17:41:14","modified_gmt":"2022-07-22T15:41:14","slug":"fossgis-jeopardy-the-buzzer","status":"publish","type":"post","link":"https:\/\/hannes.enjoys.it\/blog\/2022\/03\/fossgis-jeopardy-the-buzzer\/","title":{"rendered":"FOSSGIS-Jeopardy: The buzzer"},"content":{"rendered":"\n<p>First in a series of very terse posts explaining and documenting the technical setup behind our remote video conferencing <a href=\"https:\/\/media.ccc.de\/search\/?q=fossgis+jeopardy\">FOSSGIS-Jeopardy<\/a> game setup. Mostly meant as public backup and because sharing is caring. Maybe it can inspire someone else to build silly stupid stuff for fun.<\/p>\n\n\n\n<p>Here we are with the buzzer for the candidates to hit if they want to solve a task (aka ask the question to the presented <em>thing<\/em>). I wrote this for a funny digital xmas party with the lovely colleagues at <a href=\"https:\/\/civity.de\/en\/\">Civity<\/a> in 2020 and re-used it for FOSSGIS-Jeopardy 2021 and 2022.<\/p>\n\n\n\n<p>It&#8217;s using WAMP (basically PubSub via websockets) between webbrowser pages via the awesome <a href=\"https:\/\/crossbar.io\/\">Crossbar<\/a> + <a href=\"https:\/\/crossbar.io\/autobahn\/\">AutobahnJS<\/a> combo which I first used for the crazy <a href=\"https:\/\/findingplaces.hamburg\/\" data-type=\"URL\" data-id=\"https:\/\/findingplaces.hamburg\/\">https:\/\/findingplaces.hamburg\/<\/a> project.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"480\" style=\"aspect-ratio: 920 \/ 480;\" width=\"920\" controls src=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/buzzer.mp4\"><\/video><figcaption>Yes, there is a random <a href=\"https:\/\/cultofthepartyparrot.com\/\">partyparrot<\/a> on each run.<\/figcaption><\/figure>\n\n\n\n<p>A admin page can be used to unlock a buzzer &#8220;button&#8221; (well, a parrot GIF in our case because we need more silly fun in life) on participants&#8217; buzzer pages. Participants can then touch\/click their screen to &#8220;buzz&#8221;. The incoming buzzes are displayed visible for everyone with the delay since the buzzer was unlocked.<\/p>\n\n\n\n<p>This is obviously highly dependent on the participants&#8217; latency, both on their device (touch\/click to network message) as well as from their device to the message router. A tab on a desktop browser in LAN will win against a mobile device in 2G if they&#8217;d hit it in the same moment. \u00af\\_(\u30c4)_\/\u00af<\/p>\n\n\n\n<p>There are two\/three components: The message router, the webpages and optionally a webserver (I used <code>crossbar<\/code> as router which can also host static webpages)<\/p>\n\n\n\n<p>Ask me anything if you want to set this up following the <em>amazing<\/em> instructions and fail.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install and setup <code>crossbar<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">pip install crossbar<\/code><\/pre>\n\n\n\n<p><a href=\"https:\/\/crossbar.io\/docs\/TLS-Certificates\/#using-lets-encrypt-with-crossbar-io\" data-type=\"URL\" data-id=\"https:\/\/crossbar.io\/docs\/TLS-Certificates\/#using-lets-encrypt-with-crossbar-io\">https:\/\/crossbar.io\/docs\/TLS-Certificates\/#using-lets-encrypt-with-crossbar-io<\/a> &amp; <a href=\"https:\/\/certbot.eff.org\/instructions?ws=other&amp;os=ubuntufocal\" data-type=\"URL\" data-id=\"https:\/\/certbot.eff.org\/instructions?ws=other&amp;os=ubuntufocal\">https:\/\/certbot.eff.org\/instructions?ws=other&amp;os=ubuntufocal<\/a><\/p>\n\n\n\n<p>Set up a realm and static web directory in a <code>config.json<\/code>, e. g. something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n\t\"version\": 2,\n\t\"controller\": {},\n\t\"workers\": [{\n\n\t\t\"type\": \"router\",\n\t\t\"realms\": [{\n\t\t\t\"name\": \"YOURREALMHERE\",\n\t\t\t\"roles\": [{\n\t\t\t\t\"name\": \"public\",\n\t\t\t\t\"permissions\": [{\n\t\t\t\t\t\"uri\": \"com.example.your(sub)domainhere.*\",\n\t\t\t\t\t\"allow\": {\n\t\t\t\t\t\t\"call\": false,\n\t\t\t\t\t\t\"register\": false,\n\t\t\t\t\t\t\"publish\": true,\n\t\t\t\t\t\t\"subscribe\": true\n\t\t\t\t\t}\n\t\t\t\t}]\n\t\t\t}]\n\t\t}],\n\t\t\"transports\": [{\n\t\t\t\"type\": \"web\",\n\t\t\t\"endpoint\": {\n\t\t\t\t\"type\": \"tcp\",\n\t\t\t\t\"port\": 443,\n\t\t\t\t\"tls\": {\n\t\t\t\t\tYOURTLSSETUPHERE\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"paths\": {\n\t\t\t\t\"\/\": {\n\t\t\t\t\t\"type\": \"static\",\n\t\t\t\t\t\"directory\": \"web\"\n\t\t\t\t},\n\t\t\t\t\"ws\": {\n\t\t\t\t\t\"type\": \"websocket\",\n\t\t\t\t\t\"auth\": {\n\t\t\t\t\t\t\"anonymous\": {\n\t\t\t\t\t\t\t\"type\": \"static\",\n\t\t\t\t\t\t\t\"role\": \"public\"\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"options\": {\n\t\t\t\t\t        \"max_frame_size\": 20480,\n\t\t\t\t\t        \"max_message_size\": 20480,\n\t\t\t\t\t        \"fail_by_drop\": true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}]\n\t}]\n}\n<\/code><\/pre>\n\n\n\n<p>I don&#8217;t remember anything about the <code>options<\/code> part. It might not be necessary. I probably tried to stuff something more complex into the messages at some point.<\/p>\n\n\n\n<p>Then just run <code>crossbar<\/code> as root because you used a single-purpose 2\u20ac VPS for this and you will delete it after the event anyways. Yolo! You should definitely secure your system, crossbar config and certificate and everything else properly otherwise. Seriously!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">crossbar start --config \/root\/config.json<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Webpages for control and playing<\/h2>\n\n\n\n<p>Here you go: <\/p>\n\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-0a5fb14e-a68c-4dcb-b3e3-6d23858031e4\" href=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/fossgis-jeopardy-buzzer-web.7z\">fossgis-jeopardy-buzzer-web<\/a><a href=\"https:\/\/hannes.enjoys.it\/blog\/wp-content\/uploads\/fossgis-jeopardy-buzzer-web.7z\" class=\"wp-block-file__button\" download aria-describedby=\"wp-block-file--media-0a5fb14e-a68c-4dcb-b3e3-6d23858031e4\">Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>This is really really horrible and messy code, with lots of left-over bits, bugs and random snippets. But it works so who cares! I could not care less about its bEAuTy. Sometimes a banana is the right hammer.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Screen stays on (support depends on the OS)!<\/li><li>Fullscreen mode can be triggered with a button!<\/li><li>There is a sound when the buzzer is buzzed by anyone!<\/li><li>Animations are CSS transforms on PNG sprites!<\/li><li>Random emojis are displayed if a user did not set a username!<\/li><li>Inconsistent indentation!<\/li><li>Probably some german words here and there!<\/li><li>w3schools was extensively used to create this!<\/li><\/ul>\n\n\n\n<p>Put them in a <code>web\/<\/code> directory according to the crossbar config (or host it with another webserver if you like).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the buzzer<\/h2>\n\n\n\n<p>Now you have three webpages available:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.example.com\/supersecretfilename.html\" data-type=\"URL\" data-id=\"https:\/\/www.example.com\/supersecretfilename.html\">https:\/\/www.example.com\/supersecretfilename.html<\/a> has a Start\/Stop button to start a run and displays the buzzes coming in (name and time since start)<\/li><li><a href=\"https:\/\/www.example.com\/view.html\" data-type=\"URL\" data-id=\"https:\/\/www.example.com\/view.html\">https:\/\/www.example.com\/view.html<\/a> has a white background for displaying the names and timings in OBS (masking away the white color for transparency)<\/li><li><a href=\"https:\/\/www.example.com\/?name=MyName\" data-type=\"URL\" data-id=\"https:\/\/www.example.com\/?name=MyName\">https:\/\/www.example.com\/?name=MyName<\/a> is the buzzer page\/&#8221;app&#8221; for the candidates, they can touch\/click anywhere while the run is active to register their buzz. It is meant to be used on a mobile phone.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>First in a series of very terse posts explaining and documenting the technical setup behind our remote video conferencing FOSSGIS-Jeopardy game setup. Mostly meant as public backup and because sharing is caring. Maybe it can inspire someone else to build silly stupid stuff for fun. Here we are with the buzzer for the candidates to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1711","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1711","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/comments?post=1711"}],"version-history":[{"count":10,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1711\/revisions"}],"predecessor-version":[{"id":1768,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/posts\/1711\/revisions\/1768"}],"wp:attachment":[{"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/media?parent=1711"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/categories?post=1711"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hannes.enjoys.it\/blog\/wp-json\/wp\/v2\/tags?post=1711"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}