ひとりアドベントカレンダー2015 第25日目 〜 PHPer でもソケットプログラミングしてみたい その4(チャットサーバー作るぞ)

  • このエントリーをはてなブックマークに追加
  • Pocket

25日目!!!

いよいよぉ、最終日を迎えたぜぇ、おいぃ?今日オレたちはなりふり構わず行くからな!

とか書いて元ネタ分かる人いらっしゃいますかね・・・

最終日ですがあまり特別なこともなく粛々と書くのみです。きのうの select() で多重化したエコーサーバーをチャットサーバーに仕立てあげたいと思います。

チャットサーバー

複数クライアントが接続したサーバーが、あるクライアントから受信したメッセージを接続中の自分以外の全クライアントに配信する、というやつですね。これを行うには

  • 複数接続を一箇所にまとめておく
  • 各接続を監視してメッセージを送受信する

という機能が必要なので、シングルプロセスで select() を使って多重化することが必要なのかなと思います。fork() を使ってマルチプロセスでやる方法ってあるのかなぁ?

接続受け付けとメッセージの受信

接続受け付けとメッセージの受信部分は昨日やったとおりです。accept ループ内で socket_select() を使ってソケットの変化を監視します。なにか変化が起きた事がわかったらひとつひとつソケットを調べていき、メッセージを取り出します。読みやすさを考えて、もう一度 accept ループのコードを貼っておきます:

 メッセージの送信

ここまでできていれば、実はメッセージの送信は簡単です。受信したメッセージをそのままお繰り返していたところを、他の接続しているソケットに書き込むように変えるだけです(待ち受けソケットは除く)。以下のような関数を作って、上で socket_write()  を呼んでいた部分を差し替えればよいですね:

 まとめ

エコーサーバーを少し改造してチャットサーバーに仕立てあげました。PHP でもソケットを使ったサーバープログラミングが比較的簡単にできることが分かりました。さらなる改造として、Websocket プロトコルを実装してブラウザをチャットクライアントとして使う、などもやってみたいですが、また機会を改めてということで。

最後に今日のプログラムの全体を貼っておきます。

https://gist.github.com/maple-nishiyama/0cb6304070fa7d170daa

これにてひとりアドベントカレンダー2015は終了です。ここまでお読みくださりありがとうございました。

メリークリスマス&よいお年を!!

  • このエントリーをはてなブックマークに追加
  • Pocket

SNSでもご購読できます。

コメントを残す

*