私が作りかけで放置しているSNS Project Xr概要
開発::webapp
序
Project Xr (Crossroad) は2018年にスタートした、私の独自SNSソフトウェアである。
現時点では、おおまかなデザインがあるのみで、実装は存在しない。 いや、これは正確ではない。書きかけの実装は存在するが、うまくいかなかったので破棄され、これに代わるアイディアが出ずにいる。
このソフトウェアはデータベース部分に難しい要件を持っており、私で解決できる見通しが立っておらず、リリースの見込みがない。
そこで、このソフトウェアのデザイン、設計について解説してみようと思う。 もしかしたら誰かが解決策を提示してくれるかもしれないし、誰かが実装してくれるかもしれない。
前提
このソフトウェアに関しては、その発想経緯を理解していると理解しやすい。
- Twitterの変化に不満を持っていた
- Twitterの代替となるサービス (Twitterのように広く使われるサービス) を志していた
- もともとチャット的な体験を愛好していた
- Mastodonで話題になった「分散型」に対して否定的な見解を持っていた
- このサービスの設計を考える上で、ネットニュースの(分散以外の)構造を前例としてイメージしていた
- 「特定のトピックに対して、それを愛好する人たちが盛り上がれる場」というコンセプトだった
- 割とDiscordっぽさがあるけど、Discordは意識していない
ソフトウェア概要
Xrは他とはかなり異なったデザインを持つSNSである。 簡単に言えば、チャット的な体験と掲示板的な体験がミックスされている。 似たものはなくはないが、少なくともTwitterやFacebookとはかなり異なる。
ただ、基本的に「Twitterに代わるSNSを作りたい」という動機であるから、最も意識されているのはTwitterだ。
近年はActivityPubを介した分散型SNSが流行しているが、そもそも形態が異なるため互換性がなく、ActivityPubには対応せず、分散型でもない。
Xrには「ユーザー」と「タイムライン」、そして「チャンネル」の概念が重要となる。
まず、ユーザーは各々のアカウントを指す。 このユーザーはXrにおいて、「自分」を指すものか、もしくは「発言者」を指すものである。 Xrはタイムラインをユーザー単位で構築しないため、他のSNSと比べユーザーという単位を意識することが少ない。
チャンネルはTwitterのおけるハッシュタグのようなものである。 基本的に投稿はチャンネル単位で行う。つまり、原則として投稿にはハッシュタグをつける。 外見上は実際にハッシュタグになっている。
チャンネルは購読することができる。 タイムラインは購読しているすべてのチャンネルの投稿が混ざったものになる。 別の見方をすれば、「ハッシュタグをフォローする」ことでタイムラインが構成される。
投稿時はチャンネルに対して行うことができる。 これは、ハッシュタグをつけることで、投稿チャンネルを選択することができ、複数つけることでクロスポストが可能。 仕様は決まっていないが、クロスポスト可能なチャンネルの数は制限される予定である。
もしハッシュタグをつけずに投稿した場合、#general
というチャンネルに対して投稿した扱いになる。
小規模なサーバーにおけるActivityPub型のSNSのPublic Timeline(Local
Timeline)のように機能する。
ただし、何らかのチャンネルに投稿されたものは#general
には含まれない。
チャンネルは誰でも新規に作ることができるかについては、検討事項となっている。
「チャンネルを購読」という概念について
私は結構斬新だと思っていたのだが、現在だとそこまででもない。
Pleroma/Akkomaはハッシュタグをフォローすることができる。
Misskeyにはチャンネルという機能があり、チャンネルの投稿をホームタイムラインに掲載することができる。
特にPleroma/Akkomaの場合は擬似的に同じような運用をすることは可能だ。
チャンネルビュー
特定のチャンネルにフォーカスしたビューを利用することができる。 Pleroma/Akkomaではハッシュタグをビューにすることができるが、これと似たようなものだ。
チャンネルビュー表示中に投稿した場合、ハッシュタグをつけない場合のデフォルトチャンネルが#general
ではなく、表示中のチャンネルになる。
つまり、「ハッシュタグをつけなければ#general
がつく」というのは、ホーム画面で適用されるルールだ。
ユーザーの扱い
ユーザータイムラインが存在し、ユーザーの情報を表示することで、ユーザープロフィールと共にそのユーザーの投稿を確認することができる。
ユーザーに対してミュート, ブロックの処理が可能。 ミュートした場合は投稿を表示せず、ブロックした場合はそれに加えて相手ユーザーにも投稿を表示せず、ユーザー情報も見せない。 これはサーバーの応答レベルで行われる予定。
ユーザーに対するメッセージ機能はないが、メンションすることは可能。 ユーザーが持っているのは
- ユーザーID
- 表示名
- bio
- ユーザー投稿
である。
つまずいたポイント
もともと、小規模なVPSからTwitter規模までスケールできるような設計を目指していた。 もちろん、そんなことは不可能だが、できる限りそれを目指そうとしていたのだ。
そこでデータの扱いについてだが、私はリングP2P構造を採用することにした。 ……のだが、やはりリングP2Pというのはとてもむずかしく、不安定な挙動のサーバーへの対応なども含めてしっかりと実装しようとすると難しすぎた。
構造上、カスタムタイムラインまみれになる。 ユーザーが表示するタイムラインを動的に構成しようとすると処理が重いが、プレビルドするpublish構造にするとユーザー数が増えると破綻しそうだ。
単に理屈のように動くだけなら実現している。 タイムライン単位でMarshal(Ruby)ファイルにしたものだが、もちろん実際にそのような構造で実際に使うことはできない。
開発ステータス
停止中 (再開見込みなし)
SNSを作るとしても、(よりTwitter的な)また違ったものにするかもしれない。