<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Socket.io &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/socket-io/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Sun, 22 Dec 2013 01:58:46 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>&#034;WebSocket&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/22/jaac2013-w-websocket.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Sun, 22 Dec 2013 01:58:46 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Socket.io]]></category>
		<category><![CDATA[WebSocket]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3781</guid>

					<description><![CDATA[&#8220;W&#8221; は WebSocket の &#8220;W&#8221;。 WebSocket WebSocket は、サーバーとクライアント間の双方向の通信をスムーズに行う為の技術です。 XMLHtt [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;W&#8221; は WebSocket の &#8220;W&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh4.googleusercontent.com/-nLLyR4zNEGA/UqR4mAUDnyI/AAAAAAAACYg/LwX_sRpA7Xk/s400/ac2013-w.png" alt="W"/></figure>



<p></p>



<span id="more-3781"></span>



<h2 class="wp-block-heading">WebSocket</h2>



<p><strong>WebSocket</strong> は、サーバーとクライアント間の双方向の通信をスムーズに行う為の技術です。 XMLHttpRequest のように都度リクエストを送るのではなく、 一旦コネクションが貼られた後はそのコネクション上でメッセージを送り合ってデータのやり取りを行う為、 よりリアルタイム性が必要なアプリケーション、例えばチャットやオンラインゲーム等での活躍が期待されます。</p>



<h2 class="wp-block-heading">Socket.io</h2>



<p>WebSocket を恐ろしく簡単で使いやすい物に変えてしまうのが <strong>Socket.io</strong> です。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><a href="http://socket.io/">http://socket.io/</a><br />
  Socket.IO aims to make realtime apps possible in every browser and mobile device, blurring the differences between the different transport mechanisms. It&#8217;s care-free realtime 100% in JavaScript.</p>
</blockquote>



<p>node.js で楽にWebSocketのサーバが立ち上がるうえ、クライアントサイドでは WebSocket に非対応な環境の為に、 Flash で ActionScript3 の WebSocket API を使用してフォールバックを備えてくれています。</p>



<h3 class="wp-block-heading">WebSocket サーバの起動</h3>



<p>まず socket.io をインストールしましょう。</p>


<pre class="wp-block-code"><span><code class="hljs">$ npm install socket.io
</code></span></pre>


<p>そして起動用のスクリプトを書きます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// server.js</span>
<span class="hljs-keyword">var</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>).listen(<span class="hljs-number">8080</span>);
io.sockets.on(<span class="hljs-string">"connection"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">socket</span>)</span>{
    socket.emit(<span class="hljs-string">"hello"</span>, {<span class="hljs-attr">message</span>: <span class="hljs-string">"Thanks to connect !"</span>});
});
</code></span></pre>


<p>これは接続したクライアントに &#8220;hello&#8221; メッセージを送るだけのコードです。</p>



<p><strong>listen</strong> メソッドでポートを指定してサーバを起動します。 <strong>io.sockets.on</strong> メソッドでは、新たにリクエストのあったコネクションを受け取り、 そのコールバックの中で <strong>emit</strong> コマンドでクライアント側にメッセージを送ります。</p>



<p>node コマンドで WebSocket サーバを起動します。</p>


<pre class="wp-block-code"><span><code class="hljs">$ node server.js
</code></span></pre>


<p>これでサーバが立ち上がったと思います。 デーモン化したい時には <a href="https://github.com/nodejitsu/forever">forever</a> が便利です。</p>



<h3 class="wp-block-heading">クライアント側の処理</h3>



<p>WebSocketとは別に、Webサーバが立ち上がっていると仮定しましょう。 クライアント側では <strong>socket.io-client</strong> を使って WebSocket に接続します。 <strong>socket.io-client</strong> は bower でも npm でもインストールできます。</p>


<pre class="wp-block-code"><span><code class="hljs">$ bower install socket.io-client
</code></span></pre>


<p>ここではサーバから送った &#8220;hello&#8221; メッセージを受け取ってみます。</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"bower_components/socket.io-client/dist/socket.io.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
    <span class="hljs-keyword">var</span> socket = io.connect(<span class="hljs-string">"http://example.com:8080"</span>);
    socket.on(<span class="hljs-string">"hello"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{
        <span class="hljs-built_in">console</span>.log(data.message); <span class="hljs-comment">// "Thanks to connect !"</span>
    });
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
</code></span></pre>


<p>サーバから <strong>emit</strong> で送ったメッセージは、クライアント側で <strong>on</strong> で受け取る事ができます。 逆に、サーバ側にメッセージを送る時はクライアント側で <strong>emit</strong> し、サーバ側で <strong>on</strong> で受け取ります。</p>



<h3 class="wp-block-heading">全てのソケットにメッセージを送る</h3>



<p>上のサーバスクリプトでは、引数で渡された <strong>socket</strong> オブジェクトで emit を行っていましたが、 この socket はそのクライアントのみのコネクションです。 接続している全てのユーザにメッセージを送りたい場合は、socket にぶら下がっている broadcast を使用します。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">socket.emit(<span class="hljs-string">"message"</span>, ... ); <span class="hljs-comment">// 自分にメッセージを送る</span>
socket.broadcast.emit(<span class="hljs-string">"message"</span>, ...); <span class="hljs-comment">// 自分以外にメッセージを送る</span>
</code></span></pre>


<p>broadcast は自分以外のコネクションを指します。</p>



<h2 class="wp-block-heading">極めてシンプルなチャットの習作</h2>



<p>Socket.io を使って極めてシンプルなチャットプログラムを作ってみます。 上で挙げた機能のみを使用して、その場限りのチャットをする事が出来ます。 ルームや認証などは一切省いています。</p>



<p>まずHTMLは、ニックネームとメッセージを入力するインプットと、メッセージログを出力する #log で構成されます。</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-comment">&lt;!-- HTML --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"form-message"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>ニックネーム: <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"nickname"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>メッセージ: <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"log"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></span></pre>


<p>次にクライアント側の JavaScript ですが、例をシンプルにする為に jQuery を使用します。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">/* クライアント JavaScript */</span>
<span class="hljs-keyword">var</span> socket = io.connect(<span class="hljs-string">"http://example.com:8080"</span>);

socket.on(<span class="hljs-string">"connect"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    $(<span class="hljs-string">"#nickname"</span>).on(<span class="hljs-string">"change"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
        socket.emit(<span class="hljs-string">"set nickname"</span>, {
            <span class="hljs-attr">nickname</span>: <span class="hljs-keyword">this</span>.value
        });
    });
    $(<span class="hljs-string">"#form-message"</span>).on(<span class="hljs-string">"submit"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
        e.preventDefault();
        <span class="hljs-keyword">var</span> input = $(<span class="hljs-string">"#message"</span>);
        socket.emit(<span class="hljs-string">"send message"</span>, {
            <span class="hljs-attr">message</span>: input.val()
        });
        input.val(<span class="hljs-string">""</span>);
    });
});

socket.on(<span class="hljs-string">"message"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{
    $(<span class="hljs-string">"&lt;li&gt;"</span>).append($(<span class="hljs-string">"&lt;strong&gt;"</span>).text(data.nickname))
    .append($(<span class="hljs-string">"&lt;span&gt;"</span>).text(data.message))
    .prependTo(<span class="hljs-string">"#log"</span>);
});
</code></span></pre>


<p>クライアントサイドの JavaScript はこのような働きをします。</p>



<ul class="wp-block-list">
<li>#nickname の内容が変更されると <strong>&#8220;set nickname&#8221;</strong> メッセージを送ってニックネームを変更する</li>



<li>#form-message がサブミットされると、#message から <strong>&#8220;send message&#8221;</strong> でメッセージを送信する</li>



<li>サーバから <strong>&#8220;message&#8221;</strong> が届いたら、 #log の中に追加して表示する</li>
</ul>



<p>最後にサーバ側では、上記の処理をサポートするように記述します。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">/* サーバ JavaScript */</span>
<span class="hljs-keyword">var</span> io = <span class="hljs-built_in">require</span>(<span class="hljs-string">'socket.io'</span>).listen(<span class="hljs-number">8080</span>);

io.sockets.on(<span class="hljs-string">"connection"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">socket</span>)</span>{
    <span class="hljs-keyword">var</span> anonymous = <span class="hljs-string">"名無しさん"</span>;
    <span class="hljs-keyword">var</span> nickname = <span class="hljs-literal">null</span>;
    socket.on(<span class="hljs-string">"set nickname"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{
        nickname = data.nickname;
    });
    socket.on(<span class="hljs-string">"send message"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{
        <span class="hljs-keyword">if</span>(! data.message){ <span class="hljs-keyword">return</span>; }
        <span class="hljs-keyword">var</span> vars = {
            <span class="hljs-attr">nickname</span>: nickname || anonymous,
            <span class="hljs-attr">message</span>: data.message
        };
        socket.emit(<span class="hljs-string">"message"</span>, vars);
        socket.broadcast.emit(<span class="hljs-string">"message"</span>, vars);
    });
});
</code></span></pre>


<p>socket オブジェクトには set/get が実装されており、その接続毎のデータを保持する事ができますが、 コールバックを受け取るタイプで少し例が冗長になってしまう為、ここでは単なる変数として <strong>nickname</strong> を定義しています。</p>



<p>WebSocket の働きが、なんとなく伝わったでしょうか。</p>



<h2 class="wp-block-heading">その他のヒント</h2>



<h3 class="wp-block-heading">限定されたユーザにメッセージを送りたい</h3>



<p>例えばチャットルームのような物が存在していて、その中だけでメッセージをやりとりしたい時の為に、 Socket.io には <a href="https://github.com/LearnBoost/socket.io/wiki/Rooms">「ルーム機能」</a> なる物があります。 ルームは入室・退室する事ができ、そのルームの中にいるメンバーだけに通知をする事ができます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">/*  サーバ JavaScript */</span>
socket.join(<span class="hljs-string">"ChatRoom"</span>); <span class="hljs-comment">// 入室します</span>
socket.leave(<span class="hljs-string">"ChatRoom"</span>); <span class="hljs-comment">// 退室します</span>
io.sockets.in(<span class="hljs-string">"ChatRoom"</span>).emit( ... ); <span class="hljs-comment">// ルーム内のメンバーにだけ emit</span>
</code></span></pre>


<p>ルーム内にメッセージを送るには、<strong>io.sockets</strong> を <strong>in()</strong> メソッドで絞り込んで emit します。</p>



<p>また、コネクションからクライアントを切り分ける <a href="http://socket.io/#how-to-use">ネームスペース機能</a> という物もあります。 &#8220;/chat&#8221; のようにネームスペースを定義してそこに接続したクライアントだけでデータのやり取りをします。 サーバ側では <strong>of()</strong> でクライアントを絞り込んで処理をかき分けます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">/*  サーバ JavaScript */</span>
<span class="hljs-keyword">var</span> chat = io.sockets.of(<span class="hljs-string">"/chat"</span>);
chat.on(<span class="hljs-string">"connection"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">socket</span>)</span>{
    socket.on(<span class="hljs-string">"send message"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data</span>)</span>{
        chat.emit( ... );
    });
});
</code></span></pre>


<p>クライアント側では、コネクション時に &#8220;/chat&#8221; を足して接続します。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">/* クライアント JavaScript */</span>
<span class="hljs-keyword">var</span> socket = io.connect(<span class="hljs-string">"http://example.com:8080/chat"</span>);
</code></span></pre>


<p>また、ネームスペースとルーム両方で絞り込む事もできます。</p>



<h3 class="wp-block-heading">セッションを管理したい</h3>



<p>socket.io のセッションは基本的にその接続限りです。 ページをリロードしたり、新しいタブで開いたりした時点で新しいコネクションが貼り直され、id も更新されてしまいます。 その為、認証などでセッションの保持をしたい場合は少し工夫が必要です。</p>



<p><a href="https://github.com/learnboost/socket.io/wiki">socket.io の wiki</a> にいくつかその為のレシピやモジュールが公開されていますが、 基本的に <strong>express</strong> や <strong>connect</strong> など、node.js ベースの解決策になっているので、 socket.io を採用する場合はWebサーバも express を選択した方が良さそうですね。 （特に他の物を使う理由もなさそうですが）</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><a href="https://github.com/wcamarao/session.socket.io">session.socket.io (SessionSockets) </a><br />
  This tiny node module simplifies your web sockets app when using http sessions from express or connect middlewares. It has no dependencies and can be initialized using any session store and cookie parser compatible with express or connect.</p>
</blockquote>



<p>こちらは socket.io でセッションを管理する為の node モジュールです。</p>



<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="http://ja.wikipedia.org/wiki/WebSocket">WebSocket &#8211; Wikipedia</a></li>



<li><a href="http://socket.io/">Socket.IO: the cross-browser WebSocket for realtime apps.</a></li>



<li><a href="https://github.com/learnboost/socket.io/wiki">Home · LearnBoost/socket.io Wiki</a></li>



<li><a href="http://d.hatena.ne.jp/Jxck/20110730/1312042603">Socket.IO API 解説 &#8211; Block Rockin’ Codes</a></li>



<li><a href="https://github.com/wcamarao/session.socket.io">session.socket.io (SessionSockets) </a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
