単なるメモ。
まぁ、同じことで悩む人もいるだろうと思うので、ネット上のゴミを増やしておく。
この手のことをするには複数の方法が存在し、検索結果的にメジャーなのは、socket.ioを使う方法っぽい。あるいは、wsを使うという方法もある(こっちは生Nodeでやったことがある)。
いずれの方法であっても、end pointについてはExpress的なrouterが使えないので、生NodeとExpressが合体しただけの、文字通り「木に竹を継いだ」ようなコードになってしまう。
それでは残念なので、いいものがないかと探したら、
というのを発見した。これはExpress的routerを拡張してくれる。詳細は、リンク先に。
router.ws('/kernels/:id/channels', (ws, req) => {
という感じのことが出来て強さを感じる。
ところで、Expressを使う時には、私はexpress-generatorを使うことにしている。別にこれを使う必要はあまりないと思うのだが(ライブラリ的に使えばよい)、こういったものを使うことで、
- どうでもいい部分は他人と同じに出来る
- 面倒なこと(起動とかディレクトリ構造とか)を考えなくて済む
- 「フレームワーク」を提供してくれる
というメリットがあるので、このようなものがある時は積極的に使うことにしている。Expressをライブラリ的に使うという手もあるし、それはSinatraっぽいとも言えるのだが、それよりはRails的な方が気楽である。
それは良いのだが、これで生成されたコードはexpress-wsとは相性が良くない。と言うか、そのままでは動いてくれない。express-wsのページにあるサンプルコードと、./bin/wwwやapp.jsを見比べても、そのまますんなり動きそうなのだけど、動いてくれないのだ。
あれこれやってわかったのは、./bin/wwwのポートを開くところが、
var server = http.createServer(app); server.listen(port);
となっているのだけど、これを
app.listen(port);
とすることで動いてくれた。
どっちがどう違うんだとゆー話があるのだが、httpについてあれこれやらない向きには、これで良いっぽい。
Express.js – app.listen vs server.listen
なお、express-wsを使う時には、
const express = require('express'); const app = express(); const expressWS = require('express-ws')(app);
のようにするのだが、これはapp.jsの中で一度だけやっておけば、他のrouterの中でexpressをrequireしたりする時にはこのような手順を踏む必要はないようである。普通にexpressをrequireするだけで、express-ws対応の動作になってくれる。