エンジニアには日々の情報収集が欠かせません。エンジニア足るもの、その収集方法自体を改善したくなりますね。初開催の春のjigインターン、テーマは短い時間で濃い情報収集。

開発開始!

ウェブサイトの入口といえば index.html ですが、Googleなどのサーチエンジンなど、プログラムによる自動閲覧(クローラー)のための入口は robots.txt。AllowとDisallowで辿っていいところとだめなところ、サイトマップ(sitemap.xml)が記述されています。 「サイトマップの作成と送信 - Search Console ヘルプ」によると、ひとつのサイトマップに50MB or 5万URLまで設定できるとのこと(オーバーする場合は sitemapタグ を使いましょう、500コまで)


長らく放置してしまっていた一日一創 robots.txt を更新!オープンデータな当サイト、もちろん全件 Allow です。今回サイトマップ(sitemap.xml)も追加! 2012年の一日一創はまだいれてませんが、アプリなど含めて、5,650ページあったようです。

人間のためのHTMLという言語は、プログラムでは理解しづらいので、統一されたボキャブラリー(語彙)を HTML5 の itemscope 属性を使って、意味を明示することができます。
例えば、映画を紹介するHTMLはこんな感じ。(参考、Getting Started - schema.org

<div itemscope itemtype="http://schema.org/Movie"> <h1 itemprop="name">AKIRA</h1> <div>監督: <span itemprop="director">大友克洋</span></div> <div>ジャンル: <span itemprop="genre">SFアニメ</span></div> <div>出典: <a itemporp="url" href="https://eiga.com/movie/34459/">AKIRA : 作品情報 - 映画.com</a></div> </div>

itemscope と itemtype で、そのデータが何なのかを明示(この場合、映画 Movie)し、itempropを使って監督(director)、ジャンル(genre)、出典URL(url)を属性として明示しています。 「AKIRA : 作品情報 - 映画.com」のサイトでも、itemscope / itemtype / itemprop が使われているので、ソースを見てみましょう。

ブログ「一日一創」の記事は Article(記事) を使ってマークアップしました。

サイト検索が使えることも opensearch を使って、明示。ブラウザによってデフォルトの検索エンジンにしたり、いろいろと便利にしてくれます。検索の利便性も上げないと!

マシンリーダブルなウェブは、エンジニアフレンドリー!

tags
- 所要時間: 3分
- ジャンル: 3分でわかるTech記事

webの本質は共同作業、みんなの力をキュートに集めるウェブサービス、自分でも創ってみたいですね。 進化するプログラミングの世界、随分簡単にステキなサービスが作れるようになりました。

今回は、IchigoJam BASICからのステップアップにイチオシの言語「JavaScript」と便利ツール「Node.js」を使った「チャット」づくりのチュートリアル!

みんなの力を集めるには、ひとりひとりが持つコンピューターからデータを集約するために、いつも動いているコンピューター、サーバーが必要です。ひとまず、今使っている自分のパソコンでOKをサーバーにしてみましょう!

そんなサーバー上で動かすための便利ツール「Node.js(ノード・ジェイ・エス)」を使えば、サーバー上でもJavaScriptが使えます。

まずは Node.js をインストール!
(初心者の方へ、PDF WebサービスはじめのいっぽJavaScript / Node.js版
【Node.js入門】各OS別のインストール方法まとめ(Windows,Mac,Linux…) | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

GitHubから今回のチャットサービス「nodechat」をダウンロード。
ダウンロードしたファイル、まずは JavaScript での基本表示。console.logを使って、計算しましょう。(step0.js)

console.log(1 + 1)

こちら、コンソールを開いて、ダウンロードしたフォルダに移動し node コマンドを使って動かします。

node step0.js 2

1+1の計算ができました!

続いて、ウェブサーバーを作ります。(step1.js)

const http = require('http') const server = http.createServer() server.on('request', function(req, res) { console.log(req.url) res.writeHead(200, { 'Content-Type' : 'text/html; charset=utf-8' }) res.write('ハロー<br>req.url: ' + req.url) res.end() }) server.listen(8001)

こちらも同じように動かします

node step1.js

何も出ずに固まっている?エラーが出てなければ無事動いているはずです。ブラウザで http://localhost:8001/ を開いてみましょう。

ブラウザのアドレス欄、URLの末尾に数字やアルファベット足してエンター、アクセスしてみましょう(例:http://localhost:8001/abc)。nodeを実行した画面にも、ブラウザにも表示されますね。 端末側(クライアントと呼びます)からのデータを、サーバーで処理し、クライアントに返すがウェブの基本です!

※ localhostというのは自分のコンピューターを表し、コロンの後はポート番号といって窓口のID的なものです。同じ番号の窓口で複数のサーバーは起動できないので、必要であれば番号 8001 を好きな数に変えましょう(推奨:1024〜49151)。

step2.js で、static フォルダに入っているHTMLファイルや画像ファイルを返すようなプログラムを追記します。requireを使ってサーバー上のファイルを返す、簡単なウェブサーバー機能 simplewebserver.js を追加すると、画像つきのウェブページが見えるようになります。

step3.js で、クライアント側とデータをやりとりするAPIのベースを作成、/api/ で始まるパス名が来たら API として処理することにします。

server.on('request', function(req, res) { console.log(req.url) if (req.url.startsWith('/api/')) { const urlp = url.parse(req.url, true) res.writeHead(200, { 'Content-Type' : 'application/json; charset=utf-8' }) console.log(urlp.query) res.write(JSON.stringify(urlp.query)) } else { simplewebserver.serve(res, req.url) } res.end() })

そしていよいよ step4.js でチャットを実現するAPIを追加!
こちらがそのハイライト、サーバーのデータを操作しています。

let data = [] function serveAPI(fn, query) { if (fn.endsWith('/add')) { data.push(query) return data } else if (fn.endsWith('/list')) { return data } else if (fn.endsWith('/get')) { return data[query.idx] } else if (fn.endsWith('/clear')) { data = [] return data } else if (fn.endsWith('/remove')) { data.splice(query.idx, 1) return data } return { res: "OK" } }

5つのAPIを実装しました(addで追加、listで全部取得、getで1つ取得、clearで全件消去、removeで1つ消去)
こちらを動かし http://localhost:8001/chat.html を開きましょう。文字をいれて SENDボタンで、1行追記されます。別のウィンドウでも開いて一人二役チャットをやってお試しください。

ipconfig (Windows) や ifconfig (Mac/linux) を使って、今使っているIPアドレスを見つけたら、同一ネットワーク内にいる人や、Wi-Fiにつないだスマホから、IPアドレスで参加できます!(例、http://192.168.1.13:8001/chat.html )

chat.html 内は、何もフレームワークを使わないシンプルなJavaScriptでできています。

window.onload = function() { const fetchJSON = async function(path) { return await (await fetch(path)).json() } const show = function(data) { console.log("show", data) let s = "" for (let i = 0; i < data.length; i++) { const d = data[i] s += `<div><span>${d.ts}: </span><span>${d.text}</span></div>\n` } list.innerHTML = s } const update = async function() { const data = await fetchJSON('/api/list') show(data) setTimeout(update, 3000) } update() send.onclick = async function() { const text = encodeURIComponent(nickname.value + ": " + chat.value) const ts = Date.now() show(await fetchJSON(`/api/add?text=${text}&ts=${ts}`)) chat.value = "" } remove.onclick = async function() { show(await fetchJSON('/api/remove?idx=0')) } removeall.onclick = async function() { show(await fetchJSON('/api/clear')) } }

この状態だと、サーバーを止めるとデータが消えてしまうので、ファイルとして保存するようにしたのが step5.js です。require('fs')を使った違いを見てみましょう。

以上でチュートリアル終了です。おつかれさまでした!疑問に思ったところは、いろいろ変えたり、調べたりしてみましょう!分からないことあれば、@taisukef までメンション/DM大歓迎です!(より良いチュートリアルに仕上げたいので)

テキスト、絵、音声、画像など、どんなデータを集めて、どう見せる?
それはあなたの自由です!

実際にネット上のみんなに使ってもらうためには、常時動かしておくサーバーが必要です。 自宅のパソコンを動かし続けてもOKですし、Herokuで無料で始めてみたり、さくらインターネットのVPSや、ConoHa(1時間1円!)などで借りることもできます。


春のjigインターン、開始!


SCCにて、IchigoDyhookを使ったIchigoJamプログラミング教え方講座


はじめてIchigoJam BASICを触った高専生による改造されたかわくだりゲーム


こちらソース!


めがね会館、見学!明日から開発開始!

tags
- 所要時間: 3分
- ジャンル: 3分でわかるTech記事

links
- JavaScript(Node.js)編 src on GitHub
- PDF WebサービスはじめのいっぽJavaScript / Node.js版
- Vue.js x Node.js でつくろう、ウェブサービスの基本「チャット」ハンズオン

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / RSS