はじめに
現在、未経験からバックエンドエンジニアを目指し、コンピュータサイエンスの基礎をプロジェクトを通じて学習できるサイト Recursion を使用して、学習しています。
プロジェクトの一環で、UNIXドメインソケットを使って、CLIで完結するメッセージアプリを作成しました。
この記事では、このポートフォリオについて紹介・解説していきます。
GitHubはこちら
課題内容
Python のソケット通信と faker パッケージを使用して、クライアントサーバ間で情報をやりとりするシンプルなアプリケーションを作成します。
クライアントの作成
まず、ユーザーから入力を受け取り、その入力をサーバに送信するクライアントを作成します。ユーザーの入力は、例えばコマンドラインから受け取るものとします。このクライアントは、ユーザーからの入力を待ち、入力があったらそれをサーバに送信します。
サーバの作成
次に、クライアントからのメッセージを受け取り、それに対する応答を送り返すサーバを作成します。このサーバは、受け取ったメッセージに基づいて何らかの応答を生成し、それをクライアントに送り返します。
faker パッケージの利用
faker は Python のパッケージで、様々な種類の偽データを生成することができます。例えば、フェイクの名前、住所、メールアドレス、テキスト等を生成することが可能です。この課題では、サーバ側で faker を使って偽のランダムな文字列やメッセージを生成します。これは、サーバからの応答を模擬するためのもので、実際の応答がない場合やテストの際に役立ちます。Python の faker パッケージは pip を使用してインストールすることができます。
https://recursionist.io/dashboard/course/31/lesson/1099 より課題内容引用
目的
ローカル環境で動作するメッセージアプリを作成すること
必要なこと
この目的を実現するためには、以下の点の理解が必要です。
- ソケット通信
- UNIXドメインソケット
これらについては以下の記事で簡易クライアント・サーバプログラムの実装コード付きで解説ていますので、よろしければご参照ください。
実装方針
- 仮想環境を構築する
- ソケットドメインとして、UNIXドメインソケット を使用する
- ソケットタイプとして SOCK_DGRAM を使用する
実装方針の理由
- 他のプロジェクトと隔離するため
- メッセージの高速性を重視して、TCP型(SOCK_STREAM)ではなく、UDPライクなコネクションレス型の SOCK_DGRAM を選択
実装手順
1. 設定ファイル
2. サーバプログラム
2-1. サーバ用ソケットの作成
2-2. ソケットパスの初期化
2-3. ソケットのバインド
2-4. リクエストデータ受け取り
2-5. レスポンスデータ生成
2-6. レスポンスデータ送信
3. クライアントプログラム
3-1. クライアント用ソケット作成
3-2. ソケットパスの初期化
3-3. ソケットのバインド
3-4. リクエストデータ生成
3-5. リクエストデータ送信
3-6. レスポンスデータ受信
3-7. クライアントプログラム終了
fakerパッケージの使い方
指定された faker パッケージの使い方については、公式ページと合わせて以下の記事を参考にさせていただきました。
Fakerインスタンスを作成し、そのインスタンスメソッドにアクセスすることで各種ダミーデータを生成できることがわかりました。
from faker import Faker
fake = Faker()
# 名前
fake.name()
# 住所
fake.address()
# メール
fake.email()
...
from ... import ... の意味
import faker はモジュール全体を読み込み、使用時に faker.Faker()
のようにモジュール名を付けて呼び出します。
from faker import Faker は Faker クラスだけを直接スコープに取り込み、Faker()
のようにシンプルに呼び出せます。
動作確認
1. サーバ側(ターミナル)で仮想環境を有効化
先頭に (venv)
と表示されていることから仮想環境が構築されたことがわかります。
2. クライアント側(別ターミナル)も有効化されていることを確認
クライアント側も仮想環境が構築されました。
3. サーバ起動
4. クライアント起動
5. 「Hello!」と入力(文字列は任意です)・送信
6. サーバ確認
6-1. データ取得
クライアントから6バイトのデータが届いたことがわかります。
また、クライアントアドレスもソケットファイルパスになっています。
6-2. ダミーデータ作成・クライアントへレスポンス送信
受け取ったデータを使って、ダミーデータを作成。このデータは105バイトです。
そして、レスポンス送信後、改めてリクエストを待機中。
7. サーバからレスポンス取得・終了
サーバアドレスであるサーバソケットへのファイルパスからレスポンスを取得、データは105バイトで同じサイズであることが確認できます。
そして、ソケットは終了します。
補足
UNIXドメインソケットはファイルシステム上にソケットファイルを作成することが確認できます。
工夫した点
Faker インスタンス生成の位置
初期のコードでは、Faker インスタンスはレスポンスデータを生成するときに設定していました。
しかし、その場合、レスポンスを生成する都度、インスタンスのためのメモリを使うことになると見直しで気付いたため、ループ処理に入る前に生成することで、メモリの消費を抑えるようにしました。
ふりかえり
-
ブランチの作成に注意した
前回、観光スポットをDOM操作で表示するプログラムを作成したときに、ブランチを細かくしすぎてしまい、管理が大変だった点を改善しました。
今回は、機能ごとにブランチを作成し、管理しやすくしました。 -
可読性を心がけた
始め、client_socket
のような命名をせず、sock
とつけていました。
しかし、これだと初めて読む方にとってどちらのソケットか見分けがつかない可能性があると思い、何のソケットかをわかるように変数名に気を配りました。
次回に向けて
- 共通処理の関数化(ファイルパスの初期化など)
- 実装時間の計測
まとめ
今回課題では、UNIXドメインソケット(SOCK_DGRAM)によるデータの流れ、処理の実装方法などを学ぶことができました。
同一マシン上では同じファイルパスをどのように共有するのか、アドレスを確認することで bind() の仕組みを垣間見ることができました。
また、今回は同一マシン上に存在するプロセスでの動作のため、次回以降は、異なる端末間での通信をネットワークソケットを実装していきたいと思います。
最後までお読みいただき、ありがとうございました。
参考URL