Jetpack ComposeのAndroid Dev Challengeに応募した

Android Dev Challenge

偶然Androidで開発チャレンジやってるのを見かけた。商品も出るらしい。4週もやる。

https://android-developers.googleblog.com/2021/02/android-dev-challenge-lift-off-with.html

1周目はLEGOのトロフィーだって。内容を見ると俺にもできそうなレベルぽい!ということでやってみることにした。Android触るのすごい久しぶりな気がする。色々変わってたー。

準備

Githubのアカウントを作る

https://github.com/dalomo-net

つくった。dalomo取られてた、かなぴー。

Android StudioのCanary buildをインストール

Jetpack Composeってのがプレビュー版じゃないと使えないらしい。

https://developer.android.com/studio/preview?hl=ja

week1

https://android-developers.googleblog.com/2021/02/android-dev-challenge-lift-off-with.html

犬の養子縁組アプリを作るみたい。

GithubのTemplateをClone

https://github.com/android/android-dev-challenge-compose

なんやいろいろいい感じに用意されているらしい。

コード書く

とにかく最初の500人に入れればいいはずなので、それっぽいものができるようにだけ考えて調べていった。

どんなのにしよう

絵を描いた。こんな感じにできればいいな。

できた

めんどくなったので結果だけ。

https://github.com/dalomo-net/Animal-adoption-app

https://twitter.com/dalomo_dalomo/status/1365840250329722886

Android久しぶりのJetpackCompose初めてやったにしてはちゃんと形になった気がする!

Github Actionsでエラー

https://github.com/dalomo-net/Animal-adoption-app/actions

激闘の歴史。継続的インテグレーション?で使うやつでpushするたびテストが走るらしい。

BUILD FAILED in 1m 3s
Error: Process completed with exit code 1.

上記で止まった。中見ると

Task :app:spotlessKotlinCheck FAILED 
* What went wrong: 
Execution failed for task ':app:spotlessKotlinCheck'. 
The following files had format violations:

こんな、結局コードの整形がちゃんとできてなくて蹴られてた。

https://github.com/pinterest/ktlint#-with-intellij-idea

ここのoption3をやって、Terminalで

gradlew app:spotlessApply

とやったらでなくなった。ちゃんとリドミは読もう。

参考

https://developer.android.com/jetpack/compose

https://developer.android.com/jetpack/compose/tutorial

https://developer.android.com/jetpack/compose/setup

https://developer.android.com/jetpack/compose/navigation

https://takusan.negitoro.dev/posts/android_jc_recipe/

https://www.fontsquirrel.com/fonts/sniglet

https://www.isoroot.jp/blog/3034/

https://blog.mindorks.com/jetpack-compose-navigation

https://www.rockandnull.com/jetpack-compose-navigation/

https://qiita.com/Nabe1216/items/705460599db502882695

https://qiita.com/Nabe1216/items/f329e981f0da76c1d221

https://developer.android.com/studio/build/building-cmdline?hl=ja

カテゴリー: のーと | タグ: , , , , | コメントする

Socket.IOのデモのホワイトボードを設置してみた

ホワイトボード

Socket.ioのサイトを見ていたら、デモにホワイトボードもあった。面白そうなのでこちらも設置してみる。

https://socket.io/demos/whiteboard/

https://github.com/socketio/socket.io/tree/master/examples/whiteboard

設置したやつ

https://dalomo.net/whiteboard/

少しだけ変えてるので、流れとともにメモっとく。例によって、nginxをフロントに、リバーズプロキシでアクセスを振ってるのでなんかよく分からんくなっとる。

nginxの設定

/etc/nginx/conf.d/reverse_proxy.confに

upstream whiteboard {
  ip_hash;
  server 127.0.0.1:5000;
}
…
server {
…
 location /whiteboard/ {
    proxy_pass http://whiteboard;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
…
}

と追記。dalomo.net/whiteboard/へのアクセスをport5000に振る。

デモを設置

/home/dalomo/whiteboardというディレクトリを作りそこにファイルを置く。ディレクトリ内で

$ npm ci

ってやると、package.jsonを基にライブラリをダウンロードしてきてくれる。すごい便利ですね。URLがサブディレクトリになっている都合上、またうまく動いてないので色々書き換える。が、どこを変えたのかまとめるのがめんどいので

https://difff.jp/

こちらで差分を表示してスクショ撮った。

/home/dalomo/whiteboard/index.js

そもそものindex.htmlがサーブされないためapp.useの指定を変えてみた。絶対パスの指定で何故かされなかったのだけれど、サブディレクトリ名の指定だけでできた。なんでかは知らん。

ioをrequireする際にpathを指定した。指定しないと、dalomo.net/socket.ioを探しに行く。そこにはない。

/home/dalomo/whiteboard/public/index.html

色をいっぱい追加した、意味はない…。splitして名前を使ってるみたいだったのでwebcolor16色にしてみた。

クライアントサイドのsocket.ioをクラウドから取得するようにしてる。ここが自分の環境だとどうやればちゃんと配信されるか分かんないんだよね~。

リロード用のボタンをつけてる。画面が描画で一杯になっちゃった時用。canvasをリセットするやり方を検討してないので、使う人いないだろうし負荷とかは気にせず!

/home/dalomo/whiteboard/public/style.css

android使ってるんですが一番上で下にスワイプすると再読み込みになってしまう。Pull-to-Refreshというもので、今回のホワイトボードでは無用なのでなくしたい。なのでbody{overscroll-behavior-y: none;}を追加する。

再読み込み用のボタンがそのままだと色選択の後ろに隠れちゃったので、右下にくるようにしてみた。でもなんかうまく表示されなくて頑張っていい感じになるようにしたけど難しい。CSS難しい!

/home/dalomo/whiteboard/public/main.js

 var socket = io();
↓
 var socket = io.connect("/", {path: "/whiteboard/socket.io"});

としただけ。

できあがり


動いたー。PCでもスマホでも動く。以下余談。

javascriptやcssを編集したのにブラウザで開いても更新されてない

ていうことがあった。スマホの挙動の検証してたところで、なんでか変更しても表示だったり、コードだったりが変わらない。ブラウザのキャッシュを使っているのが原因らしい。ただスーパーリロードしても何故か更新されなかったりしたのでCacheBustingという方法を使って別物と認識させる感じ?で編集後のjsだったりcssだったりを読み込めるようになった。また、その過程で、スマホの表示をPCから接続して、PCのchromeでデベロッパーツールを使いながら検証するような使い方も知った。

スマホ実機でデベロッパーツールを使う

スマホで使うというよりは、スマホの表示をPCで確認するような感じ。

chrome://inspect/#devices

https://developers.google.com/web/tools/chrome-devtools/remote-debugging/?hl=ja

ちょうべんりだった。

参考

https://www.nishishi.com/javascript-tips/location-reload.html

https://qiita.com/TanakaMidnight/items/979cd7f044fb03a12a9d

https://developer.mozilla.org/ja/docs/Web/CSS/overscroll-behavior-y

https://qiita.com/aqril_1132/items/4789bc12a511136d8bfa

カテゴリー: できた | タグ: , , , | コメントする

超小型LinuxボードのQUANTUMを買った

Quantum Tiny Linux Development Kit

https://wiki.seeedstudio.com/Quantum-Mini-Linux-Development-Kit/

カテゴリー: のーと | タグ: | コメントする

500円のパルスオキシメーターをeBayで買った

パルスオキシメーター

コロナ禍で、医療資源が逼迫している中、軽~中等症の患者は入院できず自宅療養になったりするらしい。そんで、見た目には問題なさそうなのに、パルスオキシメーターって道具で計ってみると、血中酸素飽和度がガタ落ちで、ちゃんと酸素を取り込めず呼吸困難になって急死するみたいなニュースも見た。怖いなーと思ったので、パルスオキシメーターを買っておくことにした。前回の緊急事態宣言下では輸出ができなかったみたいで入手できなかったんだけど、今回はちゃんと届いた。

is 何 ?

https://www.konicaminolta.jp/healthcare/knowledge/index.html

https://www.jrs.or.jp/modules/guidelines/index.php?content_id=68

ここらへんを読もう。

どこで買ったのだ

https://www.ebay.com/sch/i.html?_from=R40&_trksid=p2380057.m570.l1313&_nkw=pulse+oximeter&_sacat=0

eBayで買った。中国から発送で届くまでに2週間程度だった。いつも1ヶ月ぐらいかかるのに、閑散期だったのかなぁ?実は2個買ったけど、1個は初期不良品だった。まぁ1個500円ぐらいで送料無料だったので、こんぐらいはご愛嬌。

開封

外箱

意外とちゃんと商品っぽい箱に入れられてきた。

中身

本体・取説・検査証・ストラップが入っていた。電池はついてない。

本体

単4電池2本で動く。海外ではAAA電池って呼称されるん初めて知った。

使ってみる

まぁ、クリップで指を挟んで、ボタン押すだけ。ボタンを複数回押すと画面表示が回転する。また、ボタンを長押しすると設定画面に行ける。取説読んでみたものの、字がちっせーわ英語だわ本体と違うイラストが書かれてるわであんまり役には立たない。

ちなみに正常値は96~99%あたりらしい。また、体が冷えていたり、喫煙してたりすると正しく数値が計れないそう。使われている技術はすでに枯れた技術らしいけど、500円の中国製だし、1っこは壊れてたしで、参考程度に思っていたほうがいいと思う。そもそも感染予防や、早期発見に効果があるようなものじゃなくて、専門家の指導の元、補助的に使うものなんだそうです。

こんな話が、

~東京都 自宅療養者へのパルスオキシメータ配布に関して~

2021年1月7日の小池東京都知事の会見で説明のありました、新型コロナ軽症・無症状の自宅療養者への配布用パルスオキシメータとして、当社の「PULSOX-Neo」も供給されました。

使用場所は一般家庭となりますが、使用方法に関しましては専門家の監修を受け、測定結果など に関しては都の自宅療養者サポートセンターにて医療従事者の判断・指導を仰いで行われます。

パルスオキシメータは、操作は簡単ですが適切に使用しなければ誤差が生じます。また、測定結果は、医師等 が患者様の総合的な状況を確認して判断する必要があります。

基礎疾患のない方には、パルスオキシメータは感染予防にも感染の早期発見にも結び付きません。一般家庭での医師等の指導のない購入はお控えいただけますよう、今一度お願いいたします。

新型コロナウイルス感染症の重症化リスクの高い基礎疾患のある方、ご高齢者、保健所の管理のもとで自宅療養される感染者の方といった、本当に必要な方への供給を優先させていただくためにご協力をお願いいたします。

(2021年1月21日 更新)

https://www.konicaminolta.jp/healthcare/knowledge/index.html

ありました。過信は禁物ですね~。

カテゴリー: のーと | タグ: | コメントする

Let’s Encryptで更新できなくなった

Let’s Encrypt

いつもはcronで自動更新してるんだけど、なんでかできなくなった。

Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.. Skipping.

最初のエラー。port80が見つかんないよ~って言われてる気がする。サーバの構成がnginxでリバースプロキシ使ってApacheに振ってるせいかなーって思った。

こんな感じ

なので、/etc/httpd/conf/httpd.conf に行って、virtual hostのセクションのポートを8080から80に戻した。

Some challenges have failed.. Skipping.

次のエラー。これの他に

Challenge failed for domain dalomo.net

Error while running apachectl graceful.

Job for httpd.service invalid.

とか

IMPORTANT NOTES: - The following errors were reported by the server: 
Domain: dalomo.net 
Type: unauthorized 
Detail: Invalid response from http://dalomo.net/.well-known/acme-challenge/W************************************ 
[140.227.173.32]: "<html>\r\n<head><title>502 Bad Gateway</title></head>\r\n
<body>\r\n
<center><h1>502 Bad Gateway</h1></center>\r\n
<hr><center>nginx</cente" 
To fix these errors, please make sure that your domain name was entered 
correctly and the DNS A/AAAA record(s) for that domain contain(s) 
the right IP address.

こんなのも。

https://qiita.com/ekzemplaro/items/523ba6026bce6d2a1846

とかなのかなーと思って、ディレクトリ作って

vi /etc/nginx/conf.d/reverse_proxy.confを

location ^~ /.well-known/acme-challenge/ {
    default_type "text/plain";
    root /var/www/html/le/;
}

てした。でもダメだった。

nginxを止めて更新

https://jijigrammer.info/programming/1115

こちらの記事を見つけたので

# systemctl stop nginx
# certbot renew

てしたらいけた。うーむ 。

今後更新の際はこれやんないといけなくなるんだろか。

カテゴリー: のーと | タグ: , , | コメントする

GoogleChromeの拡張を作りたい④ はてブ、はてなブックマークのサムネに目線をつけたい

はてなブックマーク

はてブをよく見る。よく見るんだけど、トップに顔画像がある率が高い。それを隠したい。ていう拡張を作りたい。

試行錯誤

はてブのエントリーイストのサムネ画像のところのタグは

<p class="entrylist-contents-thumb">
    <span style="background-image:url('https://example.com/image.jpg');" data-gtm-click-label="entry-info-thumbnail"></span>
</p>

みたいなんで、とりあえず

var cls = document.getElementsByClassName('entrylist-contents-thumb');
var imgurl = "";

for (const c in cls) {
  if (!cls.hasOwnProperty(c)) { continue; }
  const s = cls[c].querySelector('span');
  if (!s) { continue; }
  imgurl = s.style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2').split(',')[0];

  console.log(imgurl);

}

こんなコード書いたら、URLとれた。

こっから最高に行き詰まり、非同期処理やらimgの扱いやら、さっぱり分かんねぇ。わかんねぇなりに頑張った結果、拡張ができた。

 

https://dalomo.net/app/HatebuARuFanize.zip

 

例えば今こんな感じだとして

 

 

こうなる。

全部確実にというわけにはいかないけれど、そこそこ隠れてるのではないだろうか。

特に政治経済カテゴリはおもしろ政治家写真が沢山サムネに使われており、それがちょっと苦手なので目が隠れるだけでも見やすくて良い。

 

参考

http://alphasis.info/2013/10/javascript-dom-styleobject-backgroundimage/

https://developer.mozilla.org/ja/docs/Web/API/Element/querySelector

https://stackoverflow.com/questions/42368773/cannot-read-property-style-of-undefined-uncaught-type-error

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for…in

https://stackoverflow.com/questions/21655367/why-does-elem-style-backgroundimage-return-empty-rather-than-the-css-property/21655410

https://teratail.com/questions/189045

https://qiita.com/reeeiimi/items/759eebcb61b49556261b#comment-b0533f37f0029f9ad4cf

http://tech.hikware.com/article/20180204d.html

https://qiita.com/chihiro/items/9965cd7eca0380cf288c#%E5%8F%8D%E5%BE%A9%E5%87%A6%E7%90%86

https://qiita.com/sin_tanaka/items/b17a099d2a6a5e9a94b7

https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map

https://please-sleep.cou929.nu/onload-handler-setting-timing-and-async-request-of-image-element.html

カテゴリー: できた | タグ: , , | コメントする

ターミナルソフトをTeraTermからWindowsTerminalに変えたかった

WindowsTerminal

最初に使ったやつがTeraTermだったので惰性でこれを使ってたんだけど、Microsoft公式でTerminalが出てたみたいなので乗り換えようと思った。でも文字化けがどうにもなんなくて諦めた。

今まで

こんな感じ。

こっちにしたかった

罫線も●も文字化けしとる。色々やったけど直んなかった。

VSCodeのRemoteDevelopment

そうこうしてるとこんなものを見つけたので、こっちも使ってみる。

すごい。

WSL2も使ってみてる

今使ってるVPSがCentOSでWSL2のディストリがUbuntuなんだけど入れてどうなるのかな。でも手元にLinuxが動いてるってなんかすごいね。なにに使うかは決めてない。

 

 

 

 

 

カテゴリー: のーと | タグ: , , , , | コメントする

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.ってエラー

$ journalctl -f

で遊んでたらタイトルのエラーが出て消えなくなった。

/run/log/journalにあるログが行き場を失ってるかららしい。

$ mkdir /var/log/journal

でフォルダを作ってあげたらファイルがそっちに自動でいって

$ systemctl stop systemd-journald
$ systemctl start systemd-journald

ってしたらエラーでなくなった。

https://qiita.com/thaim/items/5d0cc595fce4ac0858e4

カテゴリー: のーと | タグ: | 1件のコメント

チャットを作りたい③ Node.js+Socket.IO

Node.js+Socket.IO

じゃーチャットを作ってこー。公式が提供してるのがあるので

https://socket.io/get-started/chat/

これ見ながらやってみる。

Socket.IOをインストール

/home/dalomo/node-chatってディレクトリ作って

$ npm init

ってすると色々聞かれるので

{
"name": "node-chat",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "dalomo",
"license": "ISC"
}

こんな感じにした(よく分かってない)。そしたら

$ npm install socket.io
$ npm install express

でインストール。expressの方も必要みたい。

expressを利用したHelloWorld

公式の流れがこうだからまずこれをやるでござる。フォルダ内に

$ vi app.js

var app = require('express')();
var http = require('http').createServer(app);

app.get('/', (req, res) => {
  res.send('<h1>Hello world</h1>');
});

http.listen(4000, () => {
  console.log('listening on *:4000');
});

3000番は使用中なので4000番に変えてみた。

自分の場合、前述の環境があるので/etc/nginx/conf.d/reverse_proxy.confに

 location /node-chat/ {
proxy_pass http://127.0.0.1:4000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

を追記。

これじゃダメだったみたい。

 

また、デーモン化のために/etc/systemd/system下にnode-chat.serviceを作り

[Unit]
Description=node-chat
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/node /home/dalomo/node-chat/app.js
Restart=always
WorkingDirectory=/home/dalomo/node-chat

[Install]
WantedBy=multi-user.target

と記載した。そんで

$ systemctl daemon-reload
$ systemctl start node-chat
$ systemctl status node-chat
● node-chat.service - node-chat
Loaded: loaded (/etc/systemd/system/node-chat.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-12-05 15:39:28 JST; 8s ago
Main PID: 13123 (node)
CGroup: /system.slice/node-chat.service
mq13123 /usr/bin/node /home/dalomo/node-chat/app.js

Dec 05 15:39:28 1scp2bi4 systemd[1]: Started node-chat.
Dec 05 15:39:28 1scp2bi4 node[13123]: listening on *:4000

うむ。じゃあhttp://dalomo.net/node-chat/にアクセスしてみますと

あれ…?いかん、ここで躓くのはいかんぞ。

https://stackoverflow.com/questions/60368255/cannot-get-chatroom

ここ見るとルートの設定が違うっぽい!app.jsを

app.get('/', (req, res) => {app.get('/node-chat/', (req, res) => {

に変えてrestartみると

できたー!あぶねー。

クライアント側HTMLを作成

app.jsの内容を

app.get('/node-chat/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

こう変更。__dirnameっていうのはapp.jsのパスをとってきてくれる。こうするとレスポンスに作成したindex.htmlを返すよーってなる。で、HTMLは丸パクる(タイトルだけ変えた^^)。

<!doctype html>
<html>
  <head>
    <title>node-chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: 0.5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

そうすっと

こうなった。CSS全然わからないので、なんでこうなるのか分かんない。

Socket.IOの処理を実装

接続確認

これもめちゃめちゃコピペである。app.jsに

var io = require('socket.io')(http);

io.on('connection', (socket) => {
  console.log('a user connected');
});

を追記。index.htmlの</body>の前に

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

を追記。そんでアクセスしてみると、statusに出てこない。なんでや。

ブラウザ側の開発者ツールを開きconsoleを見てみると

Uncaught SyntaxError: Unexpected token '<'      socket.io.js:1

との表記があり、socket.io.js:1 のURLを確認してみると

!https://dalomo.net/socket.io/socket.io.js

に行こうとしているようだった。そこにー私はーいませんー。ていうことはindex.htmlの

<script src="/socket.io/socket.io.js"></script>

ここのsrcを明示してあげればいいのかなーと思ってnode_modules/socket.io-client/dist/socket.io.jsに変更した。でも今度は

net::ERR_ABORTED 404

となる。うむむー?

https://blog.fkoji.com/2012/06300058.html

こちら試してみたりしたけどうまくいかず。試しに

https://cdnjs.com/libraries/socket.io

の、package.jsonに記載の同バージョンのsocket.io.jsを指定してみると、エラーは消えた。でもlogにa user connectedって出てこない。なんでだろ。ただなんか開発者ツールでNetwork欄を見てみると

なんかやってそうではある…。わっかんないなー。とりあえず進めてみよう。

進めてみたけど失敗する

もろコピペでapp.jsに

io.on('connection', (socket) => {
  socket.on('chat message', (msg) => {
    io.emit('chat message', msg);
  });
});

と変更。index.htmlを

<script>
  $(function () {
    var socket = io();
    $('form').submit(function(e){
      e.preventDefault(); // prevents page reloading
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

と変更してみて、試したけどメッセージは表示されなかった。なんだろなー。

上手くいった例

nginxとApacheを止めて、app.jsのポートを80番に変更。そんで

!http://サーバーのIPアドレス/node-chat

にアクセスすると上手くいった。複数タブを表示させて片方に入力し、もう片方で見るとちゃんとメッセージが表示されてる。つーことはnginxをかましてNode.jsアプリに振る所でなにかがおかしいんじゃないかなーと思う。

nginxを設定し直す

https://www.nginx.com/blog/nginx-nodejs-websockets-socketio/

https://qiita.com/StoneDot/items/e6c755fc3a6e94cc4d58

https://qiita.com/YuukiMiyoshi/items/d56d99be7fb8f69a751b

などを参考に

upstream websocket {
  ip_hash;
  server 127.0.0.1:4000;
}

server {

・・・
  location /node-chat/ {
    proxy_pass http://websocket;
    proxy_redirect                          off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host                   $host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-Proto      $scheme;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
  }

server {

・・・

   location /node-chat/ {
    proxy_pass http://websocket;
    proxy_redirect                          off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host                   $host;
    proxy_set_header X-Real-IP              $remote_addr;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-Server     $host;
    proxy_set_header X-Forwarded-Proto      $scheme;
    proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
  }
}

あたりを変えてみた。けどやっぱつながらない。

Socket.IOのディレクトリを指定する

https://stackoverflow.com/questions/58602908/how-do-i-use-socket-io-from-a-server-at-a-subfolder

https://github.com/socketio/socket.io/blob/master/examples/cluster-nginx/nginx/nginx.conf

なんかを参考にapp.jsの

var io = require('socket.io')(http, {path: "/node-chat/socket.io"});

て変えて、index.htmlも

var socket = io.connect("/", {path: "/node-chat/socket.io"});

と変えてみた。そしたらー

できましたー!

https://dalomo.net/node-chat/

もしかしたらディレクトリの指定だけでいけたんだったりして…。まぁ検証する気力が湧いてこないので、とりあえずここまで!よしっ!

カテゴリー: したい | タグ: , , , , | コメントする

チャットを作りたい② nginxとNode.jsの共存

Node.js

まずNode.jsを使えるようにしてこー。

Node.jsのインストール

https://github.com/nodesource/distributions/blob/master/README.md

$ curl -sL https://rpm.nodesource.com/setup_14.x | bash -

$ sudo yum install -y nodejs

された。

$ node -v
v14.15.1

現時点のLTS、LTSって何?Long Term Supportの略で長期サポート版ってことらしい。が、インストールされた。

$ npm -v
6.14.8

npmも同時にインストールされる。

Hello World

https://nodejs.org/ja/about/

にあるサンプルをそのままやってみる。いつも思うんですけど、こういうのってどのフォルダに置くのが一番いいんですかね。まぁなんでもいいかと

$ mkdir /home/dalomo/nodejs

した。そんでこん中に

$ vi helloworld.js

そんで

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

まるぱくる。とりあえず起動

$ node helloworld.js

そんで!http://dalomo.net:3000/にアクセスしても、反応なし。hostnameとportがちがうんかなーというのと、まずはnginxとhttpdを止める。

$ systemctl stop httpd 
$ systemctl stop nginx
  • hostname = ‘127.0.0.1’ port = 3000 アクセス先 = http://dalomo.net:3000
    • 動かない
  • hostname = ‘サーバーのIP’ port = 3000 アクセス先 = http://dalomo.net:3000
    • 動かない
  • hostname = ‘サーバーのIP’ port = 80 アクセス先 = http://サーバーのIP:80
    • 動く!
  • hostname = ‘dalomo.net’ port = 80 アクセス先 = http://dalomo.net:80
    • 動かない

結局動いたのこれだけだ。知識が足りなすぎて、どういう背景でこうなってるのか予想もつかん。多分だけどポートが開いてないとかなのかな…。試すのめんどくさいので取り合えず動いたやつに合わせてやってこう。

Node.js + forever

現状ctrl+Cしないと何もできなくなるし、その状態だとnginxと共存っつっても何もできんので、foreverでデーモン化してみる。って思ったんだけど、なんかCentOS7以降だとOSの機能としてデーモン化・永続化の機能があるみたい。そっちにしよう!

systemdでNode.jsアプリをデーモン化

デーモン化・永続化・バックグラウンドプロセス・常時起動とか色んな呼び方あるみたいだけど、何が正しいのか分からない!色んなサイトを参考にやってみよう。

https://qiita.com/you21979@github/items/588bddb59378ce7303a2

https://blog.kazu69.net/2016/06/06/start-node-server-with-systemd/

http://var.blog.jp/archives/83319334.html

https://nodesource.com/blog/running-your-node-js-app-with-systemd-part-1

https://qiita.com/ukiuni@github/items/400e4fdaae14b9bc0fcf

https://baykara.medium.com/how-to-daemonize-a-process-or-service-with-systemd-c34501e646c9

https://www.linode.com/docs/guides/start-service-at-boot/

/etc/systemd/system下にhelloworld.serviceという名前で

[Unit]
Description=helloworld
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/node /home/dalomo/nodejs/helloworld.js
Restart=always
WorkingDirectory=/home/dalomo/nodejs

[Install]
WantedBy=multi-user.target

こんな内容のファイルを作った。もうこれで使えるようになってるみたい。nginxとApacheを止めて

$ systemctl daemon-reload

で再読み込み。そんで

$ systemctl start helloworld

スタート!どきどき。確認してみる。

$ systemctl status helloworld
● helloworld.service - helloworld
Loaded: loaded (/etc/systemd/system/helloworld.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2020-12-03 22:32:45 JST; 1min 1s ago
Main PID: 13582 (node)
CGroup: /system.slice/helloworld.service
mq13582 /usr/bin/node /home/dalomo/nodejs/helloworld.js

Dec 03 22:32:45 1scp2bi4 systemd[1]: Started helloworld.
Dec 03 22:32:46 1scp2bi4 node[13582]: Server running at http://140.227.173....0/
Hint: Some lines were ellipsized, use -l to show in full.

おお…!できてるっぽい気がする。サーバーのIPアドレスにアクセスすると、上と同じように表示されてるー!すごい!めちゃめちゃ簡単なんだねぇ。そしたら

$ systemctl stop helloworld

で一回止めて、Node.jsアプリのポートを3000に変更して、nginxからリバースプロキシでアクセスできるようにしてきたい。

nginx + Node.js

http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node16.html

http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node36.html

https://heartbeats.jp/hbblog/2012/04/nginx05.html

サブディレクトリごとにどこの何を返すか、みたいなのを決めれるんと思う。現状は

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

server {
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/dalomo.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dalomo.net/privkey.pem;
    server_name localhost;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

こんな感じになってる。なんとなく、Locationのパスを追加して、proxy_passの所をポート3000に飛ばせばいいような気がする。でもそれ以下の記述は全部一緒で、それが複数回繰り返されるからなんか冗長な気がするんですけどどうなんでしょう。まぁとりあえず愚直に

location /nodejs/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

を、80と443をListenしてるserverの{…}内に追記してみる。そんでnginxとhelloworldのサービス起動すると、502 Bad Gateway…うーん?なんとなく、helloworld.jsのhostnameがよくなさそうな気がしたので、サーバーのIPアドレスから127.0.0.1に変えてみた。もっかい起動すると

できたー!!!すごい!動いてる!これでnginxとNode.jsとApacheが共存できた!いよいよチャットを作っていこう!

カテゴリー: したい | タグ: , , , | コメントする