Socket.ioとMessagePack


Socket.ioが落ちる事態に見舞われていましたが、追いかけていくと妙なところに原因が眠っていました。

Socket.ioと他システムとの連携

他のWebシステムの中にSocket.ioを取り入れる場合、(他のシステムがNode.js製でシームレスに組めるのでもなければ)連携の方策を考える必要があります。

そこでよく使われるのが、Redisのpub/subシステムを使ったSocket.io-redisです。「Redisに投げる」のは他言語でも容易にできるので、Nodeを離れての開発にも有効です。

突然のエラーに襲われて

そんな中で連携してシステムを作っていたところ、Socket.ioサーバが落ちる、ということになってしまいました。ログを見て原因を探っていくと、msgpackの処理で失敗している、ということでした。

msgpackとは

聞きなれないmsgpackですが、検索していくと公式サイトが見つかりました。JSONのように、数値・文字列・配列・連想配列をエンコードするシステムで、バイナリ表現を使うことでJSONより容量を削減している、ということでした。

問題の詳細

そして、詳細を追いかけてみると、socket.io-redisで使っているmsgpackのライブラリ自体にバグがあって、Int64/Uint64型のデータをデコードできない、という事態が発生していました。

この記事を書くために確認してみたところ、msgpackライブラリの差し替えがマージされているので、次のリリースには問題が解決しそうです。

残された課題

とはいえ、言語仕様上JavaScriptには64ビット整数がなく、doubleの精度は53ビットしかないので、それを超える数が来た場合、

  • 数値として扱って、桁落ちを起こす
  • 文字列として処理する

の2択が必要となるのでしょうが…あまりすっきりしない気がしました。