質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

1回答

3307閲覧

【php】ログイン中の管理

cresta522

総合スコア13

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

2クリップ

投稿2017/07/07 23:10

ログインの細かな実装方法について相談させてください。

ログインセッションが切れた場合

通常、ログインの処理があればログアウトの処理もあります。ここの実装は問題ないのですが、ログインセッションが切れて実質ログアウトとなった場合の検知方法がわかりません。

具体的には、例えば、チャットルームを作成したとします。
Aさんがログインしてチャットルームを作成します。
Aさんがログアウトした場合、チャットルームを削除(または非表示等)にします。
ではここで、ログインセッションのタイムアウトが起きた場合、同じようにチャットルームを削除したいのです。

現在ログイン中のユーザの確認方法

「現在ログイン中のユーザ」の取得方法の検討がつかないため相談させてください。
上記のチャットルームの例を用いますが、AさんとBさんがチャットルームにいた場合、両名の生存確認を行いたいです。
セッションに残っているのか、いないのか。

基礎的な部分が欠乏しているかとは思いますが、皆様のお力をお借りしたく思います。
何卒よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まず,まともなチャットルームを作ろうとする時点でWebSocketというHTTPとは別のプロトコルの利用は事実上必須です。サーバ側から能動的にデータを送れる仕組みはこれしかありません。

WebSocketでは,「ブラウザは開きっぱなしだけど何もしていない」という状態の場合にもハートビートと呼ばれる生存確認が行われるので,意図しない切断を回避することができます。逆に,切断されてしまった場合には onError() でそのことを検知できるはずです(未確認なので確認お願いします…)。「タイムアウト」を自前でやりくりするよりも,この仕組みに任せたほうが簡単だと思います。


リアルタイム更新無し,PHPのみで実現する昔ながらのチャットルームで十分,という場合はここまでしなくても構いません。その場合,1人あたりの処理は

  • 新規発言等の際にはHTTPリクエストを送る
  • 定期的にJavaScriptでハートビート相当のHTTPリクエストを送る
  • 何かしらHTTPリクエストを受け取ったとき,その人のセッションの有効期限を延長する

という形をとるとよいでしょう。セッションを延長する方法に関しては下記を使ってください。

そして, 自分以外の誰かのセッション切れを検知する,ここが少々面倒ですね。少々無駄はありますが,(ハートビートを含む)毎回のHTTPリクエストに対するレスポンスに,誰が生きているか・誰が死んだかの情報を含める必要があります。そのためには,session_save_path() で取得できるディレクトリ内に存在するすべてのセッションファイルに対して,

  1. filemtime() でファイルの最終更新時刻を取得し,現在と比べて期限切れかどうかを判定
  2. 期限切れであれば,該当者をタイムアウトリストに含める。セッションファイル名のみで個人の特定ができない場合は, file_get_contents() でファイルを取得して session_decode() でデコードし,必要な情報を取り出す。

という処理を行うことになると思います。

…正直面倒ですね。素直にWebSocket使ったほうがラクな気がします。

投稿2017/07/08 01:08

編集2017/07/08 01:19
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2017/07/08 01:26

RatchetはSocket.IOに影響を受けて誕生したPHP版のWebSocketサーバですが,そもそもPHPとWebSocketの相性があまり良くないです。PHPのメジャーフレームワークLaravelは,PHPでWebSocketを扱うことを諦めて,Node.jsのSocket.IOとの連携を行うようになっているぐらいです。それゆえに,Node.jsやGolangなど,イベントや平行処理の扱いに長けた言語を使って書いてみるのも一つの手だと思います。
cresta522

2017/07/08 01:48

ありがとうございます。 チャットルーム、というのはあくまで一例だったのですが…、今回チャットを実装するのではなく、部屋を作った際に作成者がログアウトした場合の生存確認をどうしようかな…と思った次第です。 また、Websocketに関しては別途採用する予定だったのでアドバイスありがとうございます。 経験がないので試行錯誤しながら挑戦してみます。 Retchatは該当ユーザのセッションがあるか(ログアウトしたか)等の確認はできるのでしょうかね…?(取り敢えず試してはみます) セッションの延長に関しては参考にさせていただきます。
cresta522

2017/07/08 01:49

補足コメントもありがとうございます。 私がコメントを入力している間に補足してくださったようで気づけませんでした。。 私はLaravelで開発しているので、ご意見参考になりました。 LaravelでNode.js使用してみようかな。
mpyw

2017/07/09 03:33 編集

なるほど,質問内容から想定したより本格的な感じですね。でしたらスケーラビリティも考慮して,RedisのPUB/SUBも併用したほうがいいと思います。ロードバランサを入れる場合は必須です。 https://blog.dakatsuka.jp/2011/06/19/nodejs-redis-pubsub.html 要するに,「接続者のソケット一覧」として保持しているものに対して直接ブロードキャストしても同一インスタンスに接続してきた人にしか届かないので,全インスタンスと接続されているRedisを介してやりとり…ということになります。結構面倒ですが…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問