y's note

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

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に入門はこれで終わりです。
今後は個人的なメモ書きを書いていきます。


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

Challenge Tablet Next root化

node.jsの記事、忙しくてなかなか書けません...
すみません。
いつかまとめて書きます。

さて、Challenge Tablet Nextをroot化する方法をハイクで聞かれたので書きます。


注意
root化は手順を間違えると、最悪文鎮になる可能性があります。
中途半端な状態で文鎮になると、修理、交換が受けられなくなることがあります。
ここに書かれていることは自己責任で実行してください。
(目的がない場合はやらない方がいいです)

ここでは、Windowsでのroot化の方法を紹介します。

1.Android SDKをインストールする
まずは、Android SDKをインストールします。

インストール方法は、
1.ここからAndroid SDKをダウンロードします。
2.「Download Eclipse ADT」と書かれているところをクリックします。
3.テキストエリアに書いてある内容をよく読み、
「I have read and agree with the above terms and conditions」にチェックを入れてください。
4.32-bitか64-bitを選択し、「Download Eclipse ADT with the Android SDK for Windows」をクリックしてください。
5.解凍したら、フォルダーの名前を「android-sdk」に名前を変えてください。
6.このフォルダーをCドライブの直下に置いてください。(コンピューターを開いて、Cドライブをクリックしたら出てくる所)

これで、Android SDKのインストールが終わりました。

2.JDKをインストールする

次に、JDK(Java SE Development Kit)をインストールします。
1.ここからJDKをダウンロードします。
2.一番上にあるところの「Accept License Agreement」をクリックしてください。
3.その後、32ビットなら「windows x86」、64ビットなら「windows x64」の横にあるリンクをクリックしてください。
4.ダウンロードしたら、ファイルを実行して、画面の通りにインストールを進めてください。
(ここが自力でできないと、root化はかなり厳しいです)

これで、JDKのインストールが終わりました。

3.必要なファイル群をインストールする

1.Cドライブの直下に置いた、「android-sdk」の中にある「SDK Manager.exe」を実行します。
(起動に少し時間が掛かります)
2.「Tools」の中にある、「Android SDK Tools」と「Android SDK Platform-tools」にチェックを入れます。
(画像はインストール後の画像です)
f:id:pwjtn527:20140929215920p:plain
3.「Install * package...」をクリックします。(*には数字が入ります)
4.インストールが終わったら、閉じるボタンをクリックして閉じてください。

4.パスを通す

1.デスクトップのコンピューターを右クリックして、「プロパティ」をクリックします。
そうすると、こんな画面が出ます。
f:id:pwjtn527:20140929220535p:plain
2.「詳細設定」をクリックします。
3.「環境変数」をクリックします。
f:id:pwjtn527:20140929220953p:plain
4.「システム環境変数」の「Path」を選択して、編集をクリックします。
f:id:pwjtn527:20140929221435p:plain
5.「C:\android-sdk\sdk\platform-tools;C:\android-sdk\sdk\tools;」を後ろに追加してください。
f:id:pwjtn527:20140929221614p:plain
6.「OK」をクリックします。
7.もう一回「OK」をクリックします。
8.また、「OK」をクリックします。
9.システムのプロパティを閉じます。

5.ドライバを書き換える

1.「android-sdk」の中にある「sdk」を開きます。
2.「sdk」の中にある「extras」を開きます。
3.「google」を開きます。
4.「usb_driver」を開きます。
5.「android_winusb.inf」というファイルをこれに置き換えてください。
6.タブレット側の設定で、USBデバッグを有効にします。

(開発者向けオプションがない場合は、「タブレット情報」の「ビルド番号」を7回タップすることで出てきます。)
7.タブレットをPCに繋げます。
8.デバイスマネージャーを開き、タブレットのデバイスを探します。
(他のデバイスか、ユニバーサル シリアルバス コントローラーあたりにあると思います)
9.見つけたら右クリックして、「プロパティ」をクリックします。
10.「詳細」タブを開きます。
11.スクロールメニューを開いて、「ハードウェアID」をクリックします。
12.すると、下の画面が出てきます。
f:id:pwjtn527:20141004153217p:plain
13.さっき置き換えたinfファイルを開きます。
14.「4E42」となっているところをさっきの画面のPID_の右に出ていた文字に書き換えます。
(二箇所とも書き換えてください)
15.上書き保存して閉じます。

6.ドライバーをインストールする
1.デバイスマネージャーを開きます。
2.タブレットの所を右クリックして、「ドライバー ソフトウェアの更新」をクリックします。
3.「コンピューターを参照してドライバーソフトウェアを検索します」をクリックします。
4.「コンピューター上のデバイスドライバーの一覧から検索します」をクリックします。
5.「ディスク使用をクリックします。
6.「参照」をクリックして、「android_winusb.inf」を選択します。
7.「Android Composite ADB Interface」を選択して、「次へ」をクリックします。
8.「ドライバーの更新警告」が出た場合は「はい」をクリックします。
9.完了したら、「閉じる」をクリックします。

7.「adb_usb.ini」を作成し、書き換える
1.コマンドプロンプトを開き、

android update adb

と入力します。
2.ユーザーフォルダー(自分のユーザー名)にある「.android」を開きます。
3.「adb_usb.ini」をワードパッドで開きます。
4.改行して、「0x18d1」と入力します。
f:id:pwjtn527:20141004224022p:plain
5.保存して閉じます。

8.タブレットが認識されているか確認する
1.一旦PCからタブレットを外して、もう一回PCに繋げます。
2.コマンドプロンプトを開き、

adb devices

と入力します。
うまく認識された場合はこんな感じになります。
f:id:pwjtn527:20141004224848p:plain
認識されなかった場合は、ドライバーの書き換えからやり直してください。

9.バックアップを取る
もしもに備えてバックアップを取ります。

1.コマンドプロンプト

adb backup -apk -shared -all

と入力します。
2.タブレット側で確認が出るので、パスワードを入力して「データをバックアップ」をタップします。
3.完了したら、次の手順に進みます。タブレットはPCに繋いだままにしておいてください。

10.root化する
さて、いよいよroot化の作業に入っていきます。

1.ここからrootkitをダウンロードします。
(ダウンロードリンクは赤字付近にあります)
2.ダウンロードが完了したら、フォルダーを開き、「RunMe.bat」を実行します。
3.「2」と入力します。
4.タブレットが再起動します。
5.root化が成功したら、アプリドロワーに「SuperSU」が追加されているはずです。
上手く行かなかった場合はもう一度やり直してください。
f:id:pwjtn527:20141004231043p:plain:w300:h400

これで、root化が完了しました。
root化しないと使えないアプリは、扱い方を間違えると文鎮になってしまうので十分気をつけてください。