2012/12/24

Bad arg length for Socket::pack_sockaddr_in - tcp socket communication by Perl

http://www.perlmonks.org/?node_id=642313

Perl を久々に触っていて、TCP 通信のコードを書こうと思った。ただ、自分がHACKしようと思っているソフトウェアはモダンなライブラリを使っておらず、低レベルなAPIを使っていたのでそれに合わせることにした。

そこで書いたのが以下のコードである。


このコードを実行すると「Bad arg length for Socket::pack_sockaddr_in, length is 14, should be 4 at invalid_tcp_code.pl line 15.」というエラーになる。なんでやねんと数十分悩み、よくよく pack_sockaddr_in関数のドキュメント を読んでみると、以下のようになっていた。第2引数には inet_aton 関数の戻り値を渡せとある。

Takes two arguments, a port number and an opaque string (as returned by inet_aton(), or a v-string).

要するにドキュメントはよく読みましょうね、、ってことで。。
動くコードの全体は以下の通りである。www.google.com に HTTP通信するコードだ。エラー処理は省略しているので注意。


[memo] Apache Core Dump on CentOS

CentOS で Apacheモジュール のデバッグをしていて、 Core Dump を吐かせようと思ったときに少し迷ったのでここにメモしておく。

Core Dump はプログラムがクラッシュしたときのメモリの状態を示すものであり、gdb でいろいろ解析ができるのでデバッグ時に重宝するのだが、サイズが結構巨大になる。それに Production な環境では不要なものなので、ディストリビューションはあの手この手で Core Dump を出力しないようにしているのが普通だ。

ググるといろんなやり方が書いてあるけれども、ディストリビューションによって手順が違うのに加えて、一般論も混じっていてかなりわかりづらい。CentOS(Red Hat系ディストリビューション) で一番簡単なのは以下だ。

これは、/etc/init.d/functions で ulimit を環境変数で毎回設定していることによる。

----

1. httpd.conf に CoreDumpDirectory を追加。

CoreDumpDirectory /tmp/

2. コアファイルの ulimit 設定を指定して Apache を再起動

DAEMON_COREFILE_LIMIT=unlimited; /etc/init.d/httpd restart

2012/12/15

Titanium 2.x traps


これは、Titanium Mobile Advent Calendar 2012 の参加エントリです。

いやーついに Titanium 3.0 がリリースされましたね! このエントリでは、僕が 2.x を触っていてハマった様々な罠について述べていきますが、3.0 以降ではこれらが全てfixしていることを祈っています。

今回のエントリでも、自分が iPhone, Android 両対応アプリを開発した経験に基づいていますので、皆様の環境では必ずしも再現しない場合もあると思いますが、その点は御容赦くださいませ m(__)m

1. String.format ってクロスプラットフォームで使うときはちょっと注意いりませんか?

今年の Advent Calendar でも触れられている String.format 関数。C言語でのsprintf関数の如く、文字列処理では重宝する関数なのでいやー便利ですよね皆さん! といいたいところなんですけど、、

 String.format("input value was %d  !!!", "hogehoge");

とかいう具合で誤った使い方をすると以下のような感じだったと記憶しています。

A) iPhone ではアプリが落ちる。
B) Android ではスルーされた。。なんで通るんだ。。

そもそも文字列連結処理が面倒だという理由で この関数を自分は使っていたので、"+" 演算子を使って回避した記憶があります。

2. "iphone" というフォルダ名を [Resources|ui] ディレクトリ以下に作るとアプリが落ちる件

http://developer.appcelerator.com/question/136031/couldnt-find-module-error-on-device

android とか、 iphone という名前は root フォルダで予約されているようで、ビルドが壊れてしまいました。"Could'nt find module error on device" というエラーメッセージが出たときは要注意です。

自分はこの罠によって iPhone アプリのエミュレーターで何の前触れもなくアプリが落ちる事象に遭遇しました。3時間悩み、フォルダ名を変えて動いたときはなんのこったいと頭をかきむしった記憶があります。

3. アプリを起動したとき "application restart is required" と表示される

https://jira.appcelerator.org/browse/TIMOB-4941

これは Android 限定の現象ですが、Google Play から落としてきた配布済みのアプリを Google Play から、またはアプリのショートカットから起動すると "application restart is required" と表示されてしまうという事象がありました。

Titanium 2.0 SDK 以降でこの現象は fix されたとありますが、2.1.x でも再現しました。

Google Play にアップロードした時以降「だけ」この現象が再現するのは始末が悪かったです。回避策は、 tiapp.xml に以下のような設定を入れることです。

   <property name="ti.android.bug2373.disableDetection" type="bool">true</property>

4. UTF-8 以外のエンコーディング問題

御存知の通り Titanium Mobile では UTF-8 が使われています。ですがいろいろな理由で UTF-8 以外の文字コードを使わざるを得ない場合もあったりなかったり。。

必要な場合は Escape Codec Library を使うのがよいとは思いますが、ライセンスが不明確なので組み込みは微妙です。

http://www.vector.co.jp/soft/other/java/se342855.html

5. JSS (JavaScript StyleSheet) の扱い

もはや 3.0 以降では別の形でウィジェットの装飾方法が確立されているため、この記述は役に立たないでしょうが、一応記しておきます。
GUIの装飾をJavaScriptで行うjss (Javascript Style Sheet) はドキュメントは残っていないし、仕様と動作が[不明確|不便]なため、自分は結局いろいろ試した末使いませんでした。JSS の記述は以下にあったりしますが、2.x では使わない方がよいでしょう。

http://gihyo.jp/dev/serial/01/titanium/0015

JSSの代替となる流儀は、require してプラットフォームごとに設定を切り替える方法です。僕は以下にあった方法を使いました。

http://higelog.brassworks.jp/?p=1144


おわりに

Titanium 3.0 では Alloy という MVC フレームワークで大幅にアプリの開発が変わるでしょうが、個々のコンポーネントやアプリを公開する時にまつわるバグや罠はいろいろなところに潜んでいることでしょう。けどそれを乗り越えて皆でノウハウをシェアしつつアプリ開発を楽しめればよいなーと思います。再度書きますが、3.0 以降では変な罠を踏みたくないものですね!

次は @astronaughts さんですね! 宜しくお願いします!

2012/12/06

[iPhone|Android] enabled Design Tips by Titanium

これは、Titanium Mobile Advent Calendar 2012 の参加エントリです。

Titanium Mobile 3.0 RC がつい最近リリースされ、新バージョンが目前ですね。
今年の前半は 4ヵ月くらい Titanium Mobile を触りました。何もないところから流儀を身につけてそれなりのコードを書き、2ヵ月半くらいで [iPhone|Android] アプリの両方をリリースしました。

今回はその経験を踏まえて、自分なりの iPhone, Android 両対応の Titanium Mobile における設計の流儀をまとめておこうと思います。「設計の流儀」としたのは、Titanium のバージョンがそれなりにあがっても自分的に通用しうるな、と思ったものだけをまとめたものだからです。 コードを書くときも様々なトラップを踏んだ覚えがありますが、それは別途まとめてみようと思います。

自分が作った経験に基づいていますので、以下のような内容になります。念頭に置いてお読みください。

  A)  Native 部分とスマホ向けのWebサイトを組み合わせたハイブリットアプリ向け 
  B)  ゲームアプリではないので、3D などのTipsは含まれていません。
  C) Titanium に限らず、スマホアプリを作るときはいつも当てはまるだろう、という事項も含まれています。


1. Android -> iPhone の順で設計する

iPhone より Android の方が出来ることが少なく、また Titaniumでの実装上の罠も 2.x 系では多い気がしました。よって、こちらをベースに先に作業した方が後々苦しまなくて済むと感じました。

UI は当然のことながら全然違うし、APIによって使える使えないが勿論存在するので、両対応を考えるなら汎用的に使えるコンポーネントで組み立てた方があとあと楽になれるかもしれません。そうした「使えそうなコンポーネント」を選ぶにあたって使えるのが御存知 「KitchenSink」です。

KitchenSink は iPhone, Android の両方で(できれば実機で)動かしてみることを強くお勧めします。それによって、それぞれのプラットフォームにおける見た目や動きが把握でき、しかもその中身がサンプルコードとして見ることができるからです。本やWebでコンポーネントの情報を把握することもよいのですが、実機での動きに勝るものはありません。

2. Titanium で出来ることと出来ないことをきちんと把握しておく

当たり前だろう、と石が飛んできそうですが、出来ることの限界が意外にわかりづらかったり、作っている途中で「これはできない」とわかったりするのが Titanium の世界だったりすると自分は思っています。。そうでもないですかね(´ー`; )

当たり前のことですが、Titanium Mobile を使えば iPhone や Android で使える機能が全部使えるとか考えてはいけません。対応していない機能は [Objective-C|Java] でモジュールを書く必要があるため、それなりの労力が必要になってきます。

Titanium のバグで動かない API をモジュールで代替せねばならない場合もあります。自分の場合は、 Android で 音声認識機能 を Intent 経由で呼びだそうと思ったらうまくいかなかったので、モジュールを書いた経験があります。

https://github.com/mumumu/Titanium-Android-VoiceRecognition

また、出来ることと出来ないことについての限界を知る目的でも、上で述べた KitchenSink は大変役に立ちます。骨の髄までしゃぶりつくしましょう。

3. iOS 向けの対応ハードはきちんと吟味する

これは Titanium に限ったことではありませんが、iOS 向けの場合は、必要な機能によっては使えるハードが限られてしまうので、iPhone や iPod、 iPad のどの世代から使えるのか、設計および実装時にきちんと吟味しておきましょう。

iTunesConnect Developer Guide にハードごとの機能互換性が表になっています。

http://developer.apple.com/library/ios/#documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/B_DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html#//apple_ref/doc/uid/TP40011225-CH17-SW1

最近はそれぞれに世代も進んできたので、差は小さくなっているのかもしれませんが。
自分の場合はカメラのオートフォーカスが弱いことが理由で一部機能が iPod Touch や iPad で使えなかったりした経験があります。

4. Webサイトが既にあり、組込む予定がある場合は、Webサイトとアプリでやることをはじめに切り分ける

アプリから組み込みブラウザでスマホサイトを呼び出せますが、組み込みブラウザのパフォーマンスはそんなに期待できません。WebView にモバイルサイトを表示させれば全て快適に動くなんていうハッピーな世界は期待してはいけません。特に3G では通信速度の問題もありますし、一気に張れるコネクションの数がそんなに多くないからです。LTE ではまた違うかもなのですが。

ハードの機能が必要な部分のみアプリで、という思考に行きがちですが、その点は以下のような態度がよいのではないかと思いました。

スピードが必要な部分ではアプリで。それで面倒な仕組みのみ、スマホサイトに任せる方式が現実的

5. アプリから組み込みブラウザ(WebView) を用いて、Webサイトを呼び出すときの注意

上で述べた通り、組み込みブラウザのパフォーマンスはそんなによくありませんし、自分がアプリを作ったときは 3G の通信ではかなり遅く感じました。なので、以下のような流儀が役に立ちました。

 ・できうる限り通信の本数は最小にする

  1本あたりの通信がとても重いです。そのため、以下の流儀が役に立ちます。

   a) 小さなモバイル向けの画像については、data スキームを大いに活用しましょう。
   b) CSS や JS も可能な限りHTML内部に収めましょう
   c) jQuery Mobile はダウンロード・実行ともにとても重かったのでキャッシュが効
     かない iOS 向けではminifyした上でアプリ内部に納め、ページロード後にeval
     させるという荒業を使った経験があります。

 ・テキストのコンテンツは gzip 圧縮する

   やむを得ず js, css などをダウンロードさせざるを得ない場合は、必ず圧縮して転
   送しましょう。jsonも当然対象です。

「HTML5 Web アプリケーションのつくりかた」というエントリもとても参考になります。
----

まとめ

なんだか基本的なことばっかりのような気もしますが、Titanium は Android が特に罠が多いように思います。それぞれのプラットフォームの特徴を見極めながら作るのは経験も必要だとは思いますけど、予備知識がそれなりにあれば大分違うよね、という思いでまとめてみました。何かのお役に立てれば幸いです。

では明日の担当 @h5y1m141 さんにバトンタッチします! よろしくお願いします。