tag:blogger.com,1999:blog-69184955449249061922024-02-08T14:22:23.994+09:00idee blogAnonymoushttp://www.blogger.com/profile/14223142502042644833noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-6918495544924906192.post-35288155710559797602015-05-25T16:26:00.004+09:002015-05-26T12:39:47.022+09:00ファイル直送サービス DirectSEND リリース<h3>
本日、ファイル<b>直送</b>サービス DirectSEND をリリースしました。</h3>
<a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="http://directsend.me/">http://directsend.me</a><br />
<br />
<br />
<div style="text-align: left;">
クラウドサーバに保存することなく、相手に直接転送する Web サービスです。</div>
ブラウザさえあれば、どなたでも<b><span style="font-size: large;">無料</span></b>かつ<b><span style="font-size: large;">容量無制限</span></b>でご利用になれます。ユーザー登録も<span style="font-size: large;">不要</span>です。もちろん、スマートフォンからも利用できます。<br />
<br />
<br />
一時的でもクラウドにファイルを置くのはなんだか嫌だな、と思うあなたにぴったり。メールに添付できないような少し大きいファイルを今すぐ送りたい時にも、きっと役立ちます。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4ewlxPRUM3_GurgFtF_5akjMN40nLUwRyyoUYTbTdKmvy2SAJAwgaHdTFKmMh2GiU8WA51-HDEvkO0eeH7BRqn6nQJ1keSyqW4R9KVFG-TDjPxSsjrUAX6ZUtHWCIfr94rhrsKJrbCjA/s1600/directsend.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4ewlxPRUM3_GurgFtF_5akjMN40nLUwRyyoUYTbTdKmvy2SAJAwgaHdTFKmMh2GiU8WA51-HDEvkO0eeH7BRqn6nQJ1keSyqW4R9KVFG-TDjPxSsjrUAX6ZUtHWCIfr94rhrsKJrbCjA/s320/directsend.png" width="320" /></a> </div>
<h3>
<a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a>
</h3>
<h3>
使い方 </h3>
送信側<br />
<ol>
<li>本サイトで、<b>送るボタン</b>を押して、ファイルを選択します。<br /> </li>
<li>画面に表示された4桁の<b>キーコード</b>を受信者にメールやSNSで伝えます。</li>
<li>あとは受信者がファイルを受信するまで待ちましょう。 </li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjazEOG2qUC0tCEB1ynHRMhTEqX3EE8ZvJWbLY9oZI8tz1tlCByzO9a-bep0FX7s6pkHPUL532Yheo9EDPpILlk7XSZU4W4gCD4sjMWzo8bNwsrRp6Qc6hcU8t9xKzNrjln7i1u9FX47Wo/s1600/waiting.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjazEOG2qUC0tCEB1ynHRMhTEqX3EE8ZvJWbLY9oZI8tz1tlCByzO9a-bep0FX7s6pkHPUL532Yheo9EDPpILlk7XSZU4W4gCD4sjMWzo8bNwsrRp6Qc6hcU8t9xKzNrjln7i1u9FX47Wo/s320/waiting.png" width="320" /></a></div>
<br />
<a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=6918495544924906192" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><br />
※ ワンクリックURLを使えば、クリックするだけで受信が始まるので便利です。<br />
<ol>
</ol>
<div style="text-align: center;">
</div>
<br />
受信側<br />
<ol>
<li>サイトにアクセスし、受け取り入力欄に4桁のキーコードを入力して、受け取るボタンを押します。</li>
<li>ファイルの受信が始まります。完了するまで待ちましょう。 </li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieM4BsU2CuXdLLEDD0xj59LgTQpimZVJQGdfXXNBH9PI70SilPL-qidzyMqBazcV5ccOOXpOl9YLAPmEJDjxENPB8ogSuCFHsH9vr1loP37VOrdy4gu7E7J63l5lperZ8xyxeFZshdmDk/s1600/receive.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="108" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieM4BsU2CuXdLLEDD0xj59LgTQpimZVJQGdfXXNBH9PI70SilPL-qidzyMqBazcV5ccOOXpOl9YLAPmEJDjxENPB8ogSuCFHsH9vr1loP37VOrdy4gu7E7J63l5lperZ8xyxeFZshdmDk/s320/receive.png" width="320" /></a></div>
<br />
<br />
たったこれだけです!<br />
<h4>
お気軽に利用してみてください。</h4>
<br />
<br />Anonymoushttp://www.blogger.com/profile/14223142502042644833noreply@blogger.com2tag:blogger.com,1999:blog-6918495544924906192.post-5767714256440470202015-04-24T17:41:00.004+09:002015-05-25T16:34:48.915+09:00サーバサイドで WebSocket を実装するための基礎<h3>
</h3>
比較的シンプルな仕様である WebSocket ですが、サーバサイドフレームワークからの視点で見ると留意しなければならない点が幾つかあります。<br />
<br />
<ul>
<li> <a href="http://ja.wikipedia.org/wiki/WebSocket" rel="nofollow" target="_blank">WebSocket</a> の事前知識として<a href="http://blog.ideeinc.co.jp/2015/04/websocket.html" target="_blank">こちらの記事</a>もご覧ください</li>
</ul>
<br />
<h4>
<span style="color: #0b5394;">多数の同時接続</span></h4>
一旦接続が成立すると、どちらかから切断しないかぎり、そのまま保持されます。WebSocket を使うサーバサイドは、同時に接続するクライアントの数が膨大になることを想定しなければなりません。いわゆる C10K 問題(クライアント1万台問題)です。<br />
<br />
これを軽減するには、Linux では epoll システムコール、BSD の場合は kqueue システムコールなどの<b><span style="color: red;">多重I/Oを使ったソケットの監視が必須</span></b>となります。<br />
<br />
<br />
また、リスエストを処理する部分については、1つの重い処理に引きずられて他のリクエストのレスポンスが遅くなっていはいけませんので、1リクエストを処理するのに1スレッド(または1プロセス)を割り当てることを考えなければなりません。スレッドもリソースを消費するので、無尽蔵に生成されないよう注意する必要があります。<br />
<br />
※ 1つの接続に対し<u>常時1つのスレッドが必要という意味ではありません</u><br />
<br />
<br />
このような理由で、シングルスレッドのイベント駆動型モデルの実装(node.jsなど)には問題があると言えるでしょう <span style="font-size: x-small;">※1</span>。但し、アプリが実行する処理が単純で、重い処理が全くないという場合はこの問題は当てはまりませんが、どのような要求にも対応すべき必要がある開発フレームワークとしてはあまり考えられないアーキテクチャだと思います。<br />
<br />
<span style="font-size: x-small;">※1 サーバをマルチプロセス化するという軽減策もでてきているが根本的な解決策ではないでしょう</span><br />
<br />
<h4>
<span style="color: #0b5394;">キープアライブ</span></h4>
通信相手がダウンしていないかどうか、または通信路が確立されているかどうかをチェックするための定期的な通信。<br />
<br />
TCPにもキープアライブの機能がありますが、ここはアプリケーションレイヤーの話です。<br />
<br />
WebSocket では長時間接続し続けることが想定されています。通信相手のプログラムがダウンしていなくとも、無通信状態が長く続くと通信路の途中にあるルータなどの機器がポートを閉じてしまうケースがあります。<br />
<br />
これを回避するため、無通信時間があまり長くならないようピン/ポンフレームを送受信しなければなりませんが、2015年4月現在、ブラウザ上のスクリプトからこれらのフレームを送る仕組み(API)はありません。<br />
<br />
従って、サーバサイドからピン/ポンフレームを<span style="color: red;"><b>定期的または任意のタイミングで送る仕組みが必要</b></span>となります。<br />
<br />
<br />
<h4>
<span style="color: #0b5394;">クライアントへのブロードキャスト</span></h4>
チャットアプリを想像すると分かりやすいですが、ある人が書いたコメントはそのグループ全員に直ちに通知されます。このようにメッセージを多数のクライアントへ一括送信できる「ブロードキャスト」の仕組みが必要です。<br />
<br />
解決策として「<a href="http://ja.wikipedia.org/wiki/%E5%87%BA%E7%89%88-%E8%B3%BC%E8%AA%AD%E5%9E%8B%E3%83%A2%E3%83%87%E3%83%AB" rel="nofollow" target="_blank">出版-購読型モデル</a>」のアーキテクチャは考えられます。アプリケーションサーバ自体にこの仕組があることが望まれます。<br />
<br />
規模が巨大なシステムの場合は、負荷分散のためにアプリケーションサーバのホストを複数設置することになるので、別のプロダクト(Redisなど)と組み合わせて実現することになるでしょう。<br />
<br />
<h4>
<span style="color: #0b5394;">データベースへのアクセス</span></h4>
敢えて書くまでもないかもしれませんが、HTTP/HTML のWebアプリと同様に、データベースとのデータの受け渡しができなければなりません。トランザクションについても機能が実装されているかどうかチェックしましょう。<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14223142502042644833noreply@blogger.com1tag:blogger.com,1999:blog-6918495544924906192.post-77916252061860453332015-04-24T14:54:00.003+09:002015-05-25T16:34:48.919+09:00WebSocket プロトコルの話<br />
HTML5 で標準化された WebSocket は、Webサーバ(アプリケーションサーバ)とクライアント(主にブラウザ)との双方向通信を実現するものです。一度接続をするとサーバサイドからも好きなタイミングでデータを送ることができます。近頃のブラウザであればほぼ実装されています。(実装されていないブラウザはあるのか。。)<br />
<br />
プロトコルの仕様は <a class="external mw-magiclink-rfc" href="http://tools.ietf.org/html/rfc6455" rel="nofollow">RFC6455</a> として標準化されています。 <br />
<div style="text-align: left;">
</div>
WebSocket は 基本 80 番ポートの TCP 通信であるので、一度接続ができてしまえば任意のタイミングで <b><span style="color: red;">NAT</span></b><b style="color: red;">を越えて </b>の送受信が可能であることを意味します。プラグインを使わずに、ブラウザだけで実現できるようになったことで Web アプリの可能性が広がりました。<br />
<br />
データフレームはヘッダとペイロードで構成され、可能な限り小さくまとめられています。ヘッダ長は最小の場合2バイト、最大でも14バイトであるので、HTTP のものと比べると劇的に小さいと言えます。<br />
<br />
ヘッダが小さい上に、データ更新のための無駄なポーリングを抑えられるので、WebSocket を利用することでサーバサイドの負荷を大幅に抑えることができます。<br />
<br />
<br />
データフレーム仕様:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF4mEb9hX06vbm55vGpjQoW1W3kW4sqd1kz0L_skpS9nvU72BKXR6CGXjtkcPzNVCzeVMJQOiyAkSwyXQMgzlUQJpKCofGYxrHnQ45wNsHdRSRwRtgUByYsSez61zao5EKZj4LGjDI5Lw/s1600/BaseFramingProtocol.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF4mEb9hX06vbm55vGpjQoW1W3kW4sqd1kz0L_skpS9nvU72BKXR6CGXjtkcPzNVCzeVMJQOiyAkSwyXQMgzlUQJpKCofGYxrHnQ45wNsHdRSRwRtgUByYsSez61zao5EKZj4LGjDI5Lw/s1600/BaseFramingProtocol.png" /></a></div>
<br />
※ 単位: ビット<br />
<br />
<br />
<br />
<h4>
<span style="color: #0b5394;">オペコード ( opcode )</span></h4>
operation code の略で、何のフレームなのかを示すコードが指定される。次の種類があります。<br />
<br />
<table><thead>
<tr><th><span style="font-size: x-small; font-weight: normal;">オペコード</span></th>
<th title="Meaning"><span style="font-size: x-small; font-weight: normal;"> 意味</span></th>
<th title="Reference"><span style="font-size: x-small;"><span style="font-weight: normal;">備考</span></span></th>
</tr>
</thead>
<tbody>
<tr><th><span style="font-size: x-small; font-weight: normal;">0 </span></th><td><span style="font-size: x-small;">継続フレーム</span></td><td><span style="font-size: x-small;"> 大きなペイロードを分割して送る際に使用 </span></td></tr>
<tr><th><span style="font-size: x-small; font-weight: normal;">1 </span></th><td><span style="font-size: x-small;">テキストフレーム</span></td><td><span style="font-size: x-small;"> ペイロードがテキスト(UTF-8)</span></td></tr>
<tr><th><span style="font-size: x-small; font-weight: normal;">2 </span></th><td><span style="font-size: x-small;">バイナリフレーム</span></td><td><span style="font-size: x-small;"> ペイロードがバイナリデータ</span></td></tr>
<tr><th><span style="font-size: x-small; font-weight: normal;">8 </span></th><td><span style="font-size: x-small;">クローズフレーム</span></td><td><span style="font-size: x-small;"> コネクションを切断する際にお互いに投げ合う</span></td></tr>
<tr><th><span style="font-size: x-small; font-weight: normal;">9 </span></th><td><span style="font-size: x-small;">ピンフレーム</span></td><td><span style="font-size: x-small;"> キープアライブ用</span></td></tr>
<tr><th><span style="font-size: x-small; font-weight: normal;">10</span></th><td><span style="font-size: x-small;">ポンフレーム</span></td><td><span style="font-size: x-small;"> ピンフレームの応答</span></td></tr>
</tbody></table>
<br />
<br />
<h4>
<span style="color: #0b5394;">ピンフレーム/ポンフレーム ( Ping-Pong )</span></h4>
通信相手が応答可能な状態なのかを確かめるために使用されます。ピンフレームを受信したら、できるだけ早くポンフレームを返信しなければなりません。<br />
<br />
<span style="font-size: x-small;">※ このやりとりが卓球(ピンポン)をイメージすることにその名が由来します</span><br />
<br />
もし応答が不要な場合(一方向の確認)は、ポンフレームの送信だけで完結することができます。<br />
<br />
<br />
<h4>
<span style="color: #0b5394;">クローズフレーム</span></h4>
切断する際はクローズフレームを送信しなければなりません。これを受信した側もレスポンスとして、同じクローズフレームを返信しなければなりません。<br />
<br />
ブラウザについては、JavaScript から WebSocket の接続をしますが、そのページから離れてしまうと、あるいはページリロードをしたタイミングで、自動的にクローズフレームを投げて切断されるように実装されていました。 <br />
<br />
モバイル端末やPCがスリープモードに入ると、コネクションは切断されます。<br />
<br />
<h4>
<span style="color: #0b5394;">ペイロード長 (9ビット目から最大79ビット目まで)</span></h4>
ペイロードの長さを設定する。ペイロードの長さによって、「ペイロード長」を設定する領域やその長さが変わるのが少しややこしい(詳細は省略)。<br />
<br />
ヘッダの長さを抑えるためにそのような仕様になったと考えられます。<br />
<br />
<h4>
<span style="color: #0b5394;">ペイロード</span></h4>
実際のデータ本体。<br />
ペイロードにどんなデータを載せるかは、アプリケーション次第。フォーマットはプレーンテキスト、JSON、XML、MessagePack、独自仕様など、なんでもあり。サーバサイドとクライアントサイドで仕様を合わせれば良いです。<br />
<br />
ペイロードがテキストかバイナリか、適切な値をオペコードに設定しましょう。<br />
<br />
<h4>
<span style="color: #0b5394;">マスク処理</span></h4>
マスクフラグが1の場合に、マスキングキー(Masking-key)でペイロードデータを変換します。クライアントからサーバに送る場合はマスク処理を施さなければなりません。マスキングキーにはランダムな値が使われます。<br />
<br />
ちなみに、ブラウザではこれらが実装されているので、開発者はほとんど気にする必要はありません。<br />
<br />
<br />
<b>なぜ、わざわざ負荷のかかるマスク処理をするのか</b><br />
<br />
マスキングキーが同じフレームに載っているので、暗号化が目的でないことは分かります。<br />
<br />
マスク処理がないと、WebSocket の中継点にあるプロキシのキャッシュを汚染させることで、悪意のあるスクリプトを実行させられる攻撃が成立する可能性があるようです。この攻撃を困難にするために、クライアントが送信する場合にマスク処理が行われます。<br />
<br />
要は、WebSocket が<u>ネット攻撃のベースにならないよう</u>にするためなのです。<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14223142502042644833noreply@blogger.com1