y's note

ソフトやゲームの作成の開発に関することを書いていきます。

Zenfone AR(ZS571KL)でADBを使えるようにする

Zenfone ARで単にUSBデバッグをONにしてもADBコマンドが使えなかったので、使えるようにした手順をメモ。
※PCにADBコマンドが導入されていることが前提です。

設定アプリを起動し、一番下にある「端末情報」をタップ。
そして、「ソフトウェア情報」をタップします。
f:id:pwjtn527:20171208212719p:plain
「ビルド番号」を7回タップすると、「これでデベロッパーになりました!」というメッセージが出ます。
f:id:pwjtn527:20171208212806p:plain
設定アプリの最初の画面に戻ると、「開発者向けオプション」が出ています。
f:id:pwjtn527:20171208212623p:plain
「開発者向けオプション」をタップし、右上のスイッチをONにした後、USBデバッグをONにします。
f:id:pwjtn527:20171208213120p:plain
「USB設定の選択」をタップし、"PTP…"と書いてある部分を選択します。
f:id:pwjtn527:20171208213215p:plain
PCに接続すると、端末側でこのようなメッセージが出るので、「OK」をタップします。
(個人的には「このパソコンからのUSBデバッグを常に許可する」にチェックすることをオススメします)
f:id:pwjtn527:20171208213902p:plain

PC側でもADBドライバが自動的にインストールされるのでそのまま待ちます。
インストールが完了した後、コマンドプロンプトから"adb device"を打ち込むと認識されていることが分かります。
f:id:pwjtn527:20171208214942p:plain

なお、このままではエクスプローラ上でファイルのやり取りが出来ないので、元に戻したいときは上記の「USB設定の選択」から「MTP…」を選択してください。

OpenShiftでApplication is not availableと出てしまう

今まで使っていたOpenShift Online v2が9月30日に終了してしまう(以下v2)とのことなので、次世代のバージョンとなるOpenShift Online v3(以下v3)に移行したんですが、そこでつまずいてしまいました。

<追記 9/15 16:04>
記事名を修正しました。

待機するポート、IPの設定ミスが原因?

登録後、まずそのままデータを移してみたんですが、このエラーが発生したのかPodsの部分が黄色→赤色になって上手く行きませんでした。
当然ながら開くとエラーが出ます。
(画像はエラーがなかったときのものです)
f:id:pwjtn527:20170912155845p:plain

f:id:pwjtn527:20170912144513p:plain
今回悩まされた"Application is not available"

どうやら、サーバーサイドのスクリプトのこの部分がいけなかったようです。

//(略)
var port = process.env.OPENSHIFT_NODEJS_PORT || 3000;
var ip = process.env.OPENSHIFT_NODEJS_IP || 'localhost';
//(略)
app.listening(port,ip);

サンプルを参考にして、このように書き換え。

//(略)
var port = process.env.PORT || process.env.OPENSHIFT_NODEJS_PORT || 8080;
var ip = process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
//(略)
app.listening(port,ip);

ルーティング設定がダメ?

Podsの色はちゃんと青くなりましたが、開くと相変わらずこの文字列が…
f:id:pwjtn527:20170912144513p:plain
数日間悩みましたが、v2の時に書いたこの部分が怪しい…

//httpsへのリダイレクト
app.use(function(req,res,next) {
	if (req.headers.host == 'localhost:8080') {
		next();
	} else {
		var proto = req.headers['x-forwarded-proto'];
		if (proto !== undefined) {
			proto = proto.toLowerCase();
		}

		if (proto === 'https') {
			next();
		} else {
			res.redirect('https://' + req.headers.host + req.url);
		}
	}
});

コメントの通り、この部分は普通のhttpリクエストが来た際、安全なhttps接続にリダイレクトする処理です。
因みにローカルでの検証時は適用しないようにしてあります。(上の部分)

この記述を消すと…httpsでは例のエラーが出てしまうものの、httpではちゃんと自分が作ったWebアプリが動くではありませんか!
しかし、このhttpsに移行しようという流れに逆らえないぞ…
と思った数秒後、以前から怪しいなと思っていたルートの設定に行きました。(左のメニューでApplications→Routes)
f:id:pwjtn527:20170912150023p:plain
Nameの部分をクリックした後、右上のActionsから、Editをクリックします。
下の画像のように、Securityの部分の"Secure route"にチェックを入れます。
f:id:pwjtn527:20170912151502p:plain
TLS Terminationの部分はどれでも良いと思います。
Insecure Trafficの部分は、

None: httpリクエストが来た場合でも何もしない、(上のようなhttpsには繋がらないということはありません)
Allow: httpリクエストが来た場合、強制的にhttpsに切り替える。
Redirect: httpリクエストが来た場合、httpsにリダイレクトさせる。

AllowとRedirectは内容は同じですが、https通信に切り替えるタイミングが違います。
見栄え的には画面が真っ白にならない"Allow"が一番おすすめです。(Noneはセキュリティ的におすすめできません)
<追記(9/12 18:05)>
"Allow"だと、https通信にならないことがあるので、"Redirect"が一番おすすめです。

Saveをクリックして、設定を反映させます。
設定後、ルート設定のトップページに行くと、"http"の部分が"https"になっているのが分かると思います。
f:id:pwjtn527:20170912153216p:plain

この後アクセスすると、エラーが出なくなり、https通信も行えるようになりました。

XPCOMGlueLoad errorが出て、Firefoxが起動できない

昨日、"pacman -Syu"でパッケージのアップグレードを行った後からFirefoxが起動できなくなってしまいました。

ターミナルから起動しようとしても、

$ firefox
XPCOMGlueLoad error for file /usr/lib/firefox/libxul.so:
libicui18n.so.58: cannot open shared object file: No such file or directory
Couldn't load XPCOM.

と、エラーが出てしまいます。

そこで色々調べてみた結果、icuのアップデートが原因でした。

下記のコマンドを打ち込んで解決することができました。
[参考元]
Arch Linux ARM • View topic - Looks like [extra]/firefox is broken
Bugs in firefox 52=>53 on ArchLinuxARM 32 bits (ARMv7h) and how to still use it | Popolon gblog3

$ cd /tmp
$ mkdir unarc
$ cd unarc
$ wget https://popolon.org/depots/ArchLinuxARM/firefox/52/hunspell-1.5.4-1-armv7h.pkg.tar.xz
$ wget https://popolon.org/depots/ArchLinuxARM/firefox/52/icu-58.2-1-armv7h.pkg.tar.xz
$ tar xvf hunspell-1.5.4-1-armv7h.pkg.tar.xz
$ tar xvf icu-58.2-1-armv7h.pkg.tar.xz
$ cd usr/lib
$ sudo rsync -a libhunspell-1.5.so* libicu* /usr/lib/
$ sudo rsync -a icu/58.2 /usr/lib/icu/
$ sudo ldconfig

これでFirefoxが起動できるようになりました。
tar.xzを展開するときに、「未知の拡張ヘッダキーワード 'SCHILY.fflags' を無視」というメッセージが出ますが、そのまま次に進んでください。

余談ですが、ARMv7のFirefoxのバージョンが52.0.2で止まっていますね…
アップデートは来るんでしょうか。

Firefoxで「接続が安全ではありません」と表示されたときの対処法

FirefoxGoogleYouTubeにアクセスしようとした際、下の画像のように「接続が安全ではありません」とエラーが出てしまいました。
f:id:pwjtn527:20170325113124p:plain

Yahooでエラーについて調べましたが、日本語の情報が無かったので探すのに苦戦しました…
最終的に、Mozillaのフォーラムに解決法があったので、その方法を示します。

参考元:Solved: Re: I am an IT admin, after migrating our Exchange... - Mozilla Support Community

初めに、上のURL欄に"about:config"と入力し、Enterキーを押します。
すると、「動作保証対象外です!」と出てきますが、「危険性を承知の上で使用する」をクリックして次に進みます。
f:id:pwjtn527:20170325113728p:plain

上の検索欄に「http2」を入力します。
下の設定名のところに"network.http.spdy.enabled.http2"というのが出てくるので、ダブルクリックして"true"から"false"に値を変えます。
f:id:pwjtn527:20170325114025p:plain
f:id:pwjtn527:20170325114042p:plain

これで、Googleに接続することが出来るようになりました。
f:id:pwjtn527:20170325114225p:plain

Arch LinuxでiPhoneをマウントする

方法自体はここに書いてあるんですが、そのままでは無理だったのでメモ。

必要なパッケージをインストールする

iPhoneをマウントするためには、usbmuxdlibplistlibimobiledeviceifuseが必要になります。
なお、libimobiledeviceifuseusbmuxdの依存パッケージなので、コマンドに書かなくてもインストールされます。

# pacman -S usbmuxd libplist ifuse

fuseモジュールのロード

$ modprobe fuse

で、fuseモジュールがロードされます。
(自分の環境では、初めて繋いだときの一回だけで大丈夫でした)

マウントポイントの作成

# mkdir /mnt/iphone
# chmod 777 /mnt/iphone

iphoneの部分はどんな名前でもOKです。
chmodで、どんなユーザーでもアクセスできるようにパーミッションを変更しています。

マウント

$ ifuse /mnt/iphone

マウントできているか確認します。

$ cd /mnt/iphone
$ ls
AirFair  Downloads      PhotoData      Radio       iTunes_Control
Books    FactoryLogs    Photos         Recordings
DCIM     MediaAnalysis  PublicStaging  Safari

DCIMなど、複数のディレクトリが出てきたらマウントに成功しています。
エラーが出たり、lsコマンドでディレクトリが何も出てこなかったらマウントに失敗しています。
もう一度やり直してください。

アンマウント

iPhoneをUSBケーブルから外す時は、必ずアンマウントを行ってください。
なお、カレントディレクトリが/mnt/iphone(マウントポイント)の場合はアンマウントができないので、

$ cd ..

などで、他のディレクトリに移動してください。

# umount /mnt/iphone



なお、二回目以降からは前準備をする必要はありません。
マウントをするだけでOKです。

Socket.IOについてのメモ

公式のドキュメントが個人的に分かりにくいので自分がよく使っているものを備忘録を兼ねてまとめてみました。


バージョンは執筆時点の最新版であるVer1.3.5です。
それ以外のバージョンでは上手く動かないことがあるので注意してください。


Socket.IOのインストール方法

node.jsのスクリプトファイルがあるディレクトリ(フォルダー)に移動し、

$ npm install socket.io
サーバーへの接続方法

サーバー側

//前略
var port = 80;
var ip = 'localhost';
var io = require('socket.io')(app.listen(port,ip));

//クライアントとの接続に成功するとconnectionイベントが発火する
io.on('connection',function(socket) {
  console.log('connection');
  //クライアントとの接続が切れるとdisconnectedイベントが発火する
  socket.on('disconnected',function() {
   console.log('disconnected');
  }
});



クライアント側
chat.ejs

<!DOCTYPE html>
<head>
<script src="/socket.io/socket.io.js"></script>
<script src="./js/chat.js"></script>
</head>
<body>
</body>
</html>



chat.js

//http://localhost/にソケット接続を試みる
var socket = io.connect('http://localhost/');

//接続に成功すると'connect'イベントが発火する
socket.on('connect',function() {
 document.write('サーバーと接続しました。');
});



なお、socket.io.jsは自動で生成されるので、作成したり、ファイルを置いたりする必要はありません。
また、サーバー側の処理は'connection'イベントの中に書きます。

データの送信、受信

クライアント側

//データの送信
socket.emit('send','hogehoge');

1番目の引数にイベント名を入れます。
2番目以降の引数にデータを入れます。
なお、型はなんでも構いません。


サーバー側

//データの受信
//クライアント側のイベント名に応じたイベントが発火する
socket.on('send',function(msg) {
 //送信した本人に送り返す
 socket.emit('push',msg);
 //他の人に送信
 socket.broadcast.emit('push',msg);
});

他の人にも送信するのを忘れないように注意してください。


クライアント側

//データの受信
socket.on('push',function(msg) {
 document.write(msg);
});

受信する時の書き方はサーバー側と同じです。

ルーム

ルームの入退室

//'chat'というルームに入室
socket.join('chat');
//ルームから退室
socket.leave('chat');

なお、切断した時にルームから自動的に退室されるのでdisconnectedイベントの中に退室処理を書く必要はありません。


ルーム内でのデータの送受信
クライアント側

socket.emit('send','hogehoge');

クライアント側での送信方法は通常のやり方と全く一緒です。

サーバー側

socket.on('send',function(msg) {
 //自分含む'chat'ルームのメンバー全員に送信
 io.to('chat').emit('push',msg);
});

サーバー側の送信方法もあまり変わりません。
io.toの次にある括弧の中にデータを送信するルーム名、引数は通常の送信方法と同じです。
なお、「socket」ではなく「io」であることに注意してください。


クライアント側

socket.on('push',function(msg) {
 document.write(msg);
});

クライアントの受信方法も全く変わりません。

ソケットIDの取得
var sid = socket.id;

で取得できます。

IPアドレスの取得
var ip = socket.request.headers['x-forwarded-for'] || socket.request.connection.remoteAddress;

で取得できます。

例外処理

Ver 1.3.3から例外処理をしないと警告が出るようになりました。

socket.on('error',function(reason) {
 console.error(reason,'Error!');
});

このサンプルの場合、エラーが発生した時、「Error!」と言う文字とともに、エラーの詳細が表示されます。

タイムアウトの時間を短くする

標準のタイムアウトの時間は長すぎて、切断がすぐに検出できないという問題があります。
そのため、タイムアウトの時間を短いぐらいに設定します。


サーバー側

//前略
var io = require('socket.io')(app.listen(ip,port));
//タイムアウトを5秒に設定する
io.set('heartbeat timeout',5000);
io.set('heartbeat interval',5000);

io.on('connection',function(socket) {
 //略
});

このようにタイムアウトの設定を接続した時のイベントの前に書きます。


クライアント側

socket.on('connect',function() {
 //タイムアウトを5秒に設定する
 socket.headbeatTimeout = 5000;
});

サーバーに接続した時に設定するのがおすすめです。

再接続
socket.connect();

とすることで再接続できます。
なお、

//これは間違った書き方です!
io.connect();

は間違いなので注意しましょう。


以上です。
Socket.IOを使うと簡単にソケット通信ができるので楽しいですね。

node.jsに入門 その3 Expressをインストール

記事を公開するのが大分遅れてしまい、すみません。
今回はExpressをインストールする手順を紹介します。


Expressとは、Webアプリケーションフレームワークの一つです。
Webアプリケーションフレームワークとは、Webアプリケーションの基本的なシステムを提供するものです。


さて、早速インストールする手順を紹介します。(npmがインストールされていることが前提です、npmのインストール方法は各自ググってください)
コンソール(ここではGit Bash)を開き、(「exp」の部分は、好きな名前でOKです)

npm install -g express-generator
cd desktop
express -e exp
cd exp && npm install

これでExpressのインストールが完了しました。


次に、テンプレートエンジンである、EJSをインストールします。
EJSは、動的なページに使われます。
インストール方法は、

npm install ejs

これだけです。


次に「express」フォルダーにある、「views」フォルダーの中の「index.ejs」というファイルを次のように書き換えます。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title><%=title %></title>
</head>
<body>
<h1><%=title %></h1>
<%-content %>
</body>
</html>

因みに、EJSの文法はHTMLと同じですが、次の文法を使うと、node.js側で表示を変えることが出来ます。

<%= %>

エスケープ処理(HTMLタグがそのまま文字になる)されて表示されます。

<%- 値 %>

エスケープ処理されずにそのまま表示されます。

<% スプリクト %>

文法はJavaScriptと同じですが、で記述されるものとは違います。
scriptタグで書かれたものはクライアント側で実行されますが、
これで記述されたものは、サーバー側で実行されて、その結果がクライアントに送られてきます。
次に「app.js」というファイルを次のように書き換えます。

var express = require('express');
var ejs = require('ejs');

//appがexpressの本体になる
var app = express();

//描画エンジンをejsに指定する
app.engine('ejs',ejs.renderFile);

//GETリクエストを受けた時
app.get('/',function(req,res) {
	res.render('index.ejs',{
		title: 'Hello World!',
		content: 'Hello World!'
	});
});

app.listen(80,'localhost');
console.log('Server Running!');
});

保存したらコマンドプロンプトから、

cd desktop\exp
node app.js

実行すると、

Server Running!

と出力されるはずです。
エラーが出た場合はコードを再確認してみてください。
「Server Running!」と出力された場合は、ブラウザのアドレスバーに
localhost
と入力してください。
すると、次のページが表示されるはずです。
f:id:pwjtn527:20150120222936p:plain
表示されない場合は、「index.ejs」と「app.js」の中身をもう一度確認して下さい。

いかがでしたでしょうか?
node.jsに入門はこれで終わりです。
今後は個人的なメモ書きを書いていきます。


分かりにくい文章を最後まで見て頂きありがとうございます。