Windows 10がSleep状態から回復しない問題の対応

| 固定リンク
| コメント (0)
| トラックバック (0)
| 固定リンク
| コメント (0)
| トラックバック (0)
やはりAngularJSの勢いがすごいですね。
| 固定リンク
| コメント (0)
| トラックバック (0)
先月35歳になった私は、人生で6度目の転職活動を行った。
今回初めてプログラマとしてではなく、違うキャリアを意識
して活動した。
具体的には、ECサイトやアクセスの解析を行う会社など、
マーケティングやユーザの行動解析のノウハウが身に付く
ような会社を選択した。
今まで、自分のプログラミングスキルを上げることが、自分
の付加価値の向上につながると思ってきたし、事実そうだった
と思う。
ただクラウド上にスケーリングするようにサーバ構築から、
DB設計、アプリ開発まで一通りできるようになった今、更に
プログラミングスキルを上げたり、扱える言語の数を増やす
ことが自分の付加価値をあげることかと考えた時に、そうで
はないと感じた。
私がプログラマとしてすごい奴なのかと言われたら、
全然そんなことはなく、大学生のTwitterやBlogを見ても、
あぁこの人には歯が立たないという人がたくさんいるし、
更に中学生でさえ、敵わないと思う人がいる。
逆にできないプログラマかと言うと、そうでもない。
このプロジェクトは、私でないと成功しなかったと言ってく
ださったプロジェクトが何個もあったり、20近くプロジェクト
を経験したが、私よりできるプログラマはそれほど多くなかった
ことを考えると、できるほうだと思う。
プログラマは、ピラミッド階層になっていて、高いところを
見ると果てしなく高く、下を見るとたくさんの人がいる。
大学時代、就職活動で初めてPCを触り、F2 SetUpの文字に
OSの起動はF2なのかと思い、押下してBIOSが表われ、
あたふたしたり、InternetExplorerの初期ページが大学の
ページになっていて、リンクを押しまくっても休講のページ
や施設案内のページにしかたどりつけなくて、どうやったら
皆のように、yahooのページに行けるのか悩んでいた私が、
気がついたら今の位置にいた。
ここで表題の業界でよく話題になるプログラマ35歳限界説
についてだが、35歳になって以前よりプログラミング能力が
落ちたかと言うと、まったくそんなことはない。ひらめきは
多少落ちたかも知れないが、以前より経験と知識がある分、
上手に書けるし、プログラミングも相変わらず楽しい。
それでも、35歳にしてプログラミングとは違うキャリアを
指向した理由は、一般的なシステムなら構築できるスキルを
得た状態で、さらに上を目指すよりも、他の知識を身につけ
るほうが役に立てると考えたから。
プログラミングだけで活躍できれば、話は楽なのだが、
y combinatorで混乱したり、モナドの説明を何度見ても
いっこうに理解できる気がしない私がそこを目指すのは
無理があるなぁと。
そこで最近どの企業に行っても、アクセスログ分析、ユーザ
特性・動向分析を行いたいが、できていないと聞き、その
分野はプログラミングが必要だが、大事な解析の部分は
経験・ノウハウによるところが大きいので、そこを身に
つけていくことにした。
また、今まで意識したことがなかったマーケティングも、
どの業界がどのぐらい全国にあるか、各業界の売上はどの
くらいか、業界内の各企業の割合、主要顧客の年齢・性別の
割合、よく使われているソフトなどを知ることで、より戦略的に
立ち回れるようになりたいと考えた。
もちろん、プログラミングが中途半端になると、ただ遠回り
しただけになってしまうので、今後も勉強していくし、そも
そも採用はプログラマで採用されているという。
社会人人生の折り返しとして、スタートを切ったつもりで
貪欲に新しいことに取り組んでいきたい。
| 固定リンク
| コメント (3)
| トラックバック (0)
この記事はNode.js Advent Calendar 2013 19日目の記事となります。
Push通知のフレームワークとしてSocket.IOがよく使われています。
Socket.IOは、Websocketが使えない環境でもPUSH通信を可能とすることで有名ですが、それ以外にも、namespace機能やroom機能、イベントを自由に使えるなど、直接websocketを使うよりも便利な機能が多くあります。
機能は豊富ですが、書き方にルールを決めずに気軽にあちらこちらでpushを使うと、見通しが悪く保守が大変なアプリになってしまいます。
そこでSocket.ioがベースの、簡単で保守しやすいプログラムが書けるsocket.io-reqevというフレームワークを紹介します。
socket.io-reqevは、pubsub機能 + requstごとの応答(HTTPのGETに該当)を簡単に行うために作られています。
クライアント(ブラウザ)とサーバ(node.js)側にそれぞれにライブラリが用意されています。
URL(socket.ioホスト名 + path)とコールバックを指定してsocket.io-reqevオブジェクトを作成し, watchメソッドに購読したいイベント名とrequestオブジェクトを指定するだけです。
サーバから応答があると指定したコールバックが呼び出されます。
socket.io-reqevオブジェクトを作成します。
eventsフィールドとrequestメソッドを持つオブジェクト(サービスと呼ぶ)をPathを指定してsocket.io-reqevオブジェクトに登録します。
クライアントからの通信にeventsフィールドがあると、eventsフィールドのeventごとにイベント名のroomにクライアントを登録し、サービスがイベントを発行すると、サービスが発行したイベント名と同じroomに登録されているクライアントにイベントの通知がいきます。
クライアントからの通信にrequestsフィールドがあると、requestsフィールドのrequestごとにサービスのrequestメソッドにそのrequestが渡され、requestメソッドからのcallbackを通じた応答をクライアントに返します。
npm install socket.io-reqev
概要を体感するために上記のリンク先のデモを実行してみてください。
Demoではサーバ側にタイマーサービスとして、5秒、10秒,30秒ごとに時間を通知するイベント(five,ten,thirty)と現在の時間を返すcurrentというリクエストが用意されています。
クライアント側には、それらごとにチェックボックスを用意して、sendボタンを押すごとに、チェックに応じたwatchが実行され、サーバからの応答をすべて画面の下部に追記していきます。
requestのcurrentにチェックがついている場合は、sendボタンを押したら即座に一度だけ、現在の時間が書き込まれます。
eventsの5秒、10秒、30秒は、秒がそれぞれ5、10、30で割り切れる時間になった時はずっと応答が返ってくるため、5秒、10秒にチェックが入っている場合は、00:00:05の時は1つだけ書きこまれ、00:00:10の時は5秒と10秒のイベント2つが応答を返すため、2つ書きこまれます。
sendは何度でも押せます。つまりwatchメソッドは何度でも呼び出し可能です。
sendを押すごとに前回購読していたイベントはとりやめられ、新たなイベントで上書きされるので、ブラウザのnetworkを見ると、イベントを減らすと通信も減ることがわかります。
スマホのWebサイトの場合は、通信量とバッテリ消費の結びつきは大きいため、購読だけでなくとりやめも簡単なのはすごく使い勝手がいいです。
socket.io-reqvのオブジェクトをsocket.ioオブジェクトを渡して初期化しています。
timerサービスを/timerで登録しています。
本質的なところは以上です。
temporary web server以下のソースは、index.htmlやjs配下のJavaScriptを返すためのWebサーバ機能です。
Timerサービスの実装になります。
serviceとしての要件であるeventsフィールドとrequestメソッドがあります。
socket.ioに依存がないので、テストがしやすそうですね!
this.eventsに5秒、10秒、30秒ごとに通知を行うためのfive,ten,thirtyのイベント名がセットされています。
サービスの初期処理で1秒ごとのタイマーを実行していて、その中で現在秒が割り切れた場合にイベントを発生させています。
また、requestメソッドも用意して、クライアントからcurrentという文字列がきた場合は現在時刻の文字列を返しています。
requestに引数がほしい場合は、requestとして文字列ではなく、オブジェクトを渡すことで実現できます。
backbone.jsのcollectionとviewをindex.htmlに埋めこんでしまっているためちょっと見づらいです。
すみません。
socket.io-reqevが直接関わっているのは18行目から30行目までです。
viewの初期処理
viewのrender処理
viewのイベント
timerCollectionのwatchメソッド
viewのremoveメソッド
今回はどこにも呼び出し箇所がない。
ブラウザのjavascriptコンソール上でv.remove()と実行することで呼び出し可能。
Viewが破棄され画面が真っ白になる。
Backbone.jsの決まりとしてveiwの開放時にviewのremoveを呼び出すことでview内でlistenToで登録されたイベントハンドラが開放されるが、timerや今回のようなsocket.ioのリソースは自分で開放する必要がある。
viewの中でremoveをオーバーロードして、そこでsocket.ioのリソースを開放している。
それによりsocket.ioの通信がstopする。(socket.ioの死活監視の通信は残る)
去年にNode.js + WebSocket + Backbone.jsのすすめ という記事を書いてその中で実装はちょっと大変だみたいなことを書きましたが、その後経験をつみ、このようなライブラリを使うことで、効率的にアプリを書けるようになりました。
よそよそしく紹介しましたが、socket.io-reqevは自作です。
server側のio-reqev.jsは57行、client側のio-reqev-client.jsは61行というソースの小ささのため、socket.ioを知っている人が見るとすぐ理解できると思います。
Backbone.jsもそうですが、ライブラリが小さくても、考え方の導入次第でプログラムの作りを大きく改善できます。
ライブラリが小さいと、ソースも読めて融通もきいていいですね。
| 固定リンク
| コメント (0)
| トラックバック (0)
| 固定リンク
| コメント (0)
| トラックバック (0)
最近Require.jsが取り上げられることが多いのですが、私は使っていません。
Backbone.jsを使ったアプリには、非同期ローディングよりも、Javascriptをひとつのファイルにまとめてminifyして、gzip圧縮して最初に読み込んでしまうほうがいいと思ってます。
例えば今開発しているアプリのJavaScriptのそのままのSizeは651KBですがminifyすると517KBになり、gzip圧縮すると117KBとなります。
Node.jsを使っている私の一押しはやっぱりmincer です。
mincerの解説はAsset Pipelineのすすめ を参照ください。
mincerは、minify,gzip圧縮の機能はないので、別に対応する必要があります。 さらにそのファイルをS3にアップロードして、S3にJavaScriptをホスティングしてもらうまでのNode.jsのscriptを作成しました。
|
上記スクリプトの'' ''で囲まれている箇所は適切な値に置き変えてください。 また、mincerのmanifestファイルはapp/assets/javascripts/application.js だと仮定しています。適切に書き換えてください。
minifyには、googleのclosure-compilerのWebサービスを使って行なっています。
closure-compilerはjarとして、提供されているのでそれを使うのもいいと思います。Webサービスは極まれに落ちていることがあるし、今後もサービスが続くとは限らないので。ただ、Javaをinstallしていない環境を考慮したり、jarがそこそこ大きいので配布するのも面倒だったため、Webサービス利用にしました。
上記コマンドを実行すると、lib/compiled.jsに下記のようにs3のURLの定数が定義されます。(下記URLは適当)
app.jsを下記のようにすることで、開発の場合は動的compileによりファイルの変更を即座に変更するようにしています。
|
index.ejsは下記
<% if(js_path){ %> <script type="text/javascript" src="<%- js_path %>"></script> <% }else{ %> <script type="text/javascript" src="/assets/application.js"></script> <% } %>
| 固定リンク
| コメント (0)
| トラックバック (0)
Ajaxはsame origin policyのため、AjaxのリクエストだったらCSRF対策いらないのでは?
残念。
FlashやJava appletを利用した場合にcsrfが起こる可能性があるそうです。
(参考: Rails 3.0.4と2.3.11からXHRリクエストの際もCSRFトークンの検証が必須になったので注意)
Backbone.jsを使っているとAjax部分は勝手に行われるので、CSRF対策のために拡張する必要がありそうです。
Stack Overflowを調べても、tokenを渡せばいいんじゃない?のそっけない返答しかなかったので、実装してみました。
概要
実装
app.js
1 2 3 4 5 6 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
| 固定リンク
| コメント (0)
| トラックバック (0)
はじめに
|
上記のサンプルを任意の場所のファイルにコピーして
ブラウザでそのファイルにアクセスしてみてください。
(例) Macで/Users/takeshy/work/route.htmlという
名前でコピーした場合のURL。
file:///Users/takeshy/work/route.html
Routerのsampleについて
Routerは、Backbone.Routerを拡張します。routesの
プロパティに#以降のPATHをキーに、呼び出すメソッド
名の文字列を値としたHashを設定します。
そうすることで、Backbone.history.startのメソッドを
実行すると、#以降のPATHに応じて登録したメソッドを
実行してくれるようになります。
Pathに:名前を含めれば、(Sampleでは/greeting/:language
の部分)登録メソッドに対して:名前にあたる部分を引数
として渡すことができます。
また.*のように単に一致を判定したい場合は正規表現を
使えます。
Webサーバなしでページが遷移できることや、ブラウザの
戻る、進むボタンの対応や、特定のページをブックマーク
すると、ブックマークしたページの内容が表示されること
が確認できます。
※ここでは説明のためにRouteクラスをhtml内に記述して
いますが、普通は別jsに切り出します。
Modelについて
アプリの中心であるビジネスロジックのオブジェクト。
例えば、UserのModelだったら、名前やE-mail等の属性
を持ちます。
Modelのオブジェクトの集合を表わすCollectionと呼ば
れるクラスもあります。
Backbone.ModelやBackbone.Collectionを拡張することで
たくさんの機能が提供されます。
提供される機能
イベントのトリガー(Model & Collection)
Collectionの場合、内容を置き換えた場合はreset,
Modelのオブジェクトを追加した場合はadd、削除
した場合はremoveイベント等が発行されます。
Modelの場合、内容を変更した場合はchange,削除
した場合はdestoroyイベント等が発行されます。
データのSetter,Getter,validate(Modelのみ)
Modelオブジェクトに対して、defaults属性もしくは、
initialize({属性名:値})、もしくはset({属性名:値})
メソッドでセットした値は直接Modelオブジェクトの
属性にセットされるのではなく、attributesとよばれる
属性の中にセットされて、取得する場合は、get(属性名)
で取得できるようになります。
間接化することで、setメソッド実行によるchangeイベント
の発行やAjaxの送信にはattributesの内容のみを送信する
ので、Webサーバに送信しない属性を持つことができます。
validateメソッドを定義すれば、set時に値の妥当性を
チェックすることができ、不正時は、戻り値をセットする
ことで、errorイベントが発行され不正な値のセットを
防ぐことができます。
Ajax(Model & Collection)
RESTを前提として、save()やfetch()メソッドの実行で自動
的にAjaxでWebサーバにアクセスします。
ただし予めurl属性がセットされている必要があります。
Collectionのオブジェクトに対してfetchメソッドを呼びだ
すと、GET urlが実行されAjaxの戻り値の配列のJSONをmodel
の属性にもつModelオブジェクトに変換して、保持します。
IDがセットされたModelのオブジェクトに対してfetch()を
実行すると、GET urlRoot/IDの戻り値のJSONをModelの属性
にセットしします。またIDが未セットのModelのオブジェクト
にsave()を実行した場合、POST /urlRootのAjaxが実行され、
IDがセットされている状態でsaveするとPUT /urlRoot/IDの
Ajaxが実行され、destroy()を実行するとDELETE /urlRoot/ID
のAjaxが実行されます。
集合操作メソッド(Collectionのみ)
Collectionのオブジェクトに対して、each,map,findなど
underscore.js由来の便利メソッドがCollectionに対して
実行できるようになっています。
|
上記のサンプルを任意の場所のファイルにコピーして
ブラウザでそのファイルにアクセスしてみてください。
(例) Macで/Users/takeshy/work/model.htmlという
名前でコピーした場合のURL。
file:///Users/takeshy/work/model.html
Modelのsampleについて
Modelのnameに対してdefaultsの属性をセットしています。
このためブラウザのJavaScriptのコンソールを開くと、
new ExampleModel({age: 0})で作成したオブジェクト
のattributesのnameにデフォルト値がセットされています。
validateメソッドにageが0以上かどうかをチェックして
いるため、set({age: -1})の実行をするとerrorのイベント
に登録したconsole.log(err)により、コンソールに
"age must be positive."が表示されます。
また、console.log(sample)でageが0のままであること
が確認できます。
ExampleCollectionにはurl属性に/examplesをセットし
model属性にExampleModelをセットしているので、
ExampleCollectionのオブジェクトに対しfetch()を実行
すると、Backbone.jsの機能により、Get /examplesが
実行され、戻り値のJSONの配列をExampleModelの
オブジェクトの集合に変換するはずです。
今回はWebサーバなしのローカルファイルで実行できる
よう、jQueryのAjaxをダミー関数で上書きして、パラメタ
をconsole.logに出力しているので、type: GET,
url: /examplesが実行され、ダミーで返したJSONの配列
に基づいてExampleModelのオブジェクトが2個格納されて
いることを確認できます。
collection.get(ID)でcollectionに格納されているIDが
1のModelのオブジェクトを取り出し、そのModelに対して
changeのイベントをObserveして変更があれば変更になった
値を画面に表示するような関数を渡しているので、その後の
model.setによる変更により、画面上に37が出力されている
ことも確認できます。
Viewについて
RouterでPATHごとに処理を登録しますが、その処理の
中でViewオブジェクトを生成し、Viewに処理を移譲する
ことが、Backbone.jsでは一般的です。
Viewオブジェクトに対しては、下記を行います。
events属性に、HTML内のイベントに対して処理を登録。
(Form内で属性の値を変更した場合に変更内容をModel
に反映するetc)
Modelの更新イベントに対して処理を登録(Modelが変更
されたらrenderメソッドを呼ぶことで再描画するetc)
renderメソッドを呼び出されると、templateを
展開し、elと呼ばれるプロパティに描画すべきHTMLの
要素をセットし、自身を返す。
|
上記のサンプルを任意の場所のファイルにコピーして
ブラウザでそのファイルにアクセスしてみてください。
(例) Macで/Users/takeshy/work/view.htmlという
名前でコピーした場合のURL。
file:///Users/takeshy/work/view.html
Viewのsampleについて
ViewはModelオブジェクトと連携するのが基本なので
counterという属性のみをもつModelを定義しています。
Viewの一番重要なelという属性は、backbone.jsが
デフォルトとして<div/>がセットしています。
もちろんそれ以外がよければ、el: '<ul id="hoge"></ul>'
のように値をセットします。
単にtag種別だけでよければ、elをセットせず、
tagName: "ul"とすれば、el: "<ul/>"とした場合と
同じことができます。
template属性には、templateメソッドを定義するのが
よくあるパターンです。
今回はunderscore.jsのtemplateメソッドを使用して
いますが、view内にHTML文字列を書いたり、元HTML
にtemplateを仕込むのは、保守を考えるとイケていない
ので、Assets Piplineを使うのがいいと思います。
events属性には、このview内のHTMLの要素に対する
イベントをキーにメソッド名の文字列を値にセット
しています。
Backbone.jsのオブジェクトは、初期時にinitialize
メソッドが呼び出されるので、initializeの中で、
Modelオブジェクトを生成し、Modelオブジェクトの
変更イベントに対して、renderメソッドを登録
しています。
これにより、modelの値をviewを意識することなく
変更することができ、変更によってrenderが呼ばれて
表示が更新されます。
今回はTimerを使ってmodelのcounter属性を1秒ごと
に100まで+1しています。
これにより1秒おきにviewが更新されているのが確認
できます。
また、今まではmodelの変更をmodel.onで登録していた
のですが、その場合、Viewが廃棄される前にmodel.off
を使ってイベントハンドラを解除しないとメモリリーク
してしまうという問題がありました。
最近ViewにListenToというメソッドが追加され、ListenTo
経由でイベントハンドラをセットするとView破棄時に
自動的にイベントハンドラが解除され、メモリリークが
防げるので、これからはListenToを使いましょう。
お決まりのrenderメソッドの中でtemplateメソッドに
template内で使う変数名と値が組になったHashを
渡します。Backbone.jsのModelオブジェクトに対して
toJSON()を呼びだすと、attributesの値のコピーが
渡されるのでそれを使うのがよくあるパターンです。
templateメソッドにより、elにhtmlの要素をセットし、
メソッドの最後でviewオブジェクト自身を返すのが
決まりとなっています。
無視のボタンを押すとignoreが呼ばれるようにevents
属性にセットしたのは、modelに対するイベントハンドラ
を削除することで、modelの値が変わっても、画面が
更新されないことを確認するためです。
consoleを見れば、modelの値は更新されつづけている
ことが確認できます。
最後のrouterですが、viewのrender()メソッドにより
viewのel属性に生成されたHTMLを実HTMLに反映する
のはRouterで行うことがidiomとなっています。
終りに
最後のサンプルでは、model,router,viewと組み合わせた
ので、このviewのサンプルが理解できたら、backbone.js
の基礎は理解できたことになります。
もしわかりにくかったり、間違っている箇所があれば、
教えてください。
Happy backbone!
| 固定リンク
| コメント (0)
| トラックバック (0)
Backbone.js Advent Calendarの20日目です。
app.configure('development', function(){ var Mincer = require('mincer'); var environment = new Mincer.Environment(); environment.appendPath(__dirname + '/app/assets/javascript'); app.use('/assets', Mincer.createServer(environment)); app.use(express.errorHandler()); });
| 固定リンク
| コメント (0)
| トラックバック (0)
Backbone.js Advent Calendarの16日目です。 新しい技術は興味はあるけど、主流にならない技術も多くて全部覚えるにはお腹いっぱいという皆さん。 私もこれはという技術を身につけて、一生食べて行けれたらと常々思っています。 そしてようやくこれはと思える技術に出会いました。 それが表題のNode.js+WebSocket+Backbone.jsです。 それを使った簡単なサンプルアプリ(backbone-railsのサンプルをrailsではなく Node.jsに置き換え、DBをRedis、データの同期にSocket.ioを使ったもの)のソースは ここにあります。アプリの解説はまた今度します。 今回はなぜこの組み合わせに賭ける気になったのか思ったを述べます。
利点
|
| 固定リンク
| コメント (0)
| トラックバック (0)
最近のコメント