<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>schmod</title>
	<subtitle>a blog</subtitle>
	<link href="https://schmod.com/feed/feed.xml" rel="self"/>
	<link href="https://schmod.com/"/>
	<updated>2019-05-13T00:41:14.227+00:00</updated>
	<id>https://schmod.com/</id>
	<author>
		<name>Andrew Schmadel</name>
	</author>
	
	<entry>
		<title>Windows is not Unix</title>
		<link href="https://schmod.com/posts/stdarrgh/"/>
		<updated>2012-09-25T00:00:00+00:00</updated>
		<id>https://schmod.com/posts/stdarrgh/</id>
		<content type="html">&lt;p&gt;The command line doesn&#39;t get enough love.&lt;/p&gt;
&lt;p&gt;Almost every developer leans heavily on the command line, but one can&#39;t help shake the feeling that the console is slowly drifting toward irrelevance and neglect. As less and less of our data can be expressed in terms of plaintext, the core Unix toolset also drifts toward irrelevance.&lt;/p&gt;
&lt;p&gt;That&#39;s not to say these tools aren&#39;t useful. However, these tools are failing to keep pace with the evolution of computing. One only needs to look at &lt;a href=&quot;http://mosh.mit.edu/#techinfo&quot;&gt;Mosh&lt;/a&gt;&#39;s heroic attempt to fix SSH to see just how broken (and neglected) our consoles have become. The perfectionists at Apple even managed to break &lt;code&gt;cat&lt;/code&gt; &lt;a href=&quot;https://profiles.google.com/110440139189906861022/buzz/LGNWMv1LFoJ&quot;&gt;two years ago&lt;/a&gt;, and still haven&#39;t fixed it. Nobody would accept these kinds of bugs in a GUI application, so why do we put up with them in the console?&lt;/p&gt;
&lt;p&gt;If that&#39;s the state of the Unix CLI, I&#39;m sure you can imagine what things are like on Windows...&lt;/p&gt;
&lt;p&gt;At the moment, I&#39;m developing a web interface for a script that performs a few post-processing tasks on our video files so that they&#39;re in the right format for our CDN. This isn&#39;t a particularly challenging task, and indeed, the synchronous version of this script only requires about six lines of code.&lt;/p&gt;
&lt;p&gt;However, it&#39;s generally bad form for web scripts to take 10 minutes to execute, and even worse form for a process to disappear into the background/abyss with no way of monitoring it. So, we launch the process in the background, and periodically monitor/poll its output.&lt;/p&gt;
&lt;p&gt;Luckily, asynchronous I/O is currently a very hot topic, and we have a lot of great libraries for making this task as simple as possible. &lt;a href=&quot;http://nodejs.org/&quot;&gt;Node.js&lt;/a&gt; leads the pack, but Node&#39;s influence is swiftly spreading to other languages. &lt;a href=&quot;http://nodephp.org/&quot;&gt;React&lt;/a&gt; implements the Observer Pattern and much of Node&#39;s API in PHP.&lt;/p&gt;
&lt;p&gt;Modern PHP actually has a rather nice syntax, and React makes it dead-simple to open up a process, and pipe its output straight into a WebSocket connection (provided by React&#39;s cousin, &lt;a href=&quot;http://socketo.me/&quot;&gt;Ratchet&lt;/a&gt;. Once we&#39;ve got our event loop set up, and Ratchet&#39;s WebSocket server is running, we can do this with just a few lines of code:&lt;pre class=&quot;lang-php&quot;&gt;&lt;br&gt;
use React\Stream\Stream as Stream;&lt;br&gt;
$ping = new Stream(popen(&amp;quot;ping -t 127.0.0.1&amp;quot;,&#39;r&#39;),$server-&amp;gt;loop);&lt;br&gt;
$ping-&amp;gt;on(&#39;data&#39;,function($data) use ($websocket){&lt;br&gt;
$websocket-&amp;gt;send($data);&lt;br&gt;
});&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Pretty neat, right? From the &lt;code&gt;data&lt;/code&gt; callback, I can listen to my external program&#39;s output in the background, provide updates on its status/activity, and trigger some further actions once it finishes up (based on its exit code).&lt;/p&gt;
&lt;p&gt;Unfortunately, the devil is in the details. Asynchronous I/O is a relatively new concept for Windows, and almost nobody implements it correctly. &lt;a href=&quot;https://bugs.php.net/bug.php?id=47918&quot;&gt;Including PHP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While the above code works great with many external commands, the &lt;code&gt;fread()&lt;/code&gt; call that React uses to poll the process&#39;s output will block until some data has been written to the buffer. Worse still, because React implements a single-threaded event loop, this &lt;code&gt;fread()&lt;/code&gt; call will block the &lt;em&gt;entire&lt;/em&gt; application until it reads some data.&lt;/p&gt;
&lt;p&gt;We first noticed this with the &lt;a href=&quot;http://www.adobe.com/products/flash-media-server-family/tool-downloads.html&quot;&gt;Adobe F4V Post-Processor&lt;/a&gt; (&lt;code&gt;f4vpp&lt;/code&gt;). Spawning &lt;code&gt;f4vpp&lt;/code&gt; using the method described above blocks the entire event loop for the 5 minutes that it takes to run. &lt;code&gt;f4vpp&lt;/code&gt;&#39;s welcome message doesn&#39;t even make it to the Websocket until the whole thing finishes running. If we decide to run &lt;code&gt;ping&lt;/code&gt; simultaneously, its output also gets suppressed until &lt;code&gt;f4vpp&lt;/code&gt; finishes up.&lt;/p&gt;
&lt;p&gt;Maybe the haters were right. Maybe PHP just wasn&#39;t built to live in the modern world. &lt;a href=&quot;http://nodejs.org/&quot;&gt;Node&lt;/a&gt; has asynchronicity built in from the core, and its backend I/O library, &lt;a href=&quot;https://github.com/joyent/libuv&quot;&gt;libuv&lt;/a&gt;, claims to properly asynchronous I/O properly on Windows.&lt;/p&gt;
&lt;p&gt;Let&#39;s implement the same code on Node:&amp;lt;pre class&amp;quot;lang-js&amp;quot;&amp;gt;&lt;br&gt;
var spawn = require(&#39;child_process&#39;).spawn,&lt;br&gt;
ping = spawn(&#39;ping&#39;,[&#39;-t&#39;,&#39;127.0.0.1&#39;]);&lt;br&gt;
ping.stdout.setEncoding(&#39;utf8&#39;);&lt;br&gt;
ping.stdout.on(&#39;data&#39;,function(data){&lt;br&gt;
websocket.emit(&#39;message&#39;,{&#39;stdout&#39;: data});&lt;br&gt;
});&lt;/p&gt;
&lt;p&gt;Look familiar? As before, &lt;code&gt;ping&lt;/code&gt;&#39;s output gets sent to our client via a WebSocket connection.&lt;/p&gt;
&lt;p&gt;However, our old friend, &lt;code&gt;f4vpp&lt;/code&gt; shows the same problems as it did before. Node&#39;s &lt;code&gt;data&lt;/code&gt; event doesn&#39;t fire until the entire application has finished running. Unlike PHP, however, the rest of the application keeps churning along.&lt;/p&gt;
&lt;p&gt;What&#39;s going on here? Why can I see &lt;code&gt;f4vpp&lt;/code&gt;&#39;s output when I run it in the terminal, but that same output is invisible to Node and PHP? Let&#39;s try redirecting &lt;code&gt;f4vpp&lt;/code&gt;&#39;s output to a file, and examine what happens to that file.&lt;/p&gt;
&lt;p&gt;In one terminal, I run &lt;code&gt;f4vpp -v -i in.f4v -o out.mp4 &amp;gt; o.log&lt;/code&gt;, and in another, I follow the file with &lt;code&gt;tail -f o.log&lt;/code&gt;. Just like we observed in Node, nothing appears in our &lt;code&gt;stdout.log&lt;/code&gt; file until &lt;code&gt;f4vpp&lt;/code&gt; has finished. (By the way, you can get a win32-native &lt;code&gt;tail&lt;/code&gt; from &lt;a href=&quot;https://github.com/bmatzelle/gow/wiki&quot;&gt;gow&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;It turns out, this is all Adobe&#39;s fault. &lt;code&gt;f4vpp&lt;/code&gt; writes its output to &lt;code&gt;stdout&lt;/code&gt;, but never flushes that stream&#39;s buffer. If the application isn&#39;t explicitly calling &lt;code&gt;fflush()&lt;/code&gt;, it&#39;s up to the OS to decide when to flush the output buffer. Usually, this happens &lt;a href=&quot;http://www.pixelbeat.org/programming/stdio_buffering/&quot;&gt;in one of three ways&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When the buffer is full (usually 4KiB). &lt;code&gt;f4vpp&lt;/code&gt; doesn&#39;t write a lot to the console, so this never happens.&lt;/li&gt;
&lt;li&gt;When the process exits. This is why Node and PHP are able to see any output &lt;em&gt;at all&lt;/em&gt; from &lt;code&gt;f4vpp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When a newline character is written to the stream, &lt;em&gt;and&lt;/em&gt; &lt;code&gt;stdout&lt;/code&gt; is a terminal. This is why &lt;code&gt;f4vpp&lt;/code&gt; displays its output normally when we run it interactively from the terminal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Where does this leave us? We don&#39;t control Adobe&#39;s source code, and can&#39;t modify their application to improve its behavior. On some Linux-based systems, we could use the &lt;a href=&quot;http://www.pixelbeat.org/programming/stdio_buffering/stdbuf-man.html&quot;&gt;&lt;code&gt;stdbuf&lt;/code&gt;&lt;/a&gt; command to force &lt;code&gt;f4vpp&lt;/code&gt; to give us unbuffered or line-buffered output. Sadly, no equivalent command exists on Windows systems.&lt;/p&gt;
&lt;p&gt;Alternatively, we can use &lt;a href=&quot;http://expect.sourceforge.net/&quot;&gt;expect&lt;/a&gt; to interact with the external process, and unbuffer its output. It&#39;s a bit of a kludge, but expect&#39;s &lt;a href=&quot;http://www.linuxcommand.org/man_pages/unbuffer1.html&quot;&gt;&lt;code&gt;unbuffer&lt;/code&gt;&lt;/a&gt; script does work on ActiveState&#39;s &lt;a href=&quot;http://www.activestate.com/activetcl/expect&quot;&gt;win32 port of expect&lt;/a&gt; (which is part of their TCL distribution). The &lt;code&gt;unbuffer&lt;/code&gt; script isn&#39;t bundled with ActiveState&#39;s Expect, so you&#39;ll have to &lt;a href=&quot;http://expect.cvs.sourceforge.net/viewvc/expect/expect/example/unbuffer?revision=5.34&quot;&gt;download that separately&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Repeating our previous &lt;code&gt;tail -f&lt;/code&gt; experiment with &lt;code&gt;tclsh unbuffer f4vpp....&lt;/code&gt; works like we&#39;d expect it to, with similar (good!) results on Node and PHP. Unfortunately, this is all very cumbersome, and I&#39;m not sure I&#39;d recommend it for production code.&lt;/p&gt;
&lt;p&gt;Theoretically, we can compile this into a self-contained executable. Unfortunately, ActiveState&#39;s Expect isn&#39;t open-source, and the other win32 Expect distributions are ancient. Perhaps some C++ developer will come to the rescue and fix this for us...&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Socket.IO and IIS</title>
		<link href="https://schmod.com/posts/socket-io-and-iis/"/>
		<updated>2012-10-02T00:00:00+00:00</updated>
		<id>https://schmod.com/posts/socket-io-and-iis/</id>
		<content type="html">&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/WebSockets&quot;&gt;WebSockets&lt;/a&gt; are pretty great. I won&#39;t go into too much detail here, but the low-latency persistent connections that WebScokets provide have a temendous potential for boosting many web applications.&lt;/p&gt;
&lt;p&gt;Unfortunately, browser support for WebSockets is still spotty, although we&#39;ve had the basic building blocks for providing WebSocket-like functionality for some time now. &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt; patches those building blocks together, and provides WebSocket-like functionality on just about any browser imaginable.&lt;/p&gt;
&lt;p&gt;As it turns out, a few &lt;em&gt;servers&lt;/em&gt; also don&#39;t quite support WebSockets yet. Long story, but until the Windows world &lt;a href=&quot;http://www.paulbatum.com/2011/09/getting-started-with-websockets-in.html&quot;&gt;migrates to IIS 8&lt;/a&gt;, there&#39;s also no WebSocket support in IIS. Fortunately, the &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt;&#39;s Node.js-based server component lets us use &lt;a href=&quot;http://en.wikipedia.org/wiki/Comet_%28programming%29#Ajax_with_long_polling&quot;&gt;AJAX Long Polling&lt;/a&gt; to simulate the same functionality, with WebSocket-like semantics. It&#39;s not perfect, but it works, and be modified to use actual WebSockets with almost no code changes (once you get a server that supports &amp;quot;real&amp;quot; WebSockets).&lt;/p&gt;
&lt;p&gt;In any event, if you&#39;re stuck with IIS 7.5, you can still use &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt; today. This isn&#39;t particualrly well-documented, and there are some &lt;a href=&quot;https://github.com/tjanczuk/iisnode/issues/35&quot;&gt;needlessly complicated workarounds&lt;/a&gt; floating around, so here&#39;s how you should do it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href=&quot;http://nodejs.org/&quot;&gt;Node&lt;/a&gt; and &lt;a href=&quot;https://github.com/tjanczuk/iisnode&quot;&gt;iisnode&lt;/a&gt;. (More on that &lt;a href=&quot;http://tomasz.janczuk.org/2011/08/hosting-nodejs-applications-in-iis-on.html&quot;&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;In your node application&#39;s folder, grab &lt;a href=&quot;http://socket.io/&quot;&gt;socket.io&lt;/a&gt; with npm:&lt;br&gt;
&lt;code&gt;npm install socket.io&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create your &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt; server application, and a client. Be sure to &lt;a href=&quot;https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO&quot;&gt;configure&lt;/a&gt; &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt; with a &lt;code&gt;resource&lt;/code&gt; parameter on both your client and server.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&#39;s a barebones example to get you started. In practice, you&#39;ll probably want to use URL rewriting (and &lt;a href=&quot;http://expressjs.com/&quot;&gt;Express&lt;/a&gt;) so you can also serve up other content.&lt;/p&gt;
&lt;p&gt;On the server (&lt;code&gt;myApp/server.js&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;http&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;handler&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    io &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;socket.io&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;io&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  io&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;transports&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;xhr-polling&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Use long-polling instead of websockets!&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  io&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;resource&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/myApp/server.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Where we&#39;ll listen for connections.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;res&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;  &lt;span class=&quot;token comment&quot;&gt;/*&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;   *  Your code for handling non-websocket requests...&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;   *  Note that Socket.IO will intercept any requests made&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;   *  to myApp/server.js without calling this handler.&lt;/span&gt;&lt;br&gt;   */&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;io&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sockets&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;connection&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;New Connection&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;message&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;message&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Message Received&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;    client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;response&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Got it!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And on the client (which can be hosted anywhere):&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;highlight-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/path-to-socket.io-client/socket.io.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;application/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;   &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; socket &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; io&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;http://myServer&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;resource&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;myApp/server.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//Same resource as the server. socket.on(&#39;response&#39;,&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Message received:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;highlight-line&quot;&gt;  socket&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;message&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;hi&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In practice, you&#39;ll probably want to set up URL rewriting to rewrite requests for anything inside &lt;code&gt;/myApp/*&lt;/code&gt; to &lt;code&gt;server.js&lt;/code&gt;. In my case, I rewrite &lt;code&gt;myApp/socket&lt;/code&gt; to &lt;code&gt;server.js&lt;/code&gt; in &lt;code&gt;web.config&lt;/code&gt;, and specify &lt;code&gt;myApp/socket&lt;/code&gt; as the &lt;code&gt;resource&lt;/code&gt; parameter on both the client and server.&lt;/p&gt;
</content>
	</entry>
	
	<entry>
		<title>Hello.</title>
		<link href="https://schmod.com/posts/hello/"/>
		<updated>2019-05-13T00:41:14.227+00:00</updated>
		<id>https://schmod.com/posts/hello/</id>
		<content type="html">&lt;p&gt;Hi there.&lt;/p&gt;
&lt;p&gt;It&#39;s been a while since I&#39;ve had a proper home on the web. To say that I&#39;ve neglected this home is something of an understatement – the service that hosted my old blog shut down, and several years passed before I realized anything had happened.&lt;/p&gt;
&lt;p&gt;With any luck, this site will become a sporadically-updated collection of musings, links, recommendations, and esoterica. I intend to focus on &amp;quot;recommendations&amp;quot; over &amp;quot;reviews,&amp;quot; as I have little interest in being a critic, as &lt;a href=&quot;https://pitchfork.com/&quot;&gt;others&lt;/a&gt; seem to have covered that ground in tedious and excruciating detail. Similarly, I&#39;m opting to self-publish, as I have very little desire to &lt;a href=&quot;https://www.wired.co.uk/article/doug-rushkoff-hello-etsy&quot;&gt;produce free content&lt;/a&gt; for the benefit of large corporations run by &lt;a href=&quot;https://www.huffpost.com/entry/jack-dorsey-twitter-interview_n_5c3e2601e4b01c93e00e2a00&quot;&gt;horrible people&lt;/a&gt;. As I&#39;ve found my social media output dwindling due to my dissatisfaction with these platforms, I&#39;ve felt an increasing need to an alternative outlet for online expression. Maybe this will be it.&lt;/p&gt;
&lt;p&gt;I have few delusions that I will achieve any level of popularity or notoriety here. My previous attempt to establish a public internet presence produced little of interest, apart from, ironically, an &lt;a href=&quot;https://www.flickr.com/photos/schmod/419640051/in/photolist-D5Lni&quot;&gt;extremely popular&lt;/a&gt; photograph of a blank sheet of paper. I&#39;m okay with this – being internet-famous sounds awful.&lt;/p&gt;
&lt;p&gt;On the other hand, if you &lt;em&gt;do&lt;/em&gt; want to follow me, you&#39;ll be able to do so at your own convenience. There are no logins, no ads, and an &lt;a href=&quot;https://schmod.com/feed/feed.xml&quot;&gt;RSS Feed&lt;/a&gt; is available.&lt;/p&gt;
&lt;p&gt;Anyway. We&#39;ll see where this goes.&lt;/p&gt;
</content>
	</entry>
</feed>
