ラチェットウェブソケットでチャットルームをできるだけ早く設計しています。 ユーザーがいつそのページを離れるかを知っています。 例えば、ユーザ/クライアントがサーバとの接続を失った場合、クライアントとの接続が切断されていることをサーバに知らせることができません。では、チャットクライアントがインターネット接続を失って、もはやオンラインではないときをどのように追跡しますか?オンラインで誰かを確認するために半分の時間にラチェットウェブソケット - 切断されたクライアントを検出
サーバーをポーリングクライアントごとに15分:私は考えることができる
2つの解決策。応答しないクライアントは切断されます。これはPHPで起こっているすべてのことを中断することなく行うことができますか?もしそうなら、どのように?コードはどこに置くのですか?私は
addPeriodicTimer()
をLoopInterface
から見ましたが、それが仕事をするか、関数が自分のコードに収まるかわかりません。sleep()
も機能しません。この関数は(PHPで可能な場合)タイマーでありながら、私はまだPHP のメソッドは、ユーザーが実際にあらゆる状況で切断されたとき、これは検出できますonClose()
バックグラウンドで他のタスクが起こってしたいですか?もしそうなら、このイベントが発生すると、どのユーザーが切断されたかをどのように知ることができますか? ConnectionInterfaceとメッセージは渡されません。
申し訳ありませんが、私はまだラチェットライブラリに新しいが、まだこのタスクを達成する方法を試してみてください。
server.phpというために私のコード:ちょうどテストとOnCloseのを確認した(:chat.php
<?php
error_reporting(E_ALL^E_NOTICE);
session_id($_GET['sessid']);
if(!session_id)
session_start();
$userid = $_SESSION["userid"];
$username = $_SESSION["username"];
$isadmin = $_SESSION["isadmin"];
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface
{
protected $clients;
public function __construct()
{
$this->clients = new \SplObjectStorage;
}
public function onOpen(ConnectionInterface $conn)
{
$this->clients->attach($conn);
}
public function onClose(ConnectionInterface $conn)
{
$this->clients->detach($conn);
}
public function onMessage(ConnectionInterface $conn, $msg)
{
$msgjson = json_decode($msg);
$tag = $msgjson->tag;
if($tag == "[msgsend]")
{
foreach($this->clients as $client)
{
$client->send($msg);
}
}
else if($tag == "[bye]")
{
foreach($this->clients as $client)
{
$client->send($msg);
}
onClose($conn);
}
else if($tag == "[connected]")
{
//store client information
//send out messages
foreach($this->clients as $client)
{
$client->send($msg);
}
}
}
public function onError(ConnectionInterface $conn, Exception $e)
{
echo "Error: " . $e->getMessage();
$conn -> close();
}
}
?>
編集用app.js
// JavaScript Document
var chat = document.getElementById("chatwindow");
var msg = document.getElementById("messagebox");
var refInterval = 0;
var timeup = false;
var awaytimer;
var socket = new WebSocket("ws://52.39.48.172:8080");
var openn = false;
function addMessage(msg){
"use strict";
chat.innerHTML += "<p>" + msg + "</p>";
}
msg.addEventListener('keypress', function(evt){
"use strict";
if(evt.charCode != 13)
return;
evt.preventDefault();
if(msg.value == "" || !openn)
return;
socket.send(JSON.stringify({
msg: msg.value,
uname: nme,
uid: id,
tag: "[msgsend]"
}));
msg.value = "";
});
socket.onopen = function(evt) {
openn = true;
socket.send(JSON.stringify({
uname: nme,
uid: id,
tag: "[connected]"
}));
};
socket.onmessage = function(evt) {
var data = JSON.parse(evt.data);
if(data.tag == "[connected]")
{
addMessage(data.uname + " has connected...");
}
else if(data.tag == "[bye]")
{
addMessage(data.uname + " has left the room...");
if(data.uname == nme)
socket.close();
}
else if(data.tag == "[msgsend]")
{
addMessage(data.uname + ": " + data.msg);
}
};
window.onfocus = refPage;
function refPage()
{
if(timeup == true)
{
if(refInterval == 1)
{
refInterval = 0;
location.reload();
}
}
else
{
clearTimeout(awaytimer);
}
timeup = false;
}
window.onblur = timelyExit;
function timelyExit()
{
refInterval = 1;
// change this to trigger some kind of inactivity timer
awaytimer = setTimeout(function(){socket.send(JSON.stringify({
uname: nme,
uid: id,
tag: "[bye]"
})); timeup=true; }, 900000);
}
window.onoffline = window.onunload = window.onbeforeunload = confirmExit;
function confirmExit()
{
socket.send(JSON.stringify({
uname: nme,
uid: id,
tag: "[bye]"
}));
socket.close();
}
socket.onclose = function() {
openn = false;
//cant send server this message because already closed.
/*
socket.send(JSON.stringify({
uname: nme,
uid: id,
tag: "[bye]"
}));
*/
socket.close();
};
コードについて
<?php
require($_SERVER['DOCUMENT_ROOT'].'/var/www/html/vendor/autoload.php');
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
$server = IoServer::factory(new HttpServer(new WsServer(new Chat)), 8080);
$server->run();
?>
コード)メソッドは、インターネット接続が終了すると起動しません。
私はまだ最初の解決策について行くことができる方法はありますか?
いいですが、私は現在、APIを支払う立場にいたいとは思っていません。また、1日あたり100接続に制限したいと思っていません。 – emjay
aww cmon。ラチェットAPIを使用している人はいません。ラチェットAPIは、定期的にメッセージをすべてのクライアントに送信する方法を教えてくれますか? – emjay