Born Neet

- The Emotional Programmer -

Shortcut Key
Next Entry … jPrev Entry … k
Next Page … J(Shift + j)Prev Page … K(Shift + k)
Scroll Down … Space / Page Down
Scroll Up … Shift + Space / Page Up
Twitter: Do you follow me?
    2010.01.31(Sun.) 13:32
     

    今週は仕事とドラクエVIが忙しくて全然勉強の時間がとれませんでした。
    (モンスターが仲間に入らないのと難易度が下がってるのにはがっかりしましたが、やっぱり6はいいですね。)
    というわけで週末、しかも2日目に慌ててやってみます。

    触るのは、引き続きWeb Socket(s)。
    前回のでAPI(クライアントサイド。つまりJS。sがつく方)は何となくイメージできたかなぁという感じ。
    しかし、プロトコル(Web Socket protocol。こっちはsがつかない)はイマイチ理解できてません。

    こういう時はやっぱり手を動かすのが一番ということでとりあえず何か作ってみます。
    ※ ほんとはパケットキャプチャ取りたかったんですがうまくいかなかったので断念

    それでは始めましょう。

    まずは参考記事探しから。

    Web Socket ProtocolのRFC和訳 - YAMAGUCHI::weblog
    ないと思ってたプロトコルの日本語訳がありました。感謝です。
    ただこの仕様短いのはいいんだけど、細かい説明が全然ない・・・。
    websoket-protcol:ヘッダって何の意味があるんだー。
    (node.websokcet.jsではまだ未実装って書いてあるし)

    InfoQ: HTML 5 Web Sockets vs. Comet and Ajax
    仕様のこととかは詳しく書いてませんがおもしろかったです。

    PubSubHubbubとWebSocketsとクライアントサイドのjavascript « ku
    こちらも他の実現方法との比較。読みやすいです。

    Html5 Web Applications
    Html5, Web Applications 2
    HTML5のWebアプリ関連仕様をサクっとまとめた素晴らしいプレゼンです。

    [追記(2010/1/31 14:15)]
    おっと、忘れてた。
    HTTP/1.1 から TLS へのアップグレード
    Upgrade
    HTTPのUpgradeについて。さっぱりわからん。
    [/追記]

    やっぱまだ日本語のソースは少ないですねぇ。

    ネットサーフィンはこれぐらいにして、
    うーん・・・Cometアプリの代表例ホワイトボードでも作ってみますか。

    というわけで、できたのがこちら。

    ソースはいつも通りご自由に。
    説明はコメントで。そんな難しいことはやってません。
    (セキュリティ0なので間違っても公開しないで下さいね)



    うーん、一応思った通りに動いたけど、サーバ側でsetIntervalやるのは綺麗じゃないなー。
    このコード量、しかもJSだけでこういうアプリが作れるのはちょっとした衝撃でした。

    サーバ(node.websocket.js/modules/wb.js)

    var Module = this.Module = function(){
    	// グローバルにしとくと楽
    	sys = require('sys');
    };
    
    Module.prototype.onData = function(data, connection) {
    	// 初期化
    	if (data == 'start'){
    	
    		// 定期的にファイルをcatして変わってたらクライアントに送る
    		this.interval = setInterval(function(){
    			var self = this;
    			sys.exec('cat temp').addCallback(function(stdout, stderr) {
    				if (self.temp != stdout) {
    					connection.send(stdout);
    				}
    				self.temp = stdout;
    			});
    		}, 100);
    		
    	} 
    	// データを受信したらtempファイルに書き込む(超脆弱!!)
    	else {
    		sys.exec('echo "' + data +'" > temp');
    	}
    };
    
    // 後始末
    Module.prototype.onDisconnect = function(connection){
    	clearInterval(this.interval);
    };

    クライアント(apache/htdocls/wb.html)

    <!doctype html>
    <html>
    <head>
    	<title>whiteboard demo</title>
    	<style>
    canvas {
    	border: 1px solid black;
    	position: relative;
    }
    	</style>
    </head>
    <body>
    
    <h1>whiteboard demo</h1>
    
    <canvas width="300" height="200"></canvas><br />
    <input type="button" value="clear" />
    
    <script>
    
    // node.websocket.js/modules/wb.jsに繋ぐ
    var webSocket = new WebSocket('ws://localhost:8000/wb');
    
    /* お絵かき処理ここから */
    
    var canvas = document.getElementsByTagName('canvas')[0];
    var ctx = canvas.getContext('2d');
    
    var isDraw = false;
    var x, y;
    
    canvas.addEventListener('mousedown', function(e) {
    	ctx.moveTo(x, y);
    	isDraw = true;
    }, 'false');
    
    canvas.addEventListener('mousemove', function(e) {
    	x = e.layerX;
    	y = e.layerY;
    	if (isDraw) {
    		ctx.lineTo(x, y);	
    		ctx.stroke();
    	}
    }, 'false');
    
    canvas.addEventListener('mouseup', function(e) {
    	isDraw = false;
    	webSocket.send(canvas.toDataURL());
    }, 'false');
    
    /* お絵かき処理ここまで */
    
    // サーバ側に初期化を知らせる
    webSocket.onopen = function(event){
    	webSocket.send('start');
    };
    
    // データ受信時は問答無用でcanvasを更新
    webSocket.onmessage = function(event){
    	var img = new Image();
    	img.onload = function() {
    		ctx.clearRect(0, 0, canvas.width, canvas.height);
    		ctx.drawImage(img, 0, 0);
    	};
    	img.src = event.data;
    };
    
    // 白紙に戻す
    document.querySelector('input[value=clear]').addEventListener('click', function() {
    	ctx.clearRect(0, 0, canvas.width, canvas.height);
    	webSocket.send(canvas.toDataURL());
    }, 'false');
    
    </script>
    </body>
    </html>

    拍手[0回]

    2010.01.25(Mon.) 00:51
     

    HTML5の仕様も、コミュニティの皆さんも動きが速すぎてすっかり置いてかれています。
    とはいえ、HTML5は勉強しておいて絶対損はないはずなので、
    マイペースで頑張りたいと思います。。

    そんな中、今日、
    噂のnode.websocket.jsでサーバサイドJSとHTML5 WebSocketを体験してみたの巻 - ダウンロードたけし(寅年)の日記
    Real time online activity monitor example with node.js and WebSocket @ Bamboo Blog
    なんていう素敵な記事を見つけました。
    Apacheは好きだけどPythonはちょっと・・・な僕でもこれならできるはず!と
    初めてのWeb Socketsに挑戦してみました。

    というわけで、改めてお勉強。

    まずはAPI仕様。(プロトコルは長いし英語なのでまた今度)
    W3C - 『The Web Sockets API』日本語訳 - HTML5.JP
    うん、これだけじゃわからんですね^^

    デモとか見て勉強しよう。

    こてさきAjax:apache+mod_pywebsocetを用いたliteなwebsocketsチャットサンプル - livedoor Blog(ブログ)
    pywebsocketの例。サーバサイドの処理の説明がわかりやすいです。

    こてさきAjax:apache + web sockets (pywebsocket) tips #0 - livedoor Blog(ブログ)
    こてさきAjax:lite websocket チャットサンプルを更新しました。 - livedoor Blog(ブログ)
    引き続きpywebsocket。
    Origin checkとHeartBeatがキーワードというかいつかハマリそうな予感。
    覚えておこう。

    こてさきAjax:websocketでは、encodeURIComponet()は使うべきではない - livedoor Blog(ブログ)
    データはUTF-8で送受信するので、encodeURI()しなくても良いと、ふむふむ。

    なんとなくイメージが湧いてきた。
    プレゼン資料とかも漁ってみる。
    (やっぱシーケンスがあるとわかりやすいですね!)

    WebSocketでリアルタイムWeb
    かなり噛み砕いた説明でわかりやすいです。

    100113_opera webkit勉強会(websocket)
    こてさきAjax:websocket関連の説明png - livedoor Blog(ブログ)
    図がいっぱい。素敵。

    【特集】詳解! HTML 5と関連APIの最新動向 - Webアプリ開発編 (10) Web Sockets | エンタープライズ | マイコミジャーナル
    Kaazingを使ったデモ。初心者を切り捨てない感じで助かります。

    そろそろ良いかな…よし、やってみよう!

    node.jsのインストール

    node.jsのサイトからnode-v0.1.26.tar.gzをダウンロード。

    cd node-v0.1.26/
    ./configure —prefix=/Users/t/node.js/
    ※ prefix指定はできない?
    
    ./configure
    ※ 諦めてそのままインストールする。
    
    make
    sudo make install
    
    which node
    /usr/local/bin/node
    
    

    何事もなく終了。
    ※ ホントはユーザ権限でインストールしたかったけど・・・

    Hello, node.js

    とりあえず、指定ディレクトリをlsして返すプログラムを書いてみました。
    queryから取ろうと思ったけど、うまく動かないメソッドとかもあったのでやめときました。

    vi ls.js
    
    var sys = require('sys');
    
    var filename = process.ARGV[2];
    
    var http = require("http");
    http.createServer(function(req, res){
    	res.sendHeader(200,{"Content-Type": "text/html; charset=UTF-8"});
    	sys.exec('ls -alF ' + filename).addCallback(function _exec(stdout, stderr) {
    		res.sendBody(stdout);
    		res.finish();
    	});  
    }).listen(8000);
    :wq
    
    node ls.js .
    
    [別ターミナルで]
    telnet localhost 8000
    GET / HTTP/1.1
    host:localhost
    
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    Connection: keep-alive
    Transfer-Encoding: chunked
    
    1cc
    total 80
    drwxr-xr-x   9 t  staff   306  1 25 00:17 ./
    drwxr-xr-x+ 47 t  staff  1598  1 24 23:27 ../
    -rw-r--r--@  1 t  staff  6148  1 25 00:17 .DS_Store
    -rwxr-xr-x@  1 t  staff   304  1 24 23:42 example.js*
    -rwxr-xr-x@  1 t  staff   329  1 24 23:49 log.txt*
    -rwxr-xr-x@  1 t  staff   334  1 25 00:17 ls.js*
    drwxr-xr-x@ 20 t  staff   680  1 24 23:35 node-v0.1.26/
    drwxr-xr-x   5 t  staff   170  1 25 00:17 old/
    -rwxr-xr-x@  1 t  staff   601  1 24 23:50 tail.js*
    こんな感じで返ってきます。
    

    Hello, Web Sockets

    ようやく本題・・・ですが眠いので既存サンプルを動かすだけにしときます。

    git clone git://github.com/Guille/node.websocket.js.git
    node.websocket.js at masterをチェックアウト
    
    cd node.websocket.js
    
    cp test/test.html ~/apache/htdocs/
    apache上にクライアントを配置 
    
    vi ~/apache/htdocs/test.html
    var webSocket = new WebSocket('ws://localhost:8000/time');
    ポートを8000に変更(apacheと競合してたので)
    
    node runserver.js --port="8000"
    Web Socketsサーバを起動
    
    apachectl start
    apacheを起動(8080を使ってます)
    
    

    Google Chrome 4+からlocalhost:8080/test.htmlにアクセスすると、
    時刻がリアルタイムで更新されるサンプルが表示されます。
    (地味ですが確かにpullではなくpushで実現されています。)

    まとめ

    思っていたより手軽に触れそうです。
    僕程度のスキルでも2時間程度で動かすとこまではできました。

    さて、なんか面白いことできないかなー。

    拍手[0回]

    2010.01.24(Sun.) 19:37
     

    Perlの勉強の為、久々に人工無脳を作ってみました。

    説教っぽく聞こえなくもない言葉を30分に1回つぶやきます。

    迷言ボット (bornneet) on Twitter

    興味のある方はfollowしてみて下さい。
    精度は全然ですが、まぐれで良いこというかもしれませんよ^^


    最初は、以下の記事を参考にNet::Twitterでやろうとしたのですが、
    Macにうまくインストールできなかったので、断念。
    Twitter ボットの作り方 Perl 編 (1) – OTCHY.NET

    cpanをupdate(cpan > install Bundle::CPAN)とかやってみるも、状況変わらず。
    テクノロ散策: PerlでNet::Twitterがインストールできない時はcpanをアップデート

    xreaにはNet::Twitterが入ってるので、使いたかったんですが、
    仕方なく生Perlで書くことにしました。

    参考にしたのはこちらの3記事。
    404 Blog Not Found:API - Twitterfeed から Hatena::Bookmark Web Hookへ
    nDiki: Net::Twitter - Net::OAuth を使って Twitter からフィードを取得 (2009-12-30)
    LWP::UserAgentで基本認証とPOSTを - 徒書

    最後の最後、xreaでの動作確認でさらにはまりました。
    Storableに「Byte order is not compatible at blib/lib/Storable.pm」と言われてもうお手上げ。

    またまた先人の力をお借りして何とか解決しました。
    (storeを使わず、nstoreを使用)
    404 Blog Not Found:perl - 勝手に添削 - Storable
    Perl 5.6.2→5.8.7移行メモ

    いやぁ、相変わらず、Perlには慣れませんねぇ…orz

    ※ おまけでxrea無料版ではcronが動かせないという罠も。(何を今さら)
      というわけでcore serverのアカウントで稼働させてます。

    拍手[0回]

    2010.01.22(Fri.) 19:04
     

    お久しぶりです。

    僕がインターネットのない生活を送っている間に、
    待望のFirefox3.6がリリースされましたね!

    これでFirefoxがターゲットのサイトなら、FireAPIを使い放題です!!
    (今まではβ版だったので、開発者しか使ってませんでしたからね・・・)

    というわけで、以下の2作品をFile API対応させときました。

    ダイアログを使うか、選択欄にdrag&dropすればローカルファイルを指定できます。

    錯覚エディター by HTML5 Canvas
    canvasで画像拡大鏡

    何かたまにおかしくなりますが、サンプルということで許して下さい^^
    あと、巨大ファイルや画像じゃないファイルを指定すると壊れますのでご注意を。

    File API、面白いので皆さん是非試してみて下さい!

    ※ 以前File APIの簡単な使い方をLTしたのでよろしければどうぞ。

    拍手[0回]

    2010.01.17(Sun.) 11:30
     

    htmlも。

    HTML Elements Index – Jens Meiert
    index of HTML5 elements
    HTML5 Elements and Attributes
    各HTMLバージョンのDOCTYPE宣言のサンプル集

    最後の方、ちょっと投げました。

    っていうかタグと属性識別すんの忘れた…orz
    cssもプロパティとvalue一緒にしちゃったし…。

    !--
    !DOCTYPE
    --
    -//W3C//DTD HTML 4.01 Frameset//EN
    -//W3C//DTD HTML 4.01 Transitional//EN
    -//W3C//DTD HTML 4.01//EN
    -//W3C//DTD XHTML 1.0 Frameset//EN
    -//W3C//DTD XHTML 1.0 Strict//EN
    -//W3C//DTD XHTML 1.0 Transitional//EN
    -//W3C//DTD XHTML 1.1//EN
    ?xml
    abbr
    accept
    accept-charset
    access
    accesskey
    acronym
    action
    address
    align
    alink
    alt
    applet
    archive
    area
    aria-
    article
    aside
    audio
    axis
    background
    base
    basefont
    bdo
    bgcolor
    big
    blockcode
    blockquote
    body
    border
    br
    button
    canvas
    caption
    cellpadding
    cellspacing
    center
    char
    charoff
    charset
    checkbox
    checked
    cite
    class
    classid
    clear
    code
    codebase
    codetype
    col
    colgroup
    color
    cols
    colspan
    command
    compact
    content
    contenteditable
    contextmenu
    coords
    data
    data-
    datalist
    date
    datetime
    datetime-local
    dd
    declare
    defer
    del
    delete
    details
    dfn
    di
    dir
    disabled
    dispatch
    div
    dl
    draggable
    dt
    em
    email
    embed
    encoding
    enctype
    EUC-JP
    ev:listener
    face
    fieldset
    figure
    file
    font
    footer
    for
    form
    frame
    frameborder
    frameset
    group
    h1
    h1, h2, h3, h4, h5, and h6
    h2
    h3
    h4
    h5
    h6
    handler
    head
    header
    headers
    height
    hgroup
    hidden
    hr
    href
    hreflang
    hspace
    html
    http-equiv
    http://www.w3.org/1999/xhtml
    http://www.w3.org/TR/html4/frameset.dtd
    http://www.w3.org/TR/html4/loose.dtd">
    http://www.w3.org/TR/html4/strict.dtd
    http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd
    http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd
    http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
    http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd
    id
    iframe
    image
    img
    input
    ins
    insert
    isindex
    ismap
    itemid
    itemprop
    itemref
    itemscope
    itemtype
    ja
    kbd
    keygen
    label
    lang
    language
    legend
    li
    link
    listing
    load
    longdesc
    map
    marginheight
    marginwidth
    mark
    marquee
    maxlength
    media
    menu
    message
    meta
    meter
    method
    model
    month
    multiple
    name
    nav
    nl
    noframes
    nohref
    noresize
    noscript
    noshade
    nowrap
    number
    object
    ol
    onabort
    onblur
    oncanplay
    oncanplaythrough
    onchange
    onclick
    oncontextmenu
    ondblclick
    ondrag
    ondragend
    ondragenter
    ondragleave
    ondragover
    ondragstart
    ondrop
    ondurationchange
    onemptied
    onended
    onerror
    onfocus
    onformchange
    onforminput
    oninput
    oninvalid
    onkeydown
    onkeypress
    onkeyup
    onload
    onloadeddata
    onloadedmetadata
    onloadstart
    onmousedown
    onmousemove
    onmouseout
    onmouseover
    onmouseup
    onmousewheel
    onpause
    onplay
    onplaying
    onprogress
    onratechange
    onreadystatechange
    onreset
    onscroll
    onseeked
    onseeking
    onselect
    onshow
    onstalled
    onsubmit
    onsuspend
    ontimeupdate
    onunload
    onvolumechange
    onwaiting  
    optgroup
    option
    output
    param
    password
    plaintext
    pre
    profile
    progress
    prompt
    PUBLIC
    radio
    range
    rb
    rbc
    readonly
    rebuild
    recalculate
    refresh
    rel
    repeat
    reset
    rev
    revalidate
    role
    rows
    rowspan
    rp
    rt
    rtc
    ruby
    rules
    samp
    scheme
    scope
    script
    scrolling
    search
    secret
    section
    select
    select1
    selected
    send
    separator
    setfocus
    setindex
    setvalue
    shape
    Shift_JIS
    size
    small
    source
    span
    spellcheck
    src
    standby
    start
    strike
    strong
    style
    sub
    sub and sup
    submit
    summary
    sup
    switch
    tabindex
    table
    target
    tbody
    td
    tel
    text
    textarea
    tfoot
    th
    thead
    time
    title
    tr
    trigger
    tt
    type
    ul
    upload
    url
    usemap
    UTF-8
    valign
    value
    valuetype
    var
    version
    video
    vlink
    vspace
    week
    width
    xml:lang 
    xmlns
    xmp

    拍手[0回]

     HOME : Next 
    • JavaScript 第5版
    • JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
    • JavaScriptクイックリファレンス 第5版―JavaScript1.5対応
    • はじめてのAIプログラミング―C言語で作る人工知能と人工無能
    • 初めてのJavaScript―Ajax&DOM対応
    自作スクリプト実験
    ブログ内検索
    カレンダー
    01 2010/02 03
    S M T W T F S
    1 2 3 4 5 6
    7 8 9 10 11 12 13
    14 15 16 17 18 19 20
    21 22 23 24 25 26 27
    28
    最近のコメント
    [12/29 佐藤]
    [11/12 nontan]
    [10/27 htakumu]
    [10/22 JUN]
    [10/17 枚方市民]
    最近のトラックバック
    RSS
    RSS 0.91
    RSS 1.0
    RSS 2.0
    プロフィール
    HN:
    t*
    運営日数:
    ?日
    記事数:
    ?件

    ブログパーツ
    あわせて読みたい
    スポンサード リンク

    Born Neet wrote all articles. 
    Powered by Ninja.blog / TemplateDesign by TMP, modified by t*  

    SEO対策忍者ブログ