Coreを動かした、試した記録を書き残します。この広告は、90日以上更新していないブログに表示しています。Core音楽サーバ"Mopidy"のフロントエンド「Mopidy.Finder」が出来るまで、第14回です。完成版Mopidy.Finderのライブデモはこちら。CoreアプリをLinuxで動かす際にハマるポイントを追っていきます。VMはガベージコレクションが付いてます。インスタンスの破棄を意識しないで書いていても、それなりに動いてくれます。LinuxのSocket周りには注意が必要です。Windows機の場合は、参照されなくなったSocketはガベコレが回収してくれます。ところがLinuxでは、意図して破棄しないと、Socketをすぐに使い切ってしまいます。昨今のC#では、TCP/UDPのSocketを生成する場面は少ないかもしれません。HttpClient。外部のWebサービスを使う際に便利な実装ですが、内部的にはSocketが生成されます。これをDisposeしないまま放置しておくと、LinuxではやがてSocketを使い切ってしまい、接続出来なくなってしまいます。こんな検証コードを書いてみました。}}MopidyのJSON-RPCに、単純なクエリを繰り返すコードです。引数を"--withusing"とすると、HttpClientをusingでラップして破棄するように。"--withouusing"とすると、破棄しないで放置するようにしています。このコードで、linux用バイナリを生成します。linux-x64これをUbuntu18.0.4LTSで実行してみます。ミニマルインストール後に、SSHと、実行ファイルコピー用のSambaを入れました。"--withoutusing"スイッチを付けて実行してみると...接続回数1004回目で、落ちてしまいます。CentOS7.6でも試してみます。1004回目で落ちますね。"--withusing"スイッチを付けて実行してみると。Ubuntu18では...問題なし、です。CentOS7.6でも、問題ありません。Windowsでも実行してみます。win-x64そして、Linuxでは落ちてしまう"--withoutusing"スイッチを付けて実行すると...こちらは、問題なく動き続けてしまいます。このように、Windowsでは動作に問題ないコードであっても、Linuxでは動かなくなることがあるんですね。C#で通信している箇所は要注意、と見ておいたほうが良いでしょう。一部NuGetパッケージのバージョン暗黙解釈に失敗する下記は、Asp.NetCore2.2-MVCプロジェクト生成直後のcsprojファイルです。</ItemGroup></Project>Microsoft.AspNetCore.Appに、バージョンが書かれていないんですね。NuGetパッケージマネージャで見てみると。ここではきちんと、v2.2.0と表記があります。バージョンを暗黙的に解釈しているようです。/mnt/sdb/private/Work/DoBes/tmp/MopidyFinder.csproj.こんなふうに、NuGetパッケージの整合性が取れずにエラーになることがあります。この場合は、csprojファイル上のMicrosoft.AspNetCore.Appパッケージに、バージョンを書き加えます。/>これでpublishが通るようになりました。今のところ、Microsoft.AspNetCore.App以外で、バージョン表記が無いという現象に行き当たったことはありません。時々はcsprojファイルの中身もチェックしといた方が良さそうです。パス文字列の大文字/小文字これは言語に関わらず、出てくる問題ですね。Webプログラミングをやっていれば必ず直面する問題のため、みなさま恐らく普段から気をつけていらっしゃると思います。私も気を付けてはいたのですが...。Mopidy.Finderでも、一度直面しました。こちらのコミットです。キャメルケースのフォルダ名を「Sidebars」→「SideBars」と変更した際の現象です。Windows上では「SideBars」に変わっていたのですが、WindowsのGitクライアントがその違いを認識できておらず。Gitリポジトリ上ではずっと、「Sidebars」として保持されていました。TypeScriptのコンパイルをLinux上で実行することは滅多に無かったため、リリース直前まで気が付きませんでした。いやはや、お恥ずかしい。RaspberryPi(Raspbian)は32bitOS最近のラズパイのCPUは既に64bit化されているのですが、OSはまだ32bit版なんですね。CentOSやUbuntuで動かしたバイナリをそのままコピペしてしまい、起動しない原因が分からずにしばらく悩みました。Raspbianで動かすためのバイナリを作るには、publishの引数を下記のようにします。linux-armでも、乗り越えてしまえばこまごまと問題に直面することも、あるとはいえ。Coreアプリは快調に動いてくれます。最近のpublishの処理は、大変優秀です!ミニマルインストールしたLinuxにバイナリをコピペするだけで、すんなりと動きます。C#erとしては、まったく良い時代になったもんだ、としみじみ思います。以上、Linuxのハマりポイントのおはなし、でした!これで、予定していた記事を全て書き終えました。C#ネタが出てきたら、適当に書き連ねようと思います。Android音楽サーバ"Mopidy"のフロントエンド「Mopidy.Finder」が出来るまで、第13回です。完成版Mopidy.Finderのライブデモはこちら。今回は、iOSとAndroidでのデバッグ方法を追っていきます。iOSは、エミュレータでお手軽にiOSでのデバッグは、macさえあれば、とてもお手軽に出来ます。Xcodeをインストールすると、各種iOSデバイスのエミュレータが付いてきます。Safariを起動し、開発者ツールを有効にします。Safariのメニューから、環境設定を選んで...「詳細」メニューの一番下、「メニューバーに"開発"メニューを表示」にチェック。すると、Safariのメニューに"開発"が追加されます。次に、Xcodeを開きます。エミュレータ上のiOSが起動し終わると、こんな感じです。このエミュレータの中のSafariを起動して、デバッグするURLを入力します。デバッグするアプリの画面が出てきたところで...mac上のSafariに戻り、"開発"メニューから「Simulator」を選ぶと。現在エミュレータで表示中のURLが出てきます。これを選択すれば、Safariの開発者ツールが出てきます。ツール上でDOMを選択すると、エミュレータ画面上でハイライトしてくれますね。お手軽ですね!「macを買わなきゃいけない」という、Windowsユーザーにとっては大変高いハードルを、乗り越えさえすれば...。Appleさんは、ご自身のご商売をきちんと分かっていらっしゃいますねぇ。Androidは、まず環境づくりから一方、AndroidはWindowsでもデバッグ可能です。Androidの場合、エミュレータよりも実機を使う方が手軽です。SDKをインストールしておく必要があるようです。Installerの機能選択時に「.NETによるモバイル開発」(=Xamarin)を選んでいる方は、既にインストールされています。Studioをインストールすると、GUIのSDK管理ツールも一緒に入ってきます。ダウンロードはこちらから。SDKの管理用GUIツールがあります。ここで、お手元のAndroid機のOSバージョンに合わせてSDKを選びます。選んでから、下の「Apply」ボタンを押すと、SDKがインストールされます。開発PC側の準備が出来たら、次はAndroidデバイスの準備です。最近のAndroid機では標準で非表示の、「開発者向けオプション」を表示させます。デバイスの設定を開き、"端末情報"を選びます。その中の、"ソフトウェア情報"を選択。ここに出てくる、"ビルド番号"。7回タップすると、開発者モードに切り替わります。設定メニューに戻ってみると、"開発者向けオプション"が表示されています。デバイスのメーカーやOSバージョンによって、若干表記が異なります。こちらは、AmazonのFireTablet-2015年版。設定メニューから、"端末オプション"に入ります。その中の、"シリアル番号"を連打すると、開発者モードになります。MediaPadM5では、"設定"→"システム"→"タブレット情報"の中の、"ビルド番号"でした。古いAndroid機では、最初から"開発者向けオプション"が出ているものも。一度"開発者向けオプション"を出してしまえば、あとはどの端末でも同じです。"開発者向けオプション"を開き、"USBデバッグ"のチェックをONにします。ONにするとき、こんな警告が出てきます。Android機で、いざデバッグAndroid機の準備が出来たところで、USBケーブルでPCにデバイスを繋げます。最近のデバイスでは、PCに接続した際にドライバがインストールされます。デバイスでChromeを起動し、デバッグするURLを開きます。次に、PCでChromeを起動します。URLに、下記を入力します。chrome://inspect/#devicesすると、PCのChromeはこんな画面になります。Android機の方では、こんな警告が出てきます。Android機の警告を許可すると、PC側のChromeで、デバイスがリストされます。※デバイスが出て来ない場合は、PCのChromeをリロードしてみてください。※どうやってもデバイスが出て来ない場合は、ADBドライバが入っていないことが考えられます。※その場合は、メーカーのドライバ配布ページからADBドライバを貰ってきてインストールしてください。この中の「inspect」リンクをクリックすると...はい!まいどお馴染みの、Chrome開発者ツールが出てきます!FireTabletでは、AmazonアプリストアにChromeが出てきません。仕方がないので、こちらから最新版のapkを貰ってきました。https://androidapksfree.com/chrome/com-android-chrome/old/本体に転送し、インストール。FireTabletをPCに接続し、Chromeを起動してみると。リモートデバッガが動きました。XperiaVLはAndroid4.1と古いため、GooglePlayストアにChromeが出てきません。ver61.0のapkを貰ってきます。こちらはADBドライバが無かったため、PC側に発売当時のツールをインストール。すると、Android4.1機でもデバッガを認識してくれました。Mopidy音楽サーバ"Mopidy"のフロントエンド「Mopidy.Finder」が出来るまで、第12回です。完成版Mopidy.Finderのライブデモはこちら。今回は、Bootstrapテーマ導入とCSS最適化の流れを追って行きます。デザインセンスはひとにお任せまず。私のスキルセットは若干フロントエンド寄りとはいえ、デザイナではありません。自分のデザインセンスには、一切の信用を置いていません。職業デザイナさんと仕事をするたびに、毎回感心させられます。あの人たち、どうやってかっこよさと機能を両立させてるんでしょうね?こういう自分に無いものは、他人様に求めるのが一番です。Bootstrapには、そんなデザイナさんたちの能力の粋が込められたテーマが、ときには無償で配布されていたりします。ありがたや、ありがたや!テーマをえらぶいろいろとテーマをぐぐった中で、こちらのページが目に付きました。hackerthemes.com殆どがMITライセンスで公開されていて、サンプルも見やすくていいですね!色々検討したのですが、ユーザー層を考えてみると。Mopidyを使うのは恐らく、若い男性でラズパイとかが好きな技術系のひとたち。Glowを導入することにしました。読み込んでみるこればっかりはnpmという訳にもいかないので、普通にダウンロードします。貰ってきたzipを解凍してcssファイルを参照させます。Glow適用直前コミットのUI。いわゆる「Bootstrap臭い」雰囲気です。Glow適用後コミットのものです。オレンジがいい感じなので、ボタンもタイトルも全部bg-warning化しました。印象変わるわ~...。うーん、やっぱ、デザイナってすげえな。描画が、重い見栄えが一気に音楽プレイヤーらしくなった、のは、大変いいのですが。若干モッサリしていた描画が、なんとなくさらに、重くなった気がします。読み込んだCSSのサイズを見てみると。258KB(9,232行)なるほど。こりゃレンダリングに負荷が掛かっててもおかしくないですね...。使っていない定義をピックアップこちらの記事にあるChromeのCoverageツールで、CSS上の未使用ルールがどのくらいあるのか、見てみました。tools」→「Coverage」でカバレッジツールが出てきます。ツールを出してからリロードし、UIを一通り触っていくと、使っているルールが緑色に、使っていないルールは赤にハイライトされます。どれどれ...?うへえ。ほとんど使われていません。AdminLTEもNeon-Glowテーマも、Bootstrap4-CSSの修正版なので。定義の重複が山のようにあります。淡々と、手作業で使ってないルールを一発で削除するような、便利なツールがあると良いのですが。今のところ、そういうツールは、私は知りません。Studioを行き来しながら、CSSのルールを一つずつ削除していきました。無心に小一時間ほど、淡々と作業した結果。37KB(1,662行)まで、縮小することが出来ました...!ロード早い!アニメーション軽い!動画を撮るツールが手元に無いため、違いをお見せすることが出来ないのですが。ブラウザロード時の初回描画も、アニメーションも、見るからに早くなりました!「動いてるから、いいじゃない」と、ついサボりたくなるCSSのメンテですが。体感には、明らかな差が出来るもんですね。Mopidy音楽サーバ"Mopidy"のフロントエンド「Mopidy.Finder」が出来るまで、第11回です。完成版Mopidy.Finderのライブデモはこちら。今回は、スワイプ操作を検知して画面を移動する実装を追います。使えることは使える、けども...前回、デバイスごとに見栄えを調整しました。スマートフォン表示時は、ヘッダバーにボタンを置いて、リストの切替が出来るようにしてあります。実際に操作してみると。UIの切替が、思ったより不便でした...。片手サイズのデバイスでヘッダをタッチすると、手でデバイス全体が隠れちゃうんです。好きじゃないなー、ということで。スワイプ操作によるUI切替を、導入することにしました。Hammer.JSはスグレモノHammer.jsは、ブラウザのタッチ操作をひと纏めに検出出来る、便利なライブラリです。以前の案件で使っていたこともあり、特に迷いも無くこれを導入しました。なんとなく、iOSのジェスチャー検知を思わせる作りです。Vue用にラップされたライブラリ、vue2-hammerやvue-touchもあるんですが。ラップしてもらう必要も感じませんで...。そのまんま使っています。インストールはいつものnpm経由で。hammerjs@typesに型定義がありますので、こちらも入れておきます。@types/hammerjsスワイプ検知イベントを書くHammer.jsでは、スワイプの検出を下のように書きます。水平方向のスワイプを検出する。左スワイプ検知時の処理});これで、タッチパネルはおろか、マウス操作でも反応してくれる、スグレモノです。Android-Chromeで反応しない...?さてさて、Viewの各パーツにHammer.jsを導入して、動作を確認してみたところ。Android機のChromeで、反応がありません。worksのワードがずらり。頻出する現象のようですね。ご本家GitHubのissueで、解決策が議論されていました。こちらのコメントで、コード例があります。イベントの入力方式を、対応状況に応じて切り替えてるのかな?これをこのまま書いてみると、@types上の変数定義が無いため、ビルドが通りません。この変数、ライブラリの実装にはあるんかいな?と調べてみると。このへんに記述がありました。MOBILE_REGEX.test(navigator.userAgent);こりゃ単に、@types上の定義が不足してるだけ、ですね。例によって型定義ファイルをtypesフォルダにコピーし、変数定義を追記します。...Android-Chromeで試すと、きちんと検知出来るようになっていました。うむよしよし!、と思ってたら...。この方法だと、PCのマウス操作に反応しなくなっちゃいまいした...。うーん、PCブラウザのマウス操作なんで、別にオミットしちゃってもいいんですが。気になるっちゃ、気になる。悩んでいたら、例のissueの少し下の方で、CSSによる対応サンプルがありました。pan-y;なるほど、スクロールの上下操作のみを許可するよ、と定義しちゃうわけですね。試してみると、Hammer.js側の方はサンプル通りの記述のまま、Android-Chromeで動くようになりました!教訓。英語でも、きちんと全部読め、ということですね...。アニメーションを導入する検知イベントを取れるようになれば、あとはUIの切替機能を加えるだけです。元々はタブパネルのように切り替えを実装していたもの。左右にスワイプしたのに、UIが横移動せずにガチャン、と切り替わると妙な感じです。ここは、横移動アニメーションを追加したいところ。そこで、頼りになるCSSアニメーションライブラリAnimate.cssにご活躍いただきます。Animate.cssもnpmパッケージ化されており、インストールは至極簡単です。animate.css使い方も、至極簡単。DOM要素のクラスに、animatedと、各アニメーションの種類を示すクラスを追加するだけです。'fadeOut');たったこれだけで、CSSによるアニメーションが動いてくれます。なんとまあ、簡単だこと!これをなるべく多用できるように、こんなユーティリティクラスを用意していました。--}アニメーションの終了をawaitで待てるようにしてあります。備えは万全!横移動アニメーションをいれる...と?プロジェクトも終盤になると、実装が整理されて抽象クラスが増えていきますね。Mopidy.Finderでは、カラム表示/フルスクリーン表示を切り替えるコンテンツ部分を、ContentDetailBaseというクラスに機能集約していました。そこに、左右にスライド移動するアニメーションメソッドを加えます。true;}さて、スワイプ操作時に移動してみましょう!あれえ?スライドアウトは動くんですが、移動先のUIがスライドインしてきません...。UIのレイアウト修正なぜこうなるか、というと。Mopidy.Finderの画面構造では、Bootstrapのrowに複数のcol-lgを入れることで、各種モニタサイズに対応させていました。スマートフォンサイズのディスプレイでは、下のような表示になっています。BYこの図の「コンテンツ1」がスワイプ操作を受けて左にスライドアウトしているとき、「コンテンツ2」は画面に見えない下の方で、スライドインアニメーションしていた、というわけなんですね...。absoluteになるように、CSSを調整します。!important;}そしてこのCSSクラスを、モニタサイズに合わせてセットするメソッドを作ります。classes.remove(ContentDetailBase.PositionStatic);}それらをモニタサイズ検知時に実行するように組み込み。いざ動作確認!ああ、よかった!カレントUIがスライドアウトするのと一緒に、別のUIがスライドインしてきてます。Mopidy音楽サーバ"Mopidy"のフロントエンド「Mopidy.Finder」が出来るまで、第10回です。完成版Mopidy.Finderのライブデモはこちら。今回はBootstrap4をベースにした、デバイスごとに表示を最適化するフローを追います。どんなふうにする?まず、PCブラウザサイズ。私が最も使うはずのサイズです。全機能を表示しておき、マウスで即座に各機能にアクセスしたいです。BY次に、タブレットサイズ。それなりのモニタサイズがありますが、常時メニューを表示しておくには小さすぎます。サイドバーは、ハンバーガーメニューの開閉式にしておきましょう。タブレットを横にしたときは、カラムが並ぶように。縦にしたときは、各カラムがフルスクリーン表示されるようにしたいです。BYそして、スマートフォンサイズ。モニタサイズは小さいため、縦横ともにフルスクリーンで表示しておきたいです。BYモニタサイズを判定するBootstrapではマークアップ時に`lg'や'md'のようなサイズ閾値を織り交ぜることで、自動的にカラム表示/フルスクリーン表示を切り替えて貰えますよね。「今現在、どのサイズ閾値を使っているのか」を取得する方法が、プレーンなBootstrapの機能の中では見つけることが出来ませんでした。Toolkitを導入して、モニタサイズがBootstrap上のどれに当たるのか、を取得するようにしました。ToolkitはまだBootstrap4には対応していません。ぐぐってみると、ご本家GitHubのissueで対応方法が議論されていました。github.comほうほう、useメソッドで閾値定義を渡せばよい、と。いうことで、このissueに記載があった定義を、そのままコピペで持ってきました。d-lg-none"></div>')});カラム/フルスクリーン切替の閾値をきめるBootstrap4のサイズは、公式ドキュメントでは下記のとおりです。当初はmdサイズを基準に切り替えていたのですが、これではタブレットを水平にしてもカラム表示になりませんでした。htmlのmetaタグでviewportを指定しているため、デバイス本来の解像度よりも小さめに判定されるためです。content="width=device-width,initial-scale=1">ということで、切替閾値をlgに変更しました。閾値に合わせた表示切替ロジックMopidy.Finderでは、ディスプレイサイズに合わせた表示を、NavigationControllerで制御するようにしました。コンストラクタから呼び出すInitialNavigationメソッドの中で、表示制御メソッドを実行しています。Settingsクエリが終わるまで待ってからAdjustする。Toolkitは、各閾値ごとに定義した要素の表示状態を見ることで現在のサイズを取得しているようです。初回描画が終わるまで、API呼び出しを挟むことで少し待たせています。表示制御メソッドの中身はこんなかんじ。コンテンツは、mdサイズを基点にカラム<-->フルスクリーンを切り替える。サイドバーは、lgサイズを基点に常時表示<-->操作終了で非表示化を切り替える。Toolkitのインスタンスをセットしています。