Page List

Search on the blog

ラベル WEB の投稿を表示しています。 すべての投稿を表示
ラベル WEB の投稿を表示しています。 すべての投稿を表示

2016年8月17日水曜日

httpbinでテストする

Pythonのurllib3のRetry、Timeoutの動作確認をするためにテスト用のサーバを書こうかどうか迷っていたところ、httpbinという便利なサイトを見つけた。
これは便利。

指定したステータスコードを返す
https://httpbin.org/status/:code
をたたくと、指定した:codeをステータスコードとして返してくれます。

urllib3でステータスコードが400、500番台の場合はバックオフしてリトライするコードをhttpbinで動作確認。
from urllib3.util import Retry
from urllib3 import PoolManager

http = PoolManager(retries=Retry(total=4, backoff_factor=1.0, status_forcelist=range(400, 600)))

response = http.request('GET', 'https://httpbin.org/status/500')
print ("status code=%s." % response.status)

指定した秒だけ待ってレスポンスを返す
https://httpbin.org/delay/:n
をたたくと、min(n, 10)秒間待ってレスポンスを返してくれます。

urllib3のTimeoutの動作確認用ソースです。5秒たつとtimeoutエラーが発生します。
from urllib3.util import Retry, Timeout
from urllib3 import PoolManager

http = PoolManager(timeout=Timeout(5))

response = http.request('GET', 'https://httpbin.org/delay/8', retries=False)
print ("status code=%s." % response.status)

timeoutしても頑張るバージョン。
from urllib3.util import Retry, Timeout
from urllib3 import PoolManager

timeout = Timeout(5)
retries = Retry(total=4, backoff_factor=1.0, status_forcelist=range(400, 600))

http = PoolManager(timeout=timeout, retries=retries) 
response = http.request('GET', 'https://httpbin.org/delay/8')
print ("status code=%s." % response.status)
この場合は、4回リトライしtimeoutエラーになります。

2016年8月12日金曜日

TornadoでWebSocketを使ってみた

WebSocketとは?
ウェブサーバとウェブブラウザ間で双方向通信を行うための規格。
WebSocketを使うことで、サーバ側からクライアント側にプッシュ配信を行うことができる。通信ごとにコネクションを張り替えるのではなく、すべての通信を一つのコネクションで行うことができる。

Tornadoとは?
PythonのWebフレームワーク/非同期通信のライブラリ。
数万単位のコネクションにスケールすることができ、WebSocketのようにユーザごとに長期のコネクションを構築しておきたい場合に有用。

サンプル
チャットアプリを作ってみた。

サーバ側のコード。
tornado.websocket.WebSocketHandlerクラスを継承して、必要なイベントハンドラメソッドをオーバーライドすればよい。

import tornado.ioloop
import tornado.web
import tornado.websocket

class ChatHandler(tornado.websocket.WebSocketHandler):
 clients = []

 def open(self):
  if self not in ChatHandler.clients:
   ChatHandler.clients.append(self)

 def on_message(self, message):
  for c in ChatHandler.clients:
   c.write_message(message)

 def on_close(self):
  if self in ChatHandler.clients:
   ChatHandler.clients.remove(self)

class MainHandler(tornado.web.RequestHandler):
 def get(self):
  self.render('main.html')

if __name__ == "__main__":
 application = tornado.web.Application([
  (r"/chat/main.html", MainHandler),
  (r"/chat/websocket", ChatHandler),
 ])
 application.listen(8888)
 tornado.ioloop.IOLoop.current().start()

クライアント側のコード。WebSocketクラスを使って接続、メッセージ送信、メッセージ受信時の処理を行う。
<!DOCTYPE html>
<html>
  <head>
    <title>websocket chat</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
    <script>
      $(function() {
        socket = new WebSocket("ws://kenjih.com:8888/chat/websocket");
        socket.onopen = function() {};
        socket.onmessage = function(e) {
          $("#msgbox").append($('<p>'+e.data+'</p>'));
        };
        $('#send').click(function(){
          socket.send($('#msg').val());
          $('#msg').val('');
        });
        $('#msg').keydown(function(e) {
          if (e.keyCode == 13) {
            socket.send($('#msg').val());
            $('#msg').val('');
          }
        });
      });
    </script>
  </head>
  <body>
    <div class="container">
      <div class="row">
      <h1>Websocket Chat Room</h1>
      </div>
      <div class="row">
        <div class="col-xs-5">
          <div class="input-group">
            <input id="msg" type="text" class="form-control" placeholder="put your message...">
            <span class="input-group-btn">
              <button id="send" class="btn btn-primary" type="button">Send</button>
            </span>
          </div>
        </div>
        <div class="col-xs-7">
          <div class="panel panel-primary">
            <div class="panel-heading">
              <h3 class="panel-title">Messages</h3>
            </div>
            <div id="msgbox" class="panel-body"></div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>

2015年4月1日水曜日

リキッドレイアウトとレスポンシブデザイン

語句の意味
リキッドレイアウトとは、%を使ってウェブサイトをデザインすること。これにより、画面サイズが変わっても各エレメントが占める空間の割合が一定となる[1]。
 レスポンシブデザインとは、CSS Media Queries[2]を利用することで画面サイズに応じて異なるレイアウトを提供する手法のこと[1]。

デモ
まず普通のデザイン。各エレメントのサイズはpxで指定している。

sample1

画面サイズを小さくすると以下のように右側が隠れてしまう。


これをリキッドレイアウトに変更する。

sample2

すると、画面サイズを小さくしても右側が隠れない。各エレメントの幅の”割合”はディスプレイサイズによらず一定となる。


ちょっと詰まったところが、borderやpaddingの指定。divのwidthは%指定できてもborderはpx指定なのでサイズをピッタリ合わせるのが難しかった。
どうやらそういうときは、

box-sizing: border-box;

という指定をするらしい。この指定により、borderやpaddingが要素の幅に含まれるようになるらしい[3]。

リキッドレイアウトで画面サイズの問題は解決したように思えるが、さらにサイズを小さくすると以下のようになってしまう。


divエレメント内の文字が全部表示されていない。

これをレスポンシブデザインを使って解決してみる。

sample3

上のサンプルでは、CSS Media Queriesを使って画面サイズが500px以下になるレイアウトを変更するようにしている。これにより画面サイズを大幅に小さくした場合の対応が出来る。

今回の例では画面幅が500px以下になると、
  • 文字サイズ
  • メニューの段組
  • ヘッダーの文字色
を変更するようにしてみた。




参考ページ
[1] terminology - What is the exact difference between fluid and responsive design? - User Experience Stack Exchange
[2] CSS3 @media Rule
[3] box-sizing-CSS3リファレンス

2013年8月13日火曜日

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

 『「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか』を読みました。昨年新入社員研修の講師をしていたときに、マネジャーの方が新人たちに勧めていたのでどんなものかなと思って読んでみました。

 インターネットの歴史、インターネットの発展とともにどのような要求が生まれたか、その要求を満たすためにどのような技術が作られたかということがわかりやすく書かれていました。

 だいたい知ってることが多かったですが、よくまとめられていて、これまで学んだことを効率的に復習することができました。

 扱っているトピックは、
  • クライアントとサーバー
  • URLとURI
  • GETとPOST
  • CGIとサーブレット
  • HTTPプロトコルについて
  • Cookieとセッション
  • 三層構成(Webサーバー、アプリケーションサーバー、DBサーバー)
  • MVCモデルを実現するフレームワーク(Struts 1を例に)
  • O/Rマッピング(iBATISを例に)
  • セキュリティ(SQLインジェクション、XSS、セッションハイジャック、CSRFなど)

と多岐に渡り、最低限知っておくべきことはほぼ網羅されているのかなと思います。

そしてこの本の一番いいところは、「今の業界ではこうするのが常識だ!」、「この技術を使いなさい!」と押し付けるのではなく、

  • なぜその技術を使用する必要があるのか?
  • その技術が生まれる前はどのような問題があったのか?
  • その技術のおかげでどのようなメリットがえられるのか?

をきちんと説明してくれるところです。この価格で、扱ってるテーマも広いのに、ここまで丁寧に説明してくれる本はなかなかないのではと思います。エンジニア一年生に勧めるべき最高の本です。

2013年7月20日土曜日

TCPとは何か?

分かってるようで分かっていなかったので、概要レベルでまとめてみた。

wikipediaより
  • Internet protocol suiteの中核をなすプロトコル(決まりごと)の一つ。
  • TCPはとても重要なので、Internet protocol suite全体を指してTCP/IPと呼ぶことがある。
Internet protocol suiteっていうのは、HTTPとかFTPとかSSHとかTCPとかUDPとか・・・インターネットのために使われるコミュニケーションプロトコルの集まりのこと。


searchnetworkingより
  • インターネット上のコンピュータ間のデータ転送を行うための決まりごと。
  • TCPは効率的なネットワーク上のルーティングのために分割された個々のデータ(パケット)の管理を行う。
  • 例えばWEBサーバーのTCPレイヤーは、HTMLファイルを複数のパケットに分割し、パケットの数を数え、個々のパケットをIPレイヤーに渡す。それぞれのパケットの行き先は同じIPアドレスだったとしても、それぞれのパケットは異なるルーティングをされるかもしれない。
  • クライアントサイドでは、TCPはパケットが送られてくるのを待って、パケットを一つの元のファイルに組み立て直す。
要するに、TCPの役割はデータをパケットに分割すること + 受け取り側で分割されたパケットを組み立てること。
なぜそんなことが必要かというと、効率的にデータを転送するため。(パケットを使わずに一気に送ろうとすると、何らかの理由で相手に届かなかったとき最初からすべて送り直さないといけないので非効率。パケットを使うと、届かなかったパケットがあった場合そのパケットだけを再送すればいい。)


Reference
[1] https://en.wikipedia.org/wiki/Transmission_Control_Protocol
[2] http://searchnetworking.techtarget.com/definition/TCP