<?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>@blog.justoneplanet.info &#187; JavaScript</title>
	<atom:link href="http://blog.justoneplanet.info/category/computer-language/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.justoneplanet.info</link>
	<description>日々勉強</description>
	<lastBuildDate>Wed, 08 Feb 2012 02:57:17 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>node.jsでbasic認証を使ってhttps接続する</title>
		<link>http://blog.justoneplanet.info/2011/09/30/node-js%e3%81%a7basic%e8%aa%8d%e8%a8%bc%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6https%e6%8e%a5%e7%b6%9a%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/09/30/node-js%e3%81%a7basic%e8%aa%8d%e8%a8%bc%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6https%e6%8e%a5%e7%b6%9a%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 14:42:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[サーバーサイド]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4451</guid>
		<description><![CDATA[nodeのバグを踏んだりしてたら4時間かかってしまったのでメモしておく。 ■HTTP接続 以下のようにしてHTTPクライアントを生成し、ホストに接続することができる。 var host = 'www.example.co [...]]]></description>
			<content:encoded><![CDATA[<p>nodeのバグを踏んだりしてたら4時間かかってしまったのでメモしておく。</p>
<h3>■HTTP接続</h3>
<p>以下のようにしてHTTPクライアントを生成し、ホストに接続することができる。</p>
<pre class="brush: jscript;">
var host   = 'www.example.com';
var header = {&quot;Host&quot;: host};
var client = http.createClient(
    80,
    host,
    false,
    false
).
client.request(
    &quot;GET&quot;,
    &quot;/&quot;,
    header
);
</pre>
<section class="kakomi">
<p>createClienetはどうやら廃止される方向らしいので以下のように書きなおす。</p>
<pre class="brush: jscript;">
var http = require('http');
var host = 'www.example.com';
var req  = http.get(
    {
        &quot;host&quot;  : host,
        &quot;port&quot;  : 80,
        &quot;path&quot;  : &quot;/&quot;
    },
    function(res) {
        console.log(&quot;Got response: &quot; + res.statusCode);
    }
);
req.on('error', function(e){
    console.log(e);
})
</pre>
</section>
<h3>■Basic認証+HTTP接続</h3>
<p>以下のようにしてHTTPクライアントを生成し、ホストに接続することができる。</p>
<pre class="brush: jscript;">
var username = 'hoge';
var password = 'fuga';
var auth     = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var host     = 'www.example.com';
var header   = {
    &quot;Host&quot;          : host,
    &quot;Authorization&quot; : auth
};
var client   = http.createClient(
    80,
    host,
    false,
    false
).
client.request(
    &quot;GET&quot;,
    &quot;/&quot;,
    header
);
</pre>
<section class="kakomi">
<p>createClienetはどうやら廃止される方向らしいので以下のように書きなおす。</p>
<pre class="brush: jscript;">
var http = require('http');
var host = 'www.example.com';
var req  = http.get(
    {
        &quot;host&quot;  : host,
        &quot;port&quot;  : 80,
        &quot;path&quot;  : &quot;/&quot;,
        &quot;auth&quot;  : &quot;username:password&quot;
    },
    function(res) {
        console.log(&quot;Got response: &quot; + res.statusCode);
    }
);
req.on('error', function(e){
    console.log(e);
})
</pre>
</section>
<h3>■Basic認証+HTTPS接続</h3>
<section class="kakomi">
<h4>失敗例</h4>
<p>以下のようにしてHTTPSクライアントを生成しても、ホストに接続することはできない。</p>
<pre class="brush: jscript;">
var username = 'hoge';
var password = 'fuga';
var auth     = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var host     = 'www.example.com';
var header   = {
    &quot;Host&quot;          : host,
    &quot;Authorization&quot; : auth
};
var client   = http.createClient(
    443,
    host,
    true,
    false
).
client.request(
    &quot;GET&quot;,
    &quot;/&quot;,
    header
);
</pre>
<p>実行してもエラーがでる。</p>
<h5>参考</h5>
<ul>
<li><a href="https://github.com/joyent/node/issues/939">HTTPS fails with &#8216;socket hang up&#8217;</a></li>
<li><a href="https://github.com/nodejitsu/node-http-proxy/issues/36">https proxy: socket hang up</a></li>
</ul>
</section>
<p>上述のように失敗するのでhttpsモジュールを使う。</p>
<h3>■Basic認証+HTTPS接続</h3>
<p>以下のようにすることで、HTTPSクライアントでBasic認証を使うことができる。</p>
<pre class="brush: jscript;">
var https    = require('https');
var host     = 'www.example.com';
var username = 'hoge';
var password = 'fuga';
var auth     = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
var options  = {
    &quot;host&quot;          : host,
    &quot;port&quot;          : 443,
    &quot;path&quot;          : '/',
    &quot;method&quot;        : 'GET',
    &quot;Authorization&quot; : auth
};
var request = https.request(
    options,
    function(response) {
        console.log(&quot;statusCode: &quot;, response.statusCode);
        console.log(&quot;headers: &quot;, response.headers);
    }
);
request[&quot;_headers&quot;][&quot;Authorization&quot;]     = auth;// ...(a)
request[&quot;_headerNames&quot;][&quot;Authorization&quot;] = 'Authorization';// ...(b)
request.end();
</pre>
<p>optionsにAuthorizationをセットするだけではBasic認証が成功しなかった。認証用のヘッダが正しく付加されるように、強引に(a)と(b)を加えた。</p>
<h4>参考</h4>
<ul>
<li><a href="http://nodejs.org/docs/v0.4.12/api/all.html#https.request">https.request(options, callback)</a></li>
<li><a href="http://stackoverflow.com/questions/3905126/how-to-use-http-client-in-node-js-if-there-are-basic-authorization">how to use http.client in Node.js if there are basic authorization</a></li>
</ul>
<h3>■後述</h3>
<p>現在のnodeのバージョンでは以下のようにして簡単にhttpsでBasic認証を行うことができた。</p>
<pre class="brush: jscript;">
var http = require('https');
var host = 'www.example.com';
var req  = http.get(
    {
        &quot;host&quot;  : host,
        &quot;port&quot;  : 443,
        &quot;path&quot;  : &quot;/&quot;,
        &quot;auth&quot;  : &quot;username:password&quot;
    },
    function(res) {
        console.log(&quot;Got response: &quot; + res.statusCode);
    }
);
req.on('error', function(e){
    console.log(e);
})
</pre>
<h4>参考</h4>
<ul>
<li><a href="http://d.hatena.ne.jp/romer/20111030/1319961167">今更ですが、node.jsでbasic認証にかかったサイトをjqueryでスクレイピングをした。そして困った。</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/09/30/node-js%e3%81%a7basic%e8%aa%8d%e8%a8%bc%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6https%e6%8e%a5%e7%b6%9a%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Goolge Developer Day 2011のWeb Gameを解いてみる</title>
		<link>http://blog.justoneplanet.info/2011/09/13/goolge-developer-day-2011%e3%81%aeweb-game%e3%82%92%e8%a7%a3%e3%81%84%e3%81%a6%e3%81%bf%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/09/13/goolge-developer-day-2011%e3%81%aeweb-game%e3%82%92%e8%a7%a3%e3%81%84%e3%81%a6%e3%81%bf%e3%82%8b/#comments</comments>
		<pubDate>Mon, 12 Sep 2011 22:00:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[アルゴリズム]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4358</guid>
		<description><![CDATA[Extensionとか入れたりするの面倒なので以下のJavaScriptをコンソールに打ち込む。 var ary = []; for(var i = 0; i &#60; 1024; i++){ if($('card' + [...]]]></description>
			<content:encoded><![CDATA[<p>Extensionとか入れたりするの面倒なので以下のJavaScriptをコンソールに打ち込む。</p>
<pre class="brush: jscript;">
var ary = [];
for(var i = 0; i &lt; 1024; i++){
    if($('card' + i)){
        $('#card' + i).click();
        ary.push($('#card' + i).css('backgroundColor'));
    }
}
ary.forEach(function(elm, i1, ary){
    for(var i2 = i1 + 1; i2 &lt; ary.length; i2++){
        if(ary[i1] == ary[i2]){
            $('#card' + i1).click();
            $('#card' + i2).click();
        }
    }
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/09/13/goolge-developer-day-2011%e3%81%aeweb-game%e3%82%92%e8%a7%a3%e3%81%84%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WebSocket Serverまとめ</title>
		<link>http://blog.justoneplanet.info/2011/08/13/websocket-server%e3%81%be%e3%81%a8%e3%82%81/</link>
		<comments>http://blog.justoneplanet.info/2011/08/13/websocket-server%e3%81%be%e3%81%a8%e3%82%81/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 13:27:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[サーバーサイド]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4288</guid>
		<description><![CDATA[Chrome 14からWebSocketプロトコルのバージョンがdraft 10になる。現在、Chrome 13はdraft 76で実装されておりdraft 76とdraft 10は互換性がない。WebSocketを使っ [...]]]></description>
			<content:encoded><![CDATA[<p>Chrome 14からWebSocketプロトコルのバージョンがdraft 10になる。現在、Chrome 13はdraft 76で実装されておりdraft 76とdraft 10は互換性がない。WebSocketを使った既存のサービスは壊れるのでdraft 10で実装されたWebSocketServerを探しときの情報をまとめた。</p>
<h3>■<a href="http://blog.chromium.org/2011/08/new-websocket-protocol-secure-and.html">New WebSocket Protocol: Secure and Extensible</a></h3>
<blockquote><p>Please note that the new protocol is incompatible with one which Chromium previously supported (draft-ietf-hybi-thewebsocketprotocol-00),<br />
so existing WebSocket-based services may break.<br />
Please upgrade your servers to ones which support HyBi 10.<br />
Existing JavaScript code still works once the protocol version used by the browser and server match.</p></blockquote>
<p>新しいプロトコルは非互換でなので既存のWebSocketをベースとしたサービスは壊れる。HyBi 10をサポートするようにサーバをアップグレードしてくれ。既存のJavaScriptコードはプロトコルのバージョンが合致すれば動作するだろう。</p>
<h3>■<a href="https://github.com/Worlize/WebSocket-Node">WebSocket-Node</a></h3>
<blockquote><p>A WebSocket Draft -08/-09/-10 Implementation for Node.JS</p></blockquote>
<p>いけちゃうっぽい！broadcastメソッドが存在しないようだが、以下のようにbroadcastメソッドを実装することにした。</p>
<pre class="brush: jscript;">
var WebSocketServer = require('websocket').server;
WebSocketServer.prototype.broadcastUTF = function(data){
    this.connections.forEach(function(connection, i, ary){
        connection.sendUTF(data);
    });
};
</pre>
<p>作者の方にも気に入って頂けたようなので近いうちにモジュールに組み込まれるかもしれない。</p>
<section class="kakomi">
<h4>インストール</h4>
<pre class="brush: bash;">
npm install websocket
</pre>
<h4>実装</h4>
<p>以下のようにしてWebSocketサーバをセットアップした。</p>
<pre class="brush: jscript;">
/**
 * extend default WebSocketServer for broadcast
 */
var WebSocketServer = require('websocket').server;
WebSocketServer.prototype.broadcastUTF = function(data){
    this.connections.forEach(function(connection, i, ary){
        connection.sendUTF(data);
    });
};

/**
 * websocket server for end users
 */
var server = require('http').createServer(
    function(request, response) {
        console.log((new Date()) + &quot; Received request for &quot; + request.url);
        response.writeHead(404);
        response.end();
    }
);
server.listen(
    eew.env['port'],
    function() {
        console.log((new Date()) + &quot; Server is listening on port 80&quot;);
    }
);

wsServer = new WebSocketServer({
    &quot;httpServer&quot;            : server,
    &quot;autoAcceptConnections&quot; : true
});

wsServer.on(
    'connect',
    function(connection){
        console.log((new Date()) + &quot; Connection accepted.&quot;);
        connection.sendUTF('{&quot;status&quot; : &quot;accepted&quot;}');
    }
);
</pre>
<p>broadcastUTFメソッドを自作した以外は殆どサンプルコードと変わらない。</p>
</section>
<h3><a href="https://github.com/miksago/node-websocket-server/issues/72">■Support draft-10 (chrome 14-dev+)</a></h3>
<p>node.jsには何種類かWebSocket Serverの実装がある。</p>
<blockquote><p>This will either be done<br />
via node-websocket-protocol (preferable), or<br />
via some kind of hack to the core of node-websocket-server, which is the route I really don&#8217;t want to take.
</p></blockquote>
<p>どうやらプロトコルだけ外に出してモジュール化することで対応する意向らしい。しかし、レスポンスが遅いのが気になる。</p>
<h3>■<a href="http://socket.io/">Socket IO</a></h3>
<p><a href="https://github.com/LearnBoost/socket.io/issues/429">hybi10 incompatibility</a></p>
<p>軽く読んだ限りでは最新の仕様では不具合が発生するようだ。ロングポールなど代替手段が揃っているので有用な選択肢ではある。但し、今回はクライアント側のコードを変更したくないので選択肢から外した。</p>
<p>追記：8/30動作するようになった模様。</p>
<h3>■<a href="http://code.google.com/p/pywebsocket/">pywebsocket</a></h3>
<p>node.js用のモジュールが存在しなければ、他の言語のモジュールで対応するという選択肢も考えた。pywebsocketではdraft-ietf-hybi-thewebsocketprotocol-07まで対応している。</p>
<h3>■<a href="http://wiki.eclipse.org/Jetty/Feature/WebSockets">Jetty</a></h3>
<blockquote><p>Jetty has supported the various WebSocket drafts in the 7.x and 8.x releases.</p></blockquote>
<p>どうやら最新の実装には対応していないようだ。</p>
<h3>■参考</h3>
<h4>The WebSocket protocol</h4>
<p><a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10">draft-ietf-hybi-thewebsocketprotocol-10</a></p>
<h4><a href="http://websocketserverswiki.pbworks.com/w/page/28646473/FrontPage">Comparison table of websocket server implementations.</a></h4>
<p>WebSocketサーバの実装が比較されているが更新されていないっぽい。</p>
<h3>■まとめ</h3>
<p>バージョンは適宜アップデートされるだろう。node.jsを選んで良かった。</p>
<section class="kakomi">
<h4>後述</h4>
<ul>
<li><a href="https://github.com/learnboost/websocket.io">websocket.io</a></li>
</ul>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/08/13/websocket-server%e3%81%be%e3%81%a8%e3%82%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Socket.IOをインストールする</title>
		<link>http://blog.justoneplanet.info/2011/08/10/socket-io%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/08/10/socket-io%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 14:15:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[サーバーサイド]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4279</guid>
		<description><![CDATA[■node.js 以前の記事にも書いたんだけど以下のようにしてインストールできる。 su yum install openssl-devel gcc-c++ git make git clone git://github [...]]]></description>
			<content:encoded><![CDATA[<h3>■node.js</h3>
<p>以前の記事にも書いたんだけど以下のようにしてインストールできる。</p>
<pre class="brush: bash;">
su
yum install openssl-devel gcc-c++ git make
git clone git://github.com/creationix/nvm.git ~/.nvm
source ~/.nvm/nvm.sh
echo &quot;~/.nvm/nvm.sh&quot; &gt;&gt; ~/.bash_profile
echo &quot;nvm use v0.5.0&quot; &gt;&gt; ~/.bash_profile
nvm sync
nvm install v0.5.0
npm install node-base64
</pre>
<p>でも使い勝手に慣れなくて結局ソースからビルドしてしまったり。</p>
<h3>■Socket.IO</h3>
<p>以下のコマンドでインストールできる。</p>
<pre class="brush: bash;">
npm install socket.io
</pre>
<p>まぁ、一瞬で終わる。</p>
<h4>使ってみる</h4>
<h5>サーバ側</h5>
<pre class="brush: jscript;">
var io = require('socket.io').listen(80);
io.sockets.on(
    'connection',// 接続された時
    function(socket){// 引数に接続(socket)をセットしてコールバックが実行される
        socket.on(
            'disconnect',
            function () {
                io.sockets.emit('message', 'hogehoge');// 全員にpushされる
            }
        );
    }
);
</pre>
<p>socketのbroadcastメソッドは接続している以外の全てのクライアントに対してpushされる。</p>
<h5>クライアント側</h5>
<p>サーバを起動させるとクライアント側で読み込むべきscriptが特定の位置に展開される。楽といえば楽。</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://127.0.0.1:80/socket.io/socket.io.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var socket = io.connect('http://127.0.0.1:80');
socket.on(
    'message',
    function (data) {
        console.log(data);
    }
);
&lt;/script&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/08/10/socket-io%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptでプリム法</title>
		<link>http://blog.justoneplanet.info/2011/06/13/javascript%e3%81%a7%e3%83%97%e3%83%aa%e3%83%a0%e6%b3%95/</link>
		<comments>http://blog.justoneplanet.info/2011/06/13/javascript%e3%81%a7%e3%83%97%e3%83%aa%e3%83%a0%e6%b3%95/#comments</comments>
		<pubDate>Sun, 12 Jun 2011 16:09:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[グラフ]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4139</guid>
		<description><![CDATA[重み付き無向グラフの最小全域木を求めるアルゴリズム。任意の辺から始めて全頂点を覆うまで連続的に木の大きさを拡大し、全ての辺の重みの総和が最小となる経路を求める。 ■実装 以下のように実装した。 /** * Vertex  [...]]]></description>
			<content:encoded><![CDATA[<p>重み付き無向グラフの最小全域木を求めるアルゴリズム。任意の辺から始めて全頂点を覆うまで連続的に木の大きさを拡大し、全ての辺の重みの総和が最小となる経路を求める。</p>
<h3>■実装</h3>
<p>以下のように実装した。</p>
<pre class="brush: jscript;">
/**
 * Vertex
 * @param int value
 */
var Vertex = function(value){
    var self = this;
    self.value    = value;
    self.neighbor = [];
    self.appendNeighbor = function(){
        for(var i = 0; i &lt; arguments.length; i++){
            self.neighbor.push(arguments[i]);
        }
    }
}

// set up a graph
var v0 = new Vertex(0);
var v1 = new Vertex(1);
var v2 = new Vertex(2);
var v3 = new Vertex(3);
var v4 = new Vertex(4);
v0.appendNeighbor(
    {&quot;vertex&quot; : v1, &quot;weight&quot; : 2},
    {&quot;vertex&quot; : v3, &quot;weight&quot; : 8},
    {&quot;vertex&quot; : v4, &quot;weight&quot; : 4}
);
v1.appendNeighbor(
    {&quot;vertex&quot; : v0, &quot;weight&quot; : 2},
    {&quot;vertex&quot; : v2, &quot;weight&quot; : 3}
);
v2.appendNeighbor(
    {&quot;vertex&quot; : v1, &quot;weight&quot; : 3},
    {&quot;vertex&quot; : v4, &quot;weight&quot; : 1},
    {&quot;vertex&quot; : v3, &quot;weight&quot; : 5}
);
v3.appendNeighbor(
    {&quot;vertex&quot; : v2, &quot;weight&quot; : 5},
    {&quot;vertex&quot; : v4, &quot;weight&quot; : 7},
    {&quot;vertex&quot; : v0, &quot;weight&quot; : 8}
);
v4.appendNeighbor(
    {&quot;vertex&quot; : v2, &quot;weight&quot; : 1},
    {&quot;vertex&quot; : v3, &quot;weight&quot; : 7},
    {&quot;vertex&quot; : v0, &quot;weight&quot; : 4}
);
var V = [v0, v1, v2, v3, v4];

// initialize
var key  = [];
var pred = [];
for(var i = 0; i &lt; V.length; i++){
    key[V[i]['value']]  = Number.POSITIVE_INFINITY;
    pred[V[i]['value']] = -1;
}
key[0] = 0;// 任意の1頂点をスタート地点とするため優先度を0にする
var bh = new BinaryHeap();
for(var i = 0; i &lt; V.length; i++){
    // 頂点を優先度付きキューに格納
    bh.insert(V[i], key[V[i]['value']]);
}

// calc
while(bh.getList().length &gt; 0){
    var u = bh.getPrior();// 優先度で先頭にくる頂点を取り出す
    for(var i = 0; i &lt; u['neighbor'].length; i++){// 経路が存在している頂点でループ
        var neighbor = u['neighbor'][i]['vertex'];
        // 頂点(a)がキューに存在している場合
        if(bh.inQueue(neighbor)){
            var weight = u['neighbor'][i]['weight'];
            // かつ頂点(a)まで距離が前回のループまでに到達した距離よりも短い場合
            if(weight &lt; key[neighbor['value']]){
                pred[neighbor['value']] = u['value'];// 頂点を配列に格納
                key[neighbor['value']]  = weight;// 距離を配列に格納
                bh.changePriority(neighbor, weight);// 優先度を更新（キューの先頭に近づく）
            }
        }
    }
}

// result
console.log(&quot;key:&quot;);
console.log(key);
console.log(&quot;pred:&quot;);
console.log(pred);
</pre>
<h4>結果</h4>
<p>最小全域木の距離の総和は以下を足した値となる。</p>
<table>
<tbody>
<tr>
<td>0</td>
<td>2</td>
<td>3</td>
<td>5</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>計算時に辿った経路は以下のようになる。</p>
<table>
<tbody>
<tr>
<td>-1</td>
<td>0</td>
<td>1</td>
<td>2</td>
<td>2</td>
</tr>
</tbody>
</table>
<section class="kakomi">
<h4>優先度付きキュー</h4>
<p><a href="/?p=3673">以前の記事</a>で使用したコードにメソッドを追記して使用した。</p>
<pre class="brush: jscript;">
/**
 * BinaryHeap
 */
var BinaryHeap = function(){
    var self = this;
    self._ary  = [];
}
BinaryHeap.prototype._build = function(){
    var self = this;
    /**
     * heapify
     * 3要素を比較し最も小さい要素を親とする
     * @param {array} ary
     * @param {int} i
     * @param {max} max
     */
    var heapify = function(ary, i, max){
        /**
         * swap
         * @param {array} ary
         * @param {int} x
         * @param {int} y
         */
        var swap = function(ary, x, y){
            var a = ary[x];
            var b = ary[y];
            ary[x] = b;
            ary[y] = a;
            return true;
        }

        var l = 2 * i + 1;
        var r = 2 * i + 2;
        var li = 0;
        if(l &lt; max &amp;&amp; ary[l].priority &lt; ary[i].priority){
            li = l;
        }
        else{
            li = i;
        }
        if(r &lt; max &amp;&amp; ary[r].priority &lt; ary[li].priority){
            li = r;
        }
        if(li !== i){
            swap(ary, i, li);
            heapify(ary, li, max);
        }
    }
    var ary = self._ary;
    for(var i = ary.length - 1; i &gt;= 0; i--){
        heapify(ary, i, self._ary.length);
    }
}
/**
 * BinaryHeap::insert
 * 要素をヒープに追加する
 * @param {Object} elm
 * @param {int} priority
 */
BinaryHeap.prototype.insert = function(elm, priority){
    var self = this;
    self._ary.push({
        &quot;priority&quot; : priority,
        &quot;elm&quot;      : elm
    });
    self._build();
}
/**
 * BinaryHeap::changePriority
 * 要素の優先度を変更する
 * @param {Object} elm
 * @param {int} priority
 */
BinaryHeap.prototype.changePriority = function(elm, priority){
    var self = this;
    var ary  = self._ary;
    for(var i = 0; i &lt; ary.length; i++){
        if(elm === ary[i][&quot;elm&quot;]){
            ary[i][&quot;priority&quot;] = priority;
            self._build();
            return true;
        }
    }
    return false;
}
/**
 * BinaryHeap::getPrior
 * 優先度の高い要素を取得する
 */
BinaryHeap.prototype.getPrior = function(){
    var self = this;
    var elm  = self._ary.shift();
    self._build();
    return elm[&quot;elm&quot;];
}
/**
 * BinaryHeap::getList
 * ヒープを返す
 */
BinaryHeap.prototype.getList = function(){
    var self = this;
    return self._ary;
}

/**
 * BinaryHeap::inQueue
 * ヒープ内で探索
 */
BinaryHeap.prototype.inQueue = function(v){
    var self = this;
    for(var i = 0; i &lt; self._ary.length; i++){
        if(self._ary[i]['elm'] === v){
            return true;
        }
    }
    return false;
}
</pre>
<p>inQueueメッソドを効率よくできないかな・・・(●´⌓`●)</p>
</section>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/06/13/javascript%e3%81%a7%e3%83%97%e3%83%aa%e3%83%a0%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>three.jsを通してWebGLを使う</title>
		<link>http://blog.justoneplanet.info/2011/06/11/three-js%e3%82%92%e9%80%9a%e3%81%97%e3%81%a6webgl%e3%82%92%e4%bd%bf%e3%81%86/</link>
		<comments>http://blog.justoneplanet.info/2011/06/11/three-js%e3%82%92%e9%80%9a%e3%81%97%e3%81%a6webgl%e3%82%92%e4%bd%bf%e3%81%86/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 17:55:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3916</guid>
		<description><![CDATA[※Google Chrome以外のブラウザでは正確に表示されない部分があります。 ■サンプルコード サンプルコードを大体そのまま動かしながらコードを理解してみる。 (function(){ var camera, sce [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript" src="/js/three.js/build/Three.js"></script><br />
<script type="text/javascript" src="/js/three.js/examples/js/RequestAnimationFrame.js"></script></p>
<p>※Google Chrome以外のブラウザでは正確に表示されない部分があります。</p>
<h3>■サンプルコード</h3>
<p>サンプルコードを大体そのまま動かしながらコードを理解してみる。</p>
<pre class="brush: jscript;">
(function(){
    var camera, scene, renderer,
    geometry, material, mesh;
    init();
    animate();
    function init() {
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        geometry = new THREE.Cube(200, 200, 200 );
        material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
        mesh = new THREE.Mesh(geometry, material);
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030601');
        renderer = new THREE.CanvasRenderer();
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    }
    function animate() {
        // Include examples/js/RequestAnimationFrame.js for cross-browser compatibility.
        requestAnimationFrame(animate);
        render();
    }
    function render() {
        mesh.rotation.x += 0.01;
        mesh.rotation.y += 0.02;
        renderer.render(scene, camera);
    }
})();
</pre>
<div id="canvas2011030601"></div>
<p><script type="text/javascript">
jQuery(function(){
    var camera, scene, renderer,
    geometry, material, mesh;
    init();
    animate();
    function init() {
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        geometry = new THREE.Cube(200, 200, 200);
        material = new THREE.MeshBasicMaterial({color: 0xff0000, wireframe: true});
        mesh = new THREE.Mesh(geometry, material);
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030601');
        renderer = new THREE.CanvasRenderer();
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    }
    function animate() {
        // Include examples/js/RequestAnimationFrame.js for cross-browser compatibility.
        requestAnimationFrame(animate);
        render();
    }
    function render() {
        mesh.rotation.x += 0.01;
        mesh.rotation.y += 0.02;
        renderer.render(scene, camera);
    }
});
</script></p>
<p>CanvasRendererとあるようにどうやら普通にcanvasで描画しているようだ。</p>
<h3>■サンプルコード</h3>
<p>以下のようにアレンジしてWebGLRendererを使うようにしてみる。</p>
<pre class="brush: jscript;">
(function(){
    var camera;
    var scene;
    var renderer;
    var mesh;
    // initialize
    (function(){
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        mesh = new THREE.Mesh(
            new THREE.Cube(200, 200, 200),
            new THREE.MeshBasicMaterial({
                &quot;color&quot;     : 0xff0000,
                &quot;wireframe&quot; : true
            })
        );
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030602');
        renderer = new THREE.WebGLRenderer();
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    })();
    // animation
    setInterval(
        function(){
            mesh.rotation.x += 0.02;
            renderer.render(scene, camera);
        },
        1000 / 60
    );
});
</pre>
<p>以下のように表示される。</p>
<div id="canvas2011030602"></div>
<p><script type="text/javascript">
jQuery(function(){
    var camera;
    var scene;
    var renderer;
    var mesh;
    // initialize
    (function(){
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        mesh = new THREE.Mesh(
            new THREE.Cube(200, 200, 200),
            new THREE.MeshBasicMaterial({
                "color"     : 0xff0000,
                "wireframe" : true
            })
        );
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030602');
        renderer = new THREE.WebGLRenderer();
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    })();
    // animation
    setInterval(
        function(){
            mesh.rotation.x += 0.02;
            renderer.render(scene, camera);
        },
        1000 / 60
    );
});
</script></p>
<p>アンチエイリアスがないのが気になる。 しかしドキュメントが見当たらなかったのでWebGLRenderer.jsを開いてみた。</p>
<pre class="brush: jscript;">
_antialias = parameters.antialias !== undefined ? parameters.antialias : false,
</pre>
<p>75行目あたりに上述の記述があるので、以下のようにオプションを指定した。</p>
<pre class="brush: jscript;">
(function(){
    var camera;
    var scene;
    var renderer;
    var mesh;
    // initialize
    (function(){
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        mesh = new THREE.Mesh(
            new THREE.Cube(200, 200, 200),
            new THREE.MeshBasicMaterial({
                &quot;color&quot;     : 0xff0000,
                &quot;wireframe&quot; : true
            })
        );
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030603');
        renderer = new THREE.WebGLRenderer({&quot;antialias&quot; : true});
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    })();
    // animation
    setInterval(
        function(){
            mesh.rotation.x += 0.02;
            renderer.render(scene, camera);
        },
        1000 / 60
    );
});
</pre>
<p>以下のようにアンチエイリアスがかかった。但し、Firefoxではアンチエイリアスがかからなかった。</p>
<div id="canvas2011030603"></div>
<p><script type="text/javascript">
jQuery(function(){
    var camera;
    var scene;
    var renderer;
    var mesh;
    // initialize
    (function(){
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        mesh = new THREE.Mesh(
            new THREE.Cube(200, 200, 200),
            new THREE.MeshBasicMaterial({
                "color"     : 0xff0000,
                "wireframe" : true
            })
        );
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030603');
        renderer = new THREE.WebGLRenderer({"antialias" : true});
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    })();
    // animation
    setInterval(
        function(){
            mesh.rotation.x += 0.02;
            renderer.render(scene, camera);
        },
        1000 / 60
    );
});
</script></p>
<p>meshを以下のように記述することでテクスチャを貼ることができる。</p>
<pre class="brush: jscript;">
mesh = new THREE.Mesh(
    new THREE.Cube(
        200,
        200,
        200,
        3,
        3,
        3,
        [
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/lock.png')}), // right
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/face.png')}), // left
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/face.png')}), //top
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/face.png')}), // bottom
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/face.png')}), // back
            new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/img/face.png')}) // front
        ]
    ),
    new THREE.MeshFaceMaterial()
);
</pre>
<p>以下のように表示される。</p>
<div id="canvas2011030604"></div>
<p><script type="text/javascript">
jQuery(function(){
    var camera;
    var scene;
    var renderer;
    var mesh;
    // initialize
    (function(){
        camera = new THREE.Camera(75, window.innerWidth / window.innerHeight, 1, 10000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        mesh = new THREE.Mesh(
            new THREE.Cube(
                200,
                200,
                200,
                3,
                3,
                3,
                [
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/lock.png')}), // right
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/face.png')}), // left
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/face.png')}), //top
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/face.png')}), // bottom
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/face.png')}), // back
                    new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('/wp-content/uploads/2011/06/face.png')}) // front
                ]
            ),
            new THREE.MeshFaceMaterial()
        );
        scene.addObject(mesh);
        var canvas = document.getElementById('canvas2011030604');
        renderer = new THREE.WebGLRenderer({"antialias" : true});
        renderer.setSize(canvas.offsetWidth, 300);
        canvas.appendChild(renderer.domElement);
    })();
    // animation
    setInterval(
        function(){
            mesh.rotation.x += 0.02;
            mesh.rotation.y += 0.02;
            renderer.render(scene, camera);
        },
        1000 / 60
    );
});
</script></p>
<p>現時点でWebGLに対応しているPCブラウザはGoogle Chrome、Firefoxとなる。残念ながらスマートフォンではandroidのデフォルトのブラウザやMobile SafariでWebGLを見ることはできず、android版のFirefoxでは見ることができる。ちなみにWebGLを使うとMacBookが熱々になる(●´⌓`●)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/06/11/three-js%e3%82%92%e9%80%9a%e3%81%97%e3%81%a6webgl%e3%82%92%e4%bd%bf%e3%81%86/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScriptでフロイドワーシャル法</title>
		<link>http://blog.justoneplanet.info/2011/06/05/javascript%e3%81%a7%e3%83%95%e3%83%ad%e3%82%a4%e3%83%89%e3%83%af%e3%83%bc%e3%82%b7%e3%83%a3%e3%83%ab%e6%b3%95/</link>
		<comments>http://blog.justoneplanet.info/2011/06/05/javascript%e3%81%a7%e3%83%95%e3%83%ad%e3%82%a4%e3%83%89%e3%83%af%e3%83%bc%e3%82%b7%e3%83%a3%e3%83%ab%e6%b3%95/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 04:20:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[グラフ]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4051</guid>
		<description><![CDATA[■実装 以下のように実装した。 //Graph var vertexes = [ [null, 2, null, null, 4],// vertex 1 [null, null, 3, null, null],// v [...]]]></description>
			<content:encoded><![CDATA[<h3>■実装</h3>
<p>以下のように実装した。</p>
<pre class="brush: jscript;">
//Graph
var vertexes = [
     [null, 2,    null, null, 4],//    vertex 1
     [null, null, 3,    null, null],// vertex 2
     [null, null, null, 5,    1],//    vertex 3
     [8,    null, null, null, null],// vertex 4
     [null, null, null, 4,    null]//  vertex 5
];

// initialize
var dist = [];
var pred = [];
var n    = vertexes.length;
for(var u = 0; u &lt; n; u++){
    dist[u] = [];
    pred[u] = [];
    for(var i = 0; i &lt; n; i++){
        dist[u][i] = Number.POSITIVE_INFINITY;// 経路が存在しない場合は無限
        pred[u][i] = -1;
        if(vertexes[u][i] !== null){
            dist[u][i] = vertexes[u][i];// 元グラフの経路を代入
            pred[u][i] = u;
        }
    }
    dist[u][u] = 0;// 自身に対しては0の距離が存在する
}
console.log('dist:');
console.log(dist);//...(a)

// 計算
for(var k = 0; k &lt; n; k++){
    for(var i = 0; i &lt; n; i++){
        if(dist[i][k] === Number.POSITIVE_INFINITY){
            continue;
        }
        // 任意の頂点まで有限の距離が開いているとき
        // 有限距離 を経由した任意の頂点を選択し
        // そこまでの距離が既に計算したものよりも小さい場合に
        // その値で上書きする
        for(var j = 0; j &lt; n; j++){
            var newLength = dist[i][k];// ik
            newLength += dist[k][j];
            if(newLength &lt; dist[i][j]){
                dist[i][j] = newLength;
                pred[i][j] = pred[k][j];
            }
        }
    }
}

// 結果
console.log(&quot;dist:&quot;);
console.log(dist);//...(b)
</pre>
<p>(a)の時、distは以下のようになる。</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>0</td>
<td>2</td>
<td>Infinity</td>
<td>Infinity</td>
<td>4</td>
</tr>
<tr>
<td>Infinity</td>
<td>0</td>
<td>3</td>
<td>Infinity</td>
<td>Infinity</td>
</tr>
<tr>
<td>Infinity</td>
<td>Infinity</td>
<td>0</td>
<td>5</td>
<td>1</td>
</tr>
<tr>
<td>8</td>
<td>Infinity</td>
<td>Infinity</td>
<td>0</td>
<td>Infinity</td>
</tr>
<tr>
<td>Infinity</td>
<td>Infinity</td>
<td>Infinity</td>
<td>4</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>殆ど元グラフと変わらない。結果(b)は、以下のようになる。</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>0</td>
<td>2</td>
<td>5</td>
<td>8</td>
<td>4</td>
</tr>
<tr>
<td>16</td>
<td>0</td>
<td>3</td>
<td>8</td>
<td>4</td>
</tr>
<tr>
<td>13</td>
<td>15</td>
<td>0</td>
<td>5</td>
<td>1</td>
</tr>
<tr>
<td>8</td>
<td>10</td>
<td>13</td>
<td>0</td>
<td>12</td>
</tr>
<tr>
<td>12</td>
<td>14</td>
<td>17</td>
<td>4</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>例えば0→1は距離が2、0→2は距離が5、0→3は距離が8、0→4は距離が4であり、1→0は距離が16である。</p>
<h4>経路</h4>
<p>終了時のpredは以下のようになる。</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>-1</td>
<td>0</td>
<td>1</td>
<td>4</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>-1</td>
<td>1</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
<td>-1</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
<td>1</td>
<td>-1</td>
<td>0</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
<td>1</td>
<td>4</td>
<td>-1</td>
</tr>
</tbody>
</table>
<p>例えば0→1の一つ前の頂点は始点0、0→2の一つ前の頂点は頂点1、0→3の一つ前の頂点は頂点4、0→4の一つ前の頂点は0であり、1→0の場合は頂点3が終点の一つ前である。</p>
<h3>■おまけ</h3>
<p>ちなみに表は以下のようにして描画した。</p>
<pre class="brush: jscript;">
document.write('&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;');
dist.forEach(function(e1, i1, ary1){
	document.write('&lt;tr&gt;');
	e1.forEach(function(e2, i2, ary2){
		document.write('&lt;td&gt;' + e2 + '&lt;/td&gt;');
	});
	document.write('&lt;/tr&gt;');
});
document.write('&lt;/table&gt;');
</pre>
<p>そろそろJavaScriptでもforEachを使って良い頃だと思う。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/06/05/javascript%e3%81%a7%e3%83%95%e3%83%ad%e3%82%a4%e3%83%89%e3%83%af%e3%83%bc%e3%82%b7%e3%83%a3%e3%83%ab%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScriptでベルマンフォード法</title>
		<link>http://blog.justoneplanet.info/2011/05/07/javascript%e3%81%a7%e3%83%99%e3%83%ab%e3%83%9e%e3%83%b3%e3%83%95%e3%82%a9%e3%83%bc%e3%83%89%e6%b3%95/</link>
		<comments>http://blog.justoneplanet.info/2011/05/07/javascript%e3%81%a7%e3%83%99%e3%83%ab%e3%83%9e%e3%83%b3%e3%83%95%e3%82%a9%e3%83%bc%e3%83%89%e6%b3%95/#comments</comments>
		<pubDate>Fri, 06 May 2011 17:29:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[アルゴリズム]]></category>
		<category><![CDATA[グラフ]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3996</guid>
		<description><![CDATA[■実装 グラフは以下のようにして実装した。グラフは前回のものと同様だがベルマンフォード法では負の重みも存在しうるので、経路が存在しない部分はnullとした。 // Graph //前回のグラフと同じグラフを使用 var  [...]]]></description>
			<content:encoded><![CDATA[<h3>■実装</h3>
<p>グラフは以下のようにして実装した。グラフは前回のものと同様だがベルマンフォード法では負の重みも存在しうるので、経路が存在しない部分はnullとした。</p>
<pre class="brush: jscript;">
// Graph //前回のグラフと同じグラフを使用
var vertexes = [
     [null, 1,    3,    null, null, null],// vertex s
     [null, null, 1,    4,    null, null],// vertex 1
     [null, null, null, 1,    null, null],// vertex 2
     [null, null, null, null, 1,    10],//   vertex 3
     [null, null, null, null, null, 1],//    vertex 4
     [null, null, null, null, null, null] // vertex g
];

// initialize
var dist    = [];
var pred    = [];
for(var i = 0; i &lt; vertexes.length; i++){
    dist[i] = Number.POSITIVE_INFINITY;
    pred[i] = -1;
}
dist[0] = 0;// start

// 計算
(function(){
    var n = vertexes.length;
    for(var i = 1; i &lt;= n; i++){
        // i=nの時
        // destinationと自身が同じであるにも関わらず
        // 後述のnewLenの方が短い場合、
        // 負の閉路が存在していることを示す
        failOnUpdate = (i === n);
        leaveEarly   = true;
        for(var u = 0; u &lt; n; u++){
            for(var ci = 0; ci &lt; n; ci++){
                if(vertexes[u][ci] === null){continue;}//経路が存在しない
                var newLen = dist[u] + vertexes[u][ci];//頂点uを経由したciへの距離
                if(newLen &lt; dist[ci]){// 頂点u経由の方が短い場合はアップデートする
                    if(failOnUpdate){
                        throw new Error('Graph has negative cycle');
                    }
                    dist[ci] = newLen;
                    pred[ci] = u;
                    leaveEarly = false;
                }
            }
        }
        if(leaveEarly){
            break;
        }
    }
})();

// 結果表示
console.log(&quot;最短経路&quot;);
console.log(pred);// [-1, 0, 1, 2, 3, 4]
console.log(&quot;最短距離&quot;);
console.log(dist);// [0, 1, 2, 3, 4, 5]
</pre>
<p>但し、上述の場合では負の重みが存在しない。</p>
<h4>負の重み</h4>
<p>従って以下のデータでテストしてみる。</p>
<pre class="brush: jscript;">
var vertexes = [
     [null, 1,    3,    null, null, null],// s
     [null, null, 1,    4,    null, null],// 1
     [null, null, null, 1,    null, null],// 2
     [null, null, null, null, 1,    -10],// 3
     [null, null, null, null, null, 1],// 4
     [null, null, null, null, null, null] // g
];
</pre>
<p>以下のような結果となる。</p>
<pre class="brush: jscript;">
console.log(&quot;最短経路&quot;);
console.log(pred);// [-1, 0, 1, 2, 3, 3]
console.log(&quot;最短距離&quot;);
console.log(dist);// [0, 1, 2, 3, 4, -7]
</pre>
<p>3→gの距離が4を経由するよりも近くなり、s〜gの重みは-7となった。</p>
<h4>負の閉路</h4>
<p>以下のように閉路（ループ）で総和が負の値になるような経路を用意する。</p>
<pre class="brush: jscript;">
var vertexes = [
     [null, -1,   3,    null, null, null],// s
     [null, null, -10,  4,    null, null],// 1
     [5,    null, null, 1,    null, null],// 2
     [null, null, null, null, 1,    -10],// 3
     [null, null, null, null, null, 1],// 4
     [null, null, null, null, null, null] // g
];
</pre>
<p>以下のようなエラーが発生する。</p>
<pre class="brush: jscript;">
//Uncaught Error: Graph has negative cycle
</pre>
<p>ベルマンフォード法は負の重みがあった場合でも処理が可能であるが、総和が0より小さい負の閉路が存在していた場合は使用できない。但し、そのような場合は最短経路自体が意味を成さない。ちなみに密グラフには向かないアルゴリズムであるので、多次元配列（行列）でのグラフ生成は良くないかもしれない。(●´⌓`●)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/05/07/javascript%e3%81%a7%e3%83%99%e3%83%ab%e3%83%9e%e3%83%b3%e3%83%95%e3%82%a9%e3%83%bc%e3%83%89%e6%b3%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>overflowがscrollの時にアンカーにsmooth scrollできるjQueryプラグインを作ってみた</title>
		<link>http://blog.justoneplanet.info/2011/05/04/overflow%e3%81%8cscroll%e3%81%ae%e6%99%82%e3%81%ab%e3%82%a2%e3%83%b3%e3%82%ab%e3%83%bc%e3%81%absmooth-scroll%e3%81%a7%e3%81%8d%e3%82%8bjquery%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%e3%82%92/</link>
		<comments>http://blog.justoneplanet.info/2011/05/04/overflow%e3%81%8cscroll%e3%81%ae%e6%99%82%e3%81%ab%e3%82%a2%e3%83%b3%e3%82%ab%e3%83%bc%e3%81%absmooth-scroll%e3%81%a7%e3%81%8d%e3%82%8bjquery%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%e3%82%92/#comments</comments>
		<pubDate>Tue, 03 May 2011 15:39:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=4457</guid>
		<description><![CDATA[久しぶりのjQueryでのちょっとしたスクリプト。 ■クライアントコード // a[href=&#34;#target&#34;]をクリックすると#targetに#mainがスムーズスクロールする。 $('a[hre [...]]]></description>
			<content:encoded><![CDATA[<p>久しぶりのjQueryでのちょっとしたスクリプト。</p>
<p><script src="https://gist.github.com/1259350.js?file=jquery-box-scroll.js"></script><br />
<script src="https://gist.github.com/1259350.js?file=jquery-position-in.js"></script></p>
<h3>■クライアントコード</h3>
<pre class="brush: jscript;">
// a[href=&quot;#target&quot;]をクリックすると#targetに#mainがスムーズスクロールする。
$('a[href=&quot;#target&quot;]').click(function(e){
    e.preventDefault();
    $('#main').boxScroll($(&quot;#target-wrapper&quot;), $('#target'));
});
</pre>
<p>こんな感じで使う。気が向いたらブラッシュアップする。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/05/04/overflow%e3%81%8cscroll%e3%81%ae%e6%99%82%e3%81%ab%e3%82%a2%e3%83%b3%e3%82%ab%e3%83%bc%e3%81%absmooth-scroll%e3%81%a7%e3%81%8d%e3%82%8bjquery%e3%83%97%e3%83%a9%e3%82%b0%e3%82%a4%e3%83%b3%e3%82%92/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>緊急地震速報 by Extensionを作ったときの感謝をこめて</title>
		<link>http://blog.justoneplanet.info/2011/04/23/%e7%b7%8a%e6%80%a5%e5%9c%b0%e9%9c%87%e9%80%9f%e5%a0%b1%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%9f%e3%81%a8%e3%81%8d%e3%81%ae%e6%84%9f%e8%ac%9d%e3%82%92%e3%81%93/</link>
		<comments>http://blog.justoneplanet.info/2011/04/23/%e7%b7%8a%e6%80%a5%e5%9c%b0%e9%9c%87%e9%80%9f%e5%a0%b1%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%9f%e3%81%a8%e3%81%8d%e3%81%ae%e6%84%9f%e8%ac%9d%e3%82%92%e3%81%93/#comments</comments>
		<pubDate>Sat, 23 Apr 2011 03:35:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[サーバーサイド]]></category>
		<category><![CDATA[日記]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3969</guid>
		<description><![CDATA[「緊急地震速報 by Extension」を作って経験したことなどをまとめました。今回は後編です。前編は会社のブログに書きました。 僕は生産設備を持っていませんので食料をはじめとした物流における支援は難しいのかもしれませ [...]]]></description>
			<content:encoded><![CDATA[<p>「緊急地震速報 by Extension」を作って経験したことなどをまとめました。今回は後編です。前編は<a href="http://tech-gym.com/2011/03/html5/235.html">会社のブログ</a>に書きました。</p>
<blockquote><p>僕は生産設備を持っていませんので食料をはじめとした物流における支援は難しいのかもしれません。しかしながらシステムエンジニアとして間接的な支援や情報における支援はできます。僕は、天災における「破壊」を修復するのは人々の「生産」と考えるとともに、その「生産」の一部分を担う者として頑張っていきたいと思います。</p></blockquote>
<p>東北地方太平洋沖地震の後、余震が頻発し緊急地震速報の警告音も頻繁に耳にするようになりました。警告音に焦らされる一方で、本当は落ち着いて揺れに対処しなければならないと思っていました。そこで緊迫感を与えないような緊急地震速報を出せないものかと今回の制作にいたりました。（なので初期バージョンには音がなかったのです）</p>
<p>また、本当は「緊急地震速報 by Chrome Extension」という名前で登録しようとしたのですが「Chrome」というワードは使用ができないので「緊急地震速報 by Extension」という名前になりました。</p>
<h3>■プロキシ経由での接続</h3>
<p>大きな会社などではプロキシ経由でインターネットに接続するようになっていて配信サーバと接続ができないようでした。</p>
<h4>変更前</h4>
<p>ポート12001番を使用していました。</p>
<pre class="brush: jscript;">
var hosts = [
    '123.123.123.123:12001'
];
</pre>
<h4>変更後</h4>
<p>ポート443番を使用するように変更しました。</p>
<pre class="brush: jscript;">
var hosts = [
    '123.123.123.123:443'
];
</pre>
<p>HTTPSで使用するポートを用いることにより一部の方の接続が可能になりました。</p>
<h4>さらに変更後</h4>
<p>ポート443番、80、8080番、12001番を使用するように変更しました。</p>
<pre class="brush: jscript;">
var hosts = [
    '123.123.123.123:443',
    '123.123.123.123:80',
    '123.123.123.123:8080',
    '123.123.123.123:12001'
];
</pre>
<p>これによって判明したのは1/3〜1/4の利用者の方は443にしか接続できなかった事です。</p>
<section class="kakomi">
<h5>参考</h5>
<ul>
<li><a href="http://kumama.org/2010/03/websockets-proxy-trick/">websockets を proxy 環境でも利用する場合の注意点</a></li>
</ul>
</section>
<h3>■マルチバイト文字列のbroadcast</h3>
<p>今回、Websocketサーバからbroadcastする際、node-websocket-serverを使用したのですが日本語を正しく送信できませんでした。</p>
<h4>解決策</h4>
<pre class="brush: jscript;">
wsServer.broadcast('\\u3092');
</pre>
<p>こうすることでクライアント側には\u3092という文字列が送信されるようになります。</p>
<section class="kakomi">
<p>ちょっとライブラリの中をのぞいてみます。</p>
<h5>server.js</h5>
<p>broadcastメソッドです。</p>
<pre class="brush: jscript;">
this.broadcast = function(data) {
    manager.forEach(function(client) {
        clientWrite(client, data);
    });
};
</pre>
<p>上述のとおりforEachで回してます。clientWriteメソッドも確認します。</p>
<pre class="brush: jscript;">
function clientWrite(client, data) {
  if (client &amp;&amp; client._state === 4) {
    client.write(data, 'utf8');
  }
}
</pre>
<p>utf8としていされてwriteされています。</p>
<h5>manager.js</h5>
<pre class="brush: jscript;">
Manager.prototype.forEach = function(callback, thisArg) {
    var current = this._head;
    while (current !== null) {
        callback.call(thisArg, current.connection);
        current = current._next;
    }
};
</pre>
<p>this._headは連結リストの先頭の要素のようです。</p>
<pre class="brush: jscript;">
this._head = client;
</pre>
<p>clientオブジェクトが入っているようです。</p>
<pre class="brush: jscript;">
var client = {
    id: connection.id,
    _next: null,
    connection: connection
};
</pre>
<p>接続IDと接続、次の要素を保持しています。</p>
<h5>connection.js</h5>
<pre class="brush: jscript;">
function write(connection, data) {
    debug(connection.id, 'write: ', (new Buffer(data)).inspect());
    if (connection._socket.writable) {
        return connection._socket.write(data, 'binary');
    }
    return false;
}
</pre>
<p>binaryと指定されていますね。完全に読み切るには少々時間がかかるので適宜更新します。</p>
<h5>参考</h5>
<ul>
<li><a href="http://nodejs.org/docs/v0.4.8/api/all.html#socket.write">socket.write(data, [encoding], [callback])</a></li>
<li><a href="https://github.com/miksago/node-websocket-server/blob/master/lib/ws/server.js">miksago / node-websocket-server</a></li>
</ul>
</section>
<h3>■正規表現</h3>
<p>情報はtwitterのUser Streams API経由で取得していたのですが、ご利用者の方から震度やマグニチュードだけを簡略化して欲しいとの要望がありました。そこで正規表現を使用し文字列を整形して表示することにしました。ところが一部のご利用者には元の文章がそのまま表示されていました。</p>
<h4>解決策</h4>
<p>以下のようにして日本語をマッチさせるときに16進表現を使用することで解決しました。</p>
<pre class="brush: jscript;">
var reg = new RegExp('\u9707\u5EA6([3-9]\u5F37*\u5F31*)', 'ig');
text.match(reg);
var scale = RegExp.$1;
// filter : simplify
if(localStorage[&quot;simplify&quot;] !== &quot;false&quot;){
    var reg = new RegExp('([0-9]*/[0-9]*/[0-9]*)', 'ig');
    text.match(reg);
    var date = RegExp.$1;

    var reg = new RegExp('([0-9]*\:[0-9]*)', 'ig');
    text.match(reg);
    var time = RegExp.$1;

    var reg = new RegExp('\u30DE\u30B0\u30CB\u30C1\u30E5\u30FC\u30C9([0-9\.]*)', 'ig');
    text.match(reg);
    var magnitude = RegExp.$1;

    var reg = new RegExp('\u3001(.*?)\u306E', 'ig');
    text.match(reg);
    var place = RegExp.$1;

    if(date != '' &amp;&amp; time != '' &amp;&amp; place != '' &amp;&amp; scale != '' &amp;&amp; magnitude != ''){
        text = date + &quot; &quot; + time + &quot; &quot; + place + &quot;\n\u9707\u5EA6&quot; + scale + &quot;\n\u30DE\u30B0\u30CB\u30C1\u30E5\u30FC\u30C9&quot; + magnitude;
    }
}

// filter : scale
switch(localStorage[&quot;scale&quot;]){
    case &quot;7&quot;:
        if(parseInt(scale, 10) &lt; 7){return false;}
        break;
    case &quot;6&quot;:
        if(parseInt(scale, 10) &lt; 6){return false;}
        break;
    case &quot;5&quot;:
        if(parseInt(scale, 10) &lt; 5){return false;}
        break;
    case &quot;4&quot;:
        if(parseInt(scale, 10) &lt; 4){return false;}
        break;
}
</pre>
<p>ブラウザ側の言語設定は各々異なります。通信時の文字コードを指定しても解決するかもしれません。</p>
<h3>■twitterとの接続</h3>
<p>node.jsを使い、以下のようなコードでtwitterと接続してます。</p>
<pre class="brush: jscript;">
var client = http.createClient(
    80,
    &quot;stream.twitter.com&quot;,
    false,
    false,
    {
        &quot;username&quot; : &quot;hogehoge&quot;,
        &quot;password&quot; : &quot;fugafuga&quot;
    }
);
var request = client.request(
    &quot;GET&quot;,
    &quot;/1/statuses/filter.json?follow=123456789&quot;,
    {
        &quot;host&quot; : &quot;stream.twitter.com&quot;
    }
);
request.end();
request.on(
    &quot;response&quot;,
    function(response){
        //sys.puts(&quot;response&quot;);
        var chunk = '';
        response.on(
            &quot;data&quot;,
            function(data){
                // データ受信処理
            }
        );
        response.on(
            'end',
            function(){
                // twitterから接続を切られた時
            }
        );
    }
);
</pre>
<h4>twitter切断時</h4>
<p>実はたまに接続を切られます。切断される可能性を考慮し以下のようなコードを使用してます。</p>
<pre class="brush: jscript;">
var getRequest = function(){
    var request = client.request(
        &quot;GET&quot;,
        &quot;/1/statuses/filter.json?follow=123456789&quot;,
        {
            &quot;host&quot; : &quot;stream.twitter.com&quot;
        }
    );
    request.end();
    request.on(
        &quot;response&quot;,
        function(response){
            response.on(
                &quot;data&quot;,
                function(data){
                    // データ受信処理
                }
            );
            response.on(
                'end',
                function(){
                    // twitterから接続を切られた時
                    r = getRequest();// 再接続
                }
            );
        }
    );
    return request;
}
var r = getRequest();
</pre>
<p>通信は必ず切れるものと考えてコードを書かなくてはいけませんね。さらに実は以下のようなスクリプトも実行してます。</p>
<pre class="brush: jscript;">
request.on(
    &quot;response&quot;,
    function(response){
        //sys.puts(&quot;response&quot;);
        var chunk = '';
        response.on(
            &quot;data&quot;,
            function(data){
                // データ受信処理
            }
        );
        response.on(
            'end',
            function(){
                // twitterから接続を切られた時
                throw new Error('twitter disconnected me!!');
            }
        );
    }
);
</pre>
<p>node.jsにおいてcatchできなかったErrorはプロセスを終了させます。従って以下のようなシェルスクリプトと組み合わせてプロセスが終了してないか定期的にチェックし、終了していた場合は再起動することで接続を維持しています。</p>
<pre class="brush: bash;">
#!/bin/sh
while true
do
    isAlive=`ps -ef | grep &quot;my-websocket-server.js&quot; | grep -v grep | wc -l`
     if [ $isAlive -ge 1 ]; then
        echo &quot;process is alive&quot;
    else
        node my-websocket-server.js.js
        echo &quot;process is dead&quot;
    fi
    sleep 3
done
</pre>
<h3>■アップデート</h3>
<p>拡張機能のアップデートは自動で行われますが、新バージョンを登録してすぐに全ユーザのアップデートが完了するわけではありません。意外にも早く直後にアップデートされる方もいれば、時間がかかる方もいます。1時間で10%程度の方がアップデートされるようです。一方、90%のユーザはアップデート前のクライアントでサーバに接続しますので考慮して更新しなければなりません。</p>
<h3>■起動</h3>
<p>ちなみにですが以下のコマンドでWebSocketサーバを起動してます。</p>
<pre class="brush: bash;">
nohup ./check.sh &gt; log.txt &amp;
</pre>
<p>接続数を調べるには以下のようなコマンドを使ってます。</p>
<pre class="brush: bash;">
lsof -i:12345 | grep &quot;node&quot; | wc -l
</pre>
<h3>■twitterからの文字列</h3>
<p>システムの設計の問題にもなりますが、twitterからの文字列が正しくパースできないようなケースが稀にあります。入力は受け手側が意図する形式になるとは限らないということです。</p>
<dl>
<dt>文字列をパースできるように条件分岐する</dt>
<dd>但し、ブラックリスト方式に近いので未知の正しくない文字列はパース出来ない</dd>
<dt>データストアを作って保存に対してbroadcastのトリガを引かせる</dt>
<dt>全てのサーバが正しくパースできなかった事はないので非常に有用だが、失敗する確率はわずかながらある</dt>
</dl>
<h3>■サーバ負荷</h3>
<p>node.jsの素晴らしさを実感する毎日ですが、接続数が1万数千を超えるとさすがに0.5〜1秒程度遅延します。早く多くの方に届けるべき情報ではあるものの、一方で多くの方が接続すると遅延が生じやすくなります。サーバは個人で賄っているので限度があります。非常に難しい問題です。財閥の末裔だったらデータセンターごと買うのになと思う毎日です。</p>
<h3>■まとめ</h3>
<p>僕は水や電気の節約には賛成です。しかしながら根拠が不明瞭な自粛ムードには反対です。冒頭で述べました通り、破壊を修復するのは生産であり、手を止めて遠慮する事では無いと思います。何もできることがないと考えた結論の自粛より、いつも通り働き、学び、生活する方が生産的だと僕は考えます。まだまだ対応できていない事ばかりで完璧ではありませんが今後とも宜しくお願いいたします。早く余震が収まるといいですね。(●´⌓`●)</p>
<h4>拡張機能への要望</h4>
<p>今まで通り<a href="http://twitter.com/#!/mi_eqbot">@mi_eqbot</a>までお願いいたします。自分のブログよりも確実にチェックしてます。w</p>
<h4>その他開発などへの興味</h4>
<p><a href="http://twitter.com/#!/mitsuaki_i">@mitsuaki_i</a>までお願いいたします。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/04/23/%e7%b7%8a%e6%80%a5%e5%9c%b0%e9%9c%87%e9%80%9f%e5%a0%b1%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%9f%e3%81%a8%e3%81%8d%e3%81%ae%e6%84%9f%e8%ac%9d%e3%82%92%e3%81%93/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>node.jsでモジュールを作る</title>
		<link>http://blog.justoneplanet.info/2011/04/16/node-js%e3%81%a7%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%9c%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/04/16/node-js%e3%81%a7%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%9c%e3%82%8b/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 13:03:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[サーバーサイド]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3960</guid>
		<description><![CDATA[以下のようなコードを考える。 var sys = require('sys'); var dog = { &#34;pochi&#34; : 16, &#34;john&#34; : 10 }; var getD [...]]]></description>
			<content:encoded><![CDATA[<p>以下のようなコードを考える。</p>
<pre class="brush: jscript;">
var sys = require('sys');

var dog = {
    &quot;pochi&quot; : 16,
    &quot;john&quot;  : 10
};
var getDogAge = function(name){
    return dog[name];
}

sys.puts('pochi is ' + getDogAge('pochi') + ' years old.');
</pre>
<p>以下のようにモジュール化すると非常にすっきりする。</p>
<h3>■モジュール側</h3>
<p>以下のように記述する。ちなみにgetメソッドなどは予約されていて使用できないようだ。</p>
<pre class="brush: jscript;">
var dog = {
    &quot;pochi&quot; : 16,
    &quot;john&quot;  : 10
};
exports.getAge = function(name){
    return dog[name];
}
</pre>
<p>クライアント側から使用するメソッドやプロパティはexportオブジェクトのプロパティとする。それ以外のグローバル空間にある変数や関数はクライアント側からは見えず、プライベート扱いとなる。</p>
<h3>■クライアント側</h3>
<p>以下のようにして使用する。</p>
<pre class="brush: jscript;">
var sys = require('sys');
var dog = require('./dog.js');
sys.puts('pochi is ' + dog.getAge('pochi') + ' years old.');
</pre>
<p>また以下のようにした場合は</p>
<pre class="brush: jscript;">
var Dog = function(name){
    var self = this;
    self.name = name;
    self.cry = function(){
        sys.puts(self.name);
    }
}
module.exports = Dog
</pre>
<p>以下のように使用することができる。</p>
<pre class="brush: jscript;">
var Dog = require('./dog.js');
var dog = new Dog();
</pre>
<p>すっきり。簡単。(●´ω｀●)</p>
<h3>■参考</h3>
<ul>
<li><a href="http://nodejs.org/docs/v0.4.6/api/modules.html#modules">Modules</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/04/16/node-js%e3%81%a7%e3%83%a2%e3%82%b8%e3%83%a5%e3%83%bc%e3%83%ab%e3%82%92%e4%bd%9c%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pywebsocketをインストールする</title>
		<link>http://blog.justoneplanet.info/2011/04/10/pywebsocket%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/</link>
		<comments>http://blog.justoneplanet.info/2011/04/10/pywebsocket%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 13:25:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[サーバーサイド]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=3949</guid>
		<description><![CDATA[■pywebsocket単体で動作させる draft75 vi /home/pywebsocket-0.5.2/src/mod_pywebsocket/standalone.py 以下の部分を parser.add_op [...]]]></description>
			<content:encoded><![CDATA[<h3>■pywebsocket単体で動作させる</h3>
<h4>draft75</h4>
<pre class="brush: bash;">
vi /home/pywebsocket-0.5.2/src/mod_pywebsocket/standalone.py
</pre>
<p>以下の部分を</p>
<pre class="brush: python;">
parser.add_option('--allow-draft75', dest='allow_draft75',
                      action='store_true', default=False,
                      help='Allow draft 75 handshake')
</pre>
<p>以下のように変更する。</p>
<pre class="brush: python;">
parser.add_option('--allow-draft75', dest='allow_draft75',
                      action='store_true', default=True,
                      help='Allow draft 75 handshake')
</pre>
<h4>起動</h4>
<pre class="brush: bash;">
python /home/pywebsocket-0.5.2/src/mod_pywebsocket/standalone.py -p 8800 -d /home/pywebsocket-0.5.2/src/example
</pre>
<p>WebSocketで8800ポートにアクセスする。(●´ω｀●)</p>
<h3>■apacheモジュールとして動作させる</h3>
<h4>http-devel</h4>
<pre class="brush: bash;">
yum install http-devel
</pre>
<h4>mod_python</h4>
<pre class="brush: bash;">
wget http://archive.apache.org/dist/httpd/modpython/mod_python-3.3.1.tgz
tar xvzf mod_python-3.3.1.tgz
cd mod_python-3.3.1
./configure –with-apxs=/usr/sbin/apxs –with-python=/usr/bin/python
make
make install
</pre>
<h5>設定</h5>
<pre class="brush: bash;">
vi /etc/httpd/conf.d/python.conf
</pre>
<p>以下の記述の下に</p>
<pre class="brush: bash;">
LoadModule python_module modules/mod_python.so
</pre>
<p>以下の記述を付加する。</p>
<pre class="brush: bash;">
AddHandler mod_python .py
</pre>
<h4>mod_pywebsocket</h4>
<pre class="brush: bash;">
wget http://pywebsocket.googlecode.com/files/mod_pywebsocket-0.5.2.tar.gz
tar xvzf mod_pywebsocket-0.5.2
cd pywebsocket-0.5.2/src
python setup.py build
python setup.py install
</pre>
<h5>設定</h5>
<pre class="brush: bash;">
vi /etc/httpd/conf.d/python_mod_pywebsocket.conf
</pre>
<p>以下を記述する。</p>
<pre class="brush: xml;">
&lt;IfModule python_module&gt;
    PythonPath &quot;sys.path+['/usr/lib/python2.4/site-packages/']&quot;
    PythonOption mod_pywebsocket.handler_root /var/www/html/wsh
    PythonHeaderParserHandler mod_pywebsocket.headerparserhandler
    PythonOption mod_pywebsocket.allow_draft75 On
&lt;/IfModule&gt;
</pre>
<pre class="brush: bash;">
/etc/init.d/httpd restart
</pre>
<h4>起動</h4>
<pre class="brush: bash;">
cp /home/pywebsocket-0.5.2/src/example/echo_wsh.py /var/www/html/wsh/
</pre>
<p>WebSocketクライアントで/echoにアクセスする。(●´ω｀●)</p>
<h3>■ベンチマーク</h3>
<p>正確性は微妙だが100クライアントからの接続でのロードアベレージは、「node : pywebsoket(standalone) : pywebsoket(apache) = 0.15 : 0.25 : 0.8」となった。最初の2つの差は微妙だったが、Apacheモジュールとして動作させた時のリソースの消費量は明らかに大きいようだ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2011/04/10/pywebsocket%e3%82%92%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

