/** * Used to update the given resource in the database * * @param $id * @param $keyValueArray */ public function update($id, $keyValueArray) { $this->guardHidden = false; $resource = $this->get($id); $this->guardHidden = true; $this->renameSearchableKey($id, $resource->toArray(), $keyValueArray); $this->redis->hMset($this->getHash($id), $keyValueArray); $this->data = array_merge($this->data, $keyValueArray); }
/** * @param $siteUrl * @param $link * @param array $data */ public function addLink($siteUrl, $link, array $data) { if (!$this->siteUrl) { $this->siteUrl = $siteUrl; } $data['link'] = $link; $this->redis->sAdd($this->getSiteKey($siteUrl), $link); $this->redis->hMset($this->getPageKey($siteUrl, $link), $data); }
<?php /** * Fill db mockup values */ $redis = new Redis(); $redis->connect('127.0.0.1'); $redis->select(2); // HSET for ($i = 0; $i <= rand(1000, 10000); $i++) { $incr = $redis->incr('test:incr:hset'); $data = array(); for ($j = 0; $j <= rand(10, 500); $j++) { $data['field' . $j] = md5($j); } $redis->hMset('test:' . $incr . ':hset', $data); } // SET for ($i = 0; $i <= rand(1000, 10000); $i++) { $incr = $redis->incr('test:incr:set'); for ($j = 0; $j <= rand(10, 100); $j++) { $redis->sAdd('test:' . $incr . ':set', $j); } } // LIST for ($i = 0; $i <= rand(1000, 10000); $i++) { $incr = $redis->incr('test:incr:list'); for ($j = 0; $j <= rand(10, 100); $j++) { $redis->rPush('test:' . $incr . ':list', $j); } }
public function testHashes() { $this->redis->delete('h', 'key'); $this->assertTrue(0 === $this->redis->hLen('h')); $this->assertTrue(1 === $this->redis->hSet('h', 'a', 'a-value')); $this->assertTrue(1 === $this->redis->hLen('h')); $this->assertTrue(1 === $this->redis->hSet('h', 'b', 'b-value')); $this->assertTrue(2 === $this->redis->hLen('h')); $this->assertTrue('a-value' === $this->redis->hGet('h', 'a')); // simple get $this->assertTrue('b-value' === $this->redis->hGet('h', 'b')); // simple get $this->assertTrue(0 === $this->redis->hSet('h', 'a', 'another-value')); // replacement $this->assertTrue('another-value' === $this->redis->hGet('h', 'a')); // get the new value $this->assertTrue('b-value' === $this->redis->hGet('h', 'b')); // simple get $this->assertTrue(FALSE === $this->redis->hGet('h', 'c')); // unknown hash member $this->assertTrue(FALSE === $this->redis->hGet('key', 'c')); // unknownkey // hDel $this->assertTrue(1 === $this->redis->hDel('h', 'a')); // 1 on success $this->assertTrue(0 === $this->redis->hDel('h', 'a')); // 0 on failure $this->redis->delete('h'); $this->redis->hSet('h', 'x', 'a'); $this->redis->hSet('h', 'y', 'b'); $this->assertTrue(2 === $this->redis->hDel('h', 'x', 'y')); // variadic // hsetnx $this->redis->delete('h'); $this->assertTrue(TRUE === $this->redis->hSetNx('h', 'x', 'a')); $this->assertTrue(TRUE === $this->redis->hSetNx('h', 'y', 'b')); $this->assertTrue(FALSE === $this->redis->hSetNx('h', 'x', '?')); $this->assertTrue(FALSE === $this->redis->hSetNx('h', 'y', '?')); $this->assertTrue('a' === $this->redis->hGet('h', 'x')); $this->assertTrue('b' === $this->redis->hGet('h', 'y')); // keys $keys = $this->redis->hKeys('h'); $this->assertTrue($keys === array('x', 'y') || $keys === array('y', 'x')); // values $values = $this->redis->hVals('h'); $this->assertTrue($values === array('a', 'b') || $values === array('b', 'a')); // keys + values $all = $this->redis->hGetAll('h'); $this->assertTrue($all === array('x' => 'a', 'y' => 'b') || $all === array('y' => 'b', 'x' => 'a')); // hExists $this->assertTrue(TRUE === $this->redis->hExists('h', 'x')); $this->assertTrue(TRUE === $this->redis->hExists('h', 'y')); $this->assertTrue(FALSE === $this->redis->hExists('h', 'w')); $this->redis->delete('h'); $this->assertTrue(FALSE === $this->redis->hExists('h', 'x')); // hIncrBy $this->redis->delete('h'); $this->assertTrue(2 === $this->redis->hIncrBy('h', 'x', 2)); $this->assertTrue(3 === $this->redis->hIncrBy('h', 'x', 1)); $this->assertTrue(2 === $this->redis->hIncrBy('h', 'x', -1)); $this->assertTrue(FALSE === $this->redis->hIncrBy('h', 'x', "not-a-number")); $this->assertTrue("2" === $this->redis->hGet('h', 'x')); $this->redis->hSet('h', 'y', 'not-a-number'); $this->assertTrue(FALSE === $this->redis->hIncrBy('h', 'y', 1)); if (version_compare($this->version, "2.5.0", "ge")) { // hIncrByFloat $this->redis->delete('h'); $this->assertTrue(1.5 === $this->redis->hIncrByFloat('h', 'x', 1.5)); $this->assertTrue(3.0 === $this->redis->hincrByFloat('h', 'x', 1.5)); $this->assertTrue(1.5 === $this->redis->hincrByFloat('h', 'x', -1.5)); $this->redis->hset('h', 'y', 'not-a-number'); $this->assertTrue(FALSE === $this->redis->hIncrByFloat('h', 'y', 1.5)); } // hmset $this->redis->delete('h'); $this->assertTrue(TRUE === $this->redis->hMset('h', array('x' => 123, 'y' => 456, 'z' => 'abc'))); $this->assertTrue('123' === $this->redis->hGet('h', 'x')); $this->assertTrue('456' === $this->redis->hGet('h', 'y')); $this->assertTrue('abc' === $this->redis->hGet('h', 'z')); $this->assertTrue(FALSE === $this->redis->hGet('h', 't')); // hmget $this->assertTrue(array('x' => '123', 'y' => '456') === $this->redis->hMget('h', array('x', 'y'))); $this->assertTrue(array('z' => 'abc') === $this->redis->hMget('h', array('z'))); $this->assertTrue(array('x' => '123', 't' => FALSE, 'y' => '456') === $this->redis->hMget('h', array('x', 't', 'y'))); $this->assertFalse(array(123 => 'x') === $this->redis->hMget('h', array(123))); $this->assertTrue(array(123 => FALSE) === $this->redis->hMget('h', array(123))); // hmget/hmset with numeric fields $this->redis->del('h'); $this->assertTrue(TRUE === $this->redis->hMset('h', array(123 => 'x', 'y' => 456))); $this->assertTrue('x' === $this->redis->hGet('h', 123)); $this->assertTrue('x' === $this->redis->hGet('h', '123')); $this->assertTrue('456' === $this->redis->hGet('h', 'y')); $this->assertTrue(array(123 => 'x', 'y' => '456') === $this->redis->hMget('h', array('123', 'y'))); // check non-string types. $this->redis->delete('h1'); $this->assertTrue(TRUE === $this->redis->hMSet('h1', array('x' => 0, 'y' => array(), 'z' => new stdclass(), 't' => NULL))); $h1 = $this->redis->hGetAll('h1'); $this->assertTrue('0' === $h1['x']); $this->assertTrue('Array' === $h1['y']); $this->assertTrue('Object' === $h1['z']); $this->assertTrue('' === $h1['t']); }
$redis->connect('localhost', 6379); $redis->hMset($key, array('x' => $msg['x'], 'y' => $msg['y'])); echo "send stop"; } else { if ($msg['type'] == 'join') { echo 'join'; $client = new RouterClient('127.0.0.1', 9010); $sid = $_SERVER['SESSIONID']; $msg['id'] = $sid; $msg['x'] = mt_rand(0, 600 - 48); $msg['y'] = mt_rand(0, 520 - 64); //write to db $redis = new Redis(); $key = 'role:' . $sid; $redis->connect('localhost', 6379); $redis->hMset($key, array('id' => $msg['id'], 'x' => $msg['x'], 'y' => $msg['y'], 'name' => $msg['name'])); //join ok $client->sendMsg($sid, json_encode(array('type' => 'joinok', 'id' => $sid, 'name' => $msg['name']))); //sync $keys = $redis->keys('role:*'); $list = array(); foreach ($keys as $k) { $data = $redis->hgetAll($k); if ($k == $key) { continue; } $data['type'] = 'join'; $client->sendMsg($sid, json_encode($data)); echo "sync-->" . $data['id'] . "\n"; } //send all
$path = $arr[4]; $remoteIp = ip2long($arr[7]); if ($method == 'POST') { continue; } if ($path == '/webapi.php') { $redis->select($config['redis']['ipdb']); parse_str($arr[5], $query); $ipInfo['cid'] = $query['q']; $ipInfo['kid'] = $query['k']; $ipInfo['adid'] = $query['a']; $ipInfo['adType'] = $query['p'] == 1 ? 'ios' : 'pc'; $ipInfo['ip'] = $remoteIp; $ipInfo['time'] = $time; $key = 'ip#' . $remoteIp; $redis->hMset($key, $ipInfo); unset($ipInfo); $keys[] = $key; } if ($path == '/pcapi.php') { parse_str($arr[5], $query); $mac = $query['mac']; $key = 'pc#' . $mac; if ($mac == '' || $query['ptype'] != 1) { continue; } $redis->select($config['redis']['ipdb']); $ipKey = 'ip#' . $remoteIp; $ipInfo = $redis->hgetall($ipKey); if ($ipInfo['adType'] == 'pc' && $time - $ipInfo['time'] < 7200) { $pcInfo = $ipInfo;
} $ipStr = long2ip($remoteIp); //设备激活时间 $deviceKey = 'wap#' . $idfa . '_' . $bid; $deviceInfo = $redis->hgetall($deviceKey); $addTime = $deviceInfo['addTime']; $kid = $deviceInfo['kid'] ? $deviceInfo['kid'] : 0; $adid = $deviceInfo['adid'] ? $deviceInfo['adid'] : 0; if (!$addTime || $addTime > $maxTime) { echo $addTime, PHP_EOL; $addTime = $time; $info['id'] = $idfa; $info['addTime'] = $addTime; $info['bid'] = $bid; $info['firstLogin'] = $calDateUnix; $redis->hMset($deviceKey, $info); } if ($addTime >= $calDateUnix) { $newFlag = 1; } else { $newFlag = 0; } //统计日期与设备激活的相隔天数 $intervalDay = calDatesInterval($addTime, $calDateUnix); //激活日期 $deviceRegDate = date('Y-m-d', $addTime); switch ($ptype) { case 1: //激活 $data[$bid][$did][$qd][$broken][$ver][$kid][$adid]['reg_total'] += 1; $data[$bid][$did][$qd][$broken][$ver][$kid][$adid]['login_total'] += 1;
public function run() { $redis = new Redis(); $redis->pconnect('127.0.0.1'); echo "Run csvParser\n"; $dbconn = pg_connect(DB_CONN_STR) or die('Не могу подключиться к БД: ' . pg_last_error()); //Выберем все не занятые и включенные аккаунты с привязанным прокси $query = 'SELECT * FROM accounts WHERE status=0 AND busy<>1 AND proxy_ip<>0 '; $result = pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); $accounts = pg_fetch_all($result); if (count($accounts) < 1) { exit; } pg_free_result($result); //Берем рандомный из этого списка $acc_arr = array_rand($accounts); //Выбранный аккаунт становится занятым $query = 'UPDATE accounts SET busy=1 ' . "WHERE id={$accounts[$acc_arr]['id']}"; pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); //Выберем список работающих прокси $query = 'SELECT * FROM proxys WHERE id = ' . $accounts[$acc_arr]['proxy_ip']; $result = pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); $proxy_acc = pg_fetch_row($result); pg_free_result($result); //Берем случайный из списка $proxy = "{$proxy_acc[1]}:{$proxy_acc[2]}"; $proxyauth = "{$proxy_acc[3]}:{$proxy_acc[4]}"; //Получаем страну для которой запущен парсер $query = 'SELECT co."ID",co.full_name country, co.short_name cntr_code FROM countries co, params p ' . 'WHERE co."ID"=p.country_id'; $result = pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); $country = pg_fetch_object($result); pg_free_result($result); //Берем первый ключ в статусе "В ожидании" (keys_status = 1) //Если ключ в статусе "No Keywords" (keys_status = 2) - берем другой do { $key = $redis->sPop("keys_status:{$country->cntr_code}:1"); } while ($redis->sIsMember("keys_status:{$country->cntr_code}:2", $key)); //Увеличим количество использования аккаунта $query = 'UPDATE accounts SET cnt_work=cnt_work+1 ' . "WHERE id={$accounts[$acc_arr]['id']}"; pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); echo "--email={$accounts[$acc_arr]['gm_login']} --pass={$accounts[$acc_arr]['gm_pass']} \n\n --proxy={$proxy} --proxy-auth={$proxyauth} \n\n --key={$key}"; //Получаем время запуска и запускаем скрипт casperjs $start = microtime(true); $q = "/usr/local/bin/casperjs {$this->baseDir}googleKeyPlaner.js --proxy=" . $proxy . " --cookies-file={$this->baseDir}cookies/{$key}.txt " . "--proxy-auth=" . $proxyauth . " --ignore-ssl-errors=yes --web-security=no --key='{$key}' " . "--email={$accounts[$acc_arr]['gm_login']} --pass={$accounts[$acc_arr]['gm_pass']} " . "--verphone={$accounts[$acc_arr]['gm_tel']} --country='{$country->country}' > {$this->baseDir}tempFiles/{$key}-exitParser.txt"; exec($q, $ret_arr, $ret_val); //Если casperjs вернул код выхода 100 - нет keywords для данного ключа. Блокируем ключ if ($ret_val == 100) { //Блокируем ключ со статусом "No keywords" (keys_status = 2) $redis->sAdd("keys_status:{$country->cntr_code}:2", $key); //Уменьшаем количество использования аккаунта $query = 'UPDATE accounts SET cnt_work=cnt_work-1 ' . "WHERE id={$accounts[$acc_arr]['id']}"; pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); //Останавливаем процесс exit; } //Скачиваем файл по полученной ссылке для ключа if (is_file($this->baseDir . 'tempFiles/dnld_' . $key . '.txt')) { $dnldUrl = file($this->baseDir . 'tempFiles/dnld_' . $key . '.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); echo '=================Start DownLoad================='; $q = "/usr/local/bin/casperjs {$this->baseDir}downloader.js --proxy=" . $proxy . " --cookies-file={$this->baseDir}cookies/{$key}.txt " . "--proxy-auth=" . $proxyauth . " --ignore-ssl-errors=yes --web-security=no --key='{$key}' " . "--dnldUrl='{$dnldUrl[0]}' > {$this->baseDir}tempFiles/{$key}-exitDownloader.txt"; exec($q, $ret_arr, $ret_val); } $work_time = microtime(true) - $start; //Проверяем наличие скачанного файла для продолжения if (is_file($this->baseDir . 'tempGrab/stats_' . $key . '.csv')) { $csvObj = new File_CSV_DataSource(); $csvObj->settings(array('delimiter' => "\t", 'eol' => '')); $csvObj->load($this->baseDir . 'tempGrab/stats_' . $key . '.csv'); $csvObj->symmetrize(0); if (!$csvObj->isSymmetric()) { echo 'Ошибка! Количество заголовков и столбцов в строках не совпадает в файле tempGrab/stats_' . $key . '.csv'; } //Если файл не пустой if ($csvObj->countRows() > 0) { $arrForSHA1 = array(0, 0); $mainKeyRow = $csvObj->getRow(0); //Добавляем информацию для заданного ключа $mainKey['keyword'] = $mainKeyRow[1] != "" ? $mainKeyRow[1] : ""; $mainKey['AMS'] = $mainKeyRow[3] != "" ? $mainKeyRow[3] : 0; $mainKey['suggested_bid'] = $mainKeyRow[5] != "" ? $mainKeyRow[5] : 0; $redis->delete("key:{$country->cntr_code}:{$key}"); $redis->hMset("key:{$country->cntr_code}:{$key}", $mainKey); $arrForSHA1[0] = sha1(serialize($mainKey)); //Добавляем keywords для заданного ключа $new_words = array(); $keywordRow = array(); for ($i = 1; $i < $csvObj->countRows(); $i++) { $childKeyRow = $csvObj->getRow($i); $keywordRow[$i]['keyword'] = $childKeyRow[1] != "" ? $childKeyRow[1] : ""; $keywordRow[$i]['AMS'] = $childKeyRow[3] != "" ? $childKeyRow[3] : 0; $keywordRow[$i]['suggested_bid'] = $childKeyRow[5] != "" ? $childKeyRow[5] : 0; //Получаем новые слова для словоря $new_words = array_merge($new_words, explode(" ", $keywordRow[$i]['keyword'])); } //Если есть новые слова для словаря if (count($new_words)) { //Удаляем дубликаты $new_words = array_unique($new_words); //Удаляем стоп-слова $query = 'SELECT "stop_words" FROM countries ' . 'WHERE "ID"=' . $country->ID; $result = pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); $st_words_str = pg_fetch_object($result)->stop_words; pg_free_result($result); if ($st_words_str) { $st_words_arr = explode("\n", $st_words_str); $new_words = array_diff($new_words, $st_words_arr); } //Если остались слова - продолжаем if (count($new_words) > 0) { //Удаляем однобуквенные слова и слова с запрещенными знаками foreach ($new_words as $w_key => $value) { if (!preg_match('|^[a-z]{2}[a-z0-9_-]*$|i', $value)) { unset($new_words[$w_key]); continue; } } //Добавляем новые слова в словарь со статусом "В ожидании" (keys_status = 1) if (count($new_words) > 0) { $ins_arr = array(); foreach ($new_words as $word) { if ($redis->exists("key:{$country->cntr_code}:{$word}") || $redis->sIsMember("keys_status:{$country->cntr_code}:2", $word)) { continue; } $redis->sAdd("keys_status:{$country->cntr_code}:1", strtolower(trim($word))); } } } } //!!!! ПРОВЕРИТЬ КЛЮЧ В ХЭШ-ТАБЛИЦЕ !!!!!!!!!!!!!!!!!!!! //Добавляем keywords для ключа if (count($keywordRow) > 0) { $arrForSHA1[1] = sha1(serialize($keywordRow)); $i = 1; $redis->delete($redis->keys("keywords:{$country->cntr_code}:{$key}:*")); foreach ($keywordRow as $row) { $redis->hMset("keywords:{$country->cntr_code}:{$key}:{$i}", $row); $i++; } } $redis->delete("keys_hash:{$country->cntr_code}:{$key}"); $redis->rPush("keys_hash:{$country->cntr_code}:{$key}", $arrForSHA1[0], $arrForSHA1[1]); } else { //Файл был пустой - разблокируем ключ (keys_status = 1) $redis->sAdd("keys_status:{$country->cntr_code}:1", $key); //Увеличиваем количество ошибок для аккаунта $query = 'UPDATE accounts SET cnt_fail=cnt_fail+1 ' . "WHERE id={$accounts[$acc_arr]['id']}"; pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); } //Удаляем скачанный файл if (is_file($this->baseDir . 'tempGrab/stats_' . $key . '.csv')) { unlink($this->baseDir . 'tempGrab/stats_' . $key . '.csv'); } } else { //Файл не скачался - разблокируем ключ(keys_status = 1) $redis->sAdd("keys_status:{$country->cntr_code}:1", $key); //Увеличиваем количество ошибок для аккаунта $query = 'UPDATE accounts SET cnt_fail=cnt_fail+1 ' . "WHERE id={$accounts[$acc_arr]['id']}"; pg_query($query) or die('Ошибка запроса: ' . pg_last_error()); } sleep(1); pg_close($dbconn); echo "STOP Run csvParser\n"; }
/** * 将key->value写入hash表中 * @param $hash string 哈希表名 * @param $data array 要写入的数据 array('key'=>'value') * @param $time longint 过期时间(S) 默认值为0-不设置过期时间 */ public static function hashSet($hash, $data, $time = 0) { $redis = new \Redis(); $redis->connect(self::_HOST, self::_PORT); $return = null; if (is_array($data) && !empty($data)) { $return = $redis->hMset($hash, $data); if ($time && is_numeric($time)) { $redis->expire($hash, $time); } } $redis->close(); $redis = null; return $return; }
public function feed() { /* * * * */ $food = ""; $errorMessage = ""; if (!empty(file_get_contents("php://input"))) { $raw = file_get_contents("php://input"); //some test data for filling if ($food = json_decode($raw, true)) { } else { header("HTTP/1.0 400 Error"); echo "invalid JSON format"; } if ($food != "") { // Validation block, to check if payLoad have endpoint, correct url provided and allowed method if (isset($food['endpoint'])) { if (isset($food['data'])) { if (!in_array(strtolower($food['endpoint']['method']), $this->params['allowedMethods'])) { $errorMessage = "Wrong Method (" . $food['endpoint']['method'] . ")"; } if (!preg_match("/\\b(?:(?:https?):\\/\\/|www\\.)[-a-z0-9+&@#\\/%?=~_|!:,.;]*[-a-z0-9+&@#\\/%=~_|]/i", $food['endpoint']['url'])) { $errorMessage = "URL is invalid"; } } else { $errorMessage = "Missing Load"; } } else { $errorMessage = "Missing Endpoint"; } if ($errorMessage == "") { //print_r($food); $redis = new Redis(); if ($redis->connect('127.0.0.1', 6379)) { $countCalls = 0; if (strtolower($food['endpoint']['method']) == 'post') { //if post, then all data will be submitted at onst filling $recordUUI = sha1(microtime() . $raw . mt_rand()); $time = time(); $args = array('load' => $raw, 'time' => $time, 'count' => 0); //saving data into redis, using multi to save roundtrips $redis->multi()->hMset($recordUUI, $args)->zAdd('sQue', $time, $recordUUI)->incrBy('postCalls', 1)->incrBy('requestCount', 1)->incrBy('loadVolume', mb_strlen($raw, '8bit'))->exec(); } if (strtolower($food['endpoint']['method']) == "get") { //for GET compatibility sake break load into multiple calls //$recordData[]='que'; $recordDataForSortedSet[] = 'sQue'; foreach ($food['data'] as $index => $data) { $time = time(); $recordUUI = sha1(microtime() . $raw . mt_rand()); $recordData[] = $recordUUI; $recordDataForSortedSet[] = $time; $recordDataForSortedSet[] = $recordUUI; $breaking['endpoint'] = $food['endpoint']; $breaking['data'] = $data; $args = array('load' => json_encode($breaking, JSON_UNESCAPED_SLASHES), 'time' => $time, 'count' => 0); $redis->hMset($recordUUI, $args); $countCalls++; } //saving data into redis, didn't find method to use multi for that //call_user_func_array(array($redis, 'lpush'), $recordData); call_user_func_array(array($redis, 'zAdd'), $recordDataForSortedSet); //sorted list for process $redis->multi()->incrBy('requestCount', 1)->incrBy('loadVolume', mb_strlen($raw, '8bit'))->incrBy('getCalls', $countCalls)->exec(); //print_r($err = $redis->getLastError()); //print_r($ind); } echo 'ok'; $redis->publish('queue', '1'); } else { header("HTTP/1.0 400 Error"); echo 'Redis is offline'; } } else { header("HTTP/1.0 400 Error"); echo $errorMessage; } } } else { header("HTTP/1.0 400 Error"); echo "No Payload"; } }
$redis->connect('127.0.0.1', 6379); $sid = $_SERVER['SESSIONID']; if (empty($_SERVER['EVENT'])) { if ($info['type'] == 'login') { //发送登陆信息 $info['name'] = str_replace(array('<', '>'), array('<', '>'), $info['name']); $router->sendAllMsg(json_encode(array('type' => 'login', 'name' => $info['name'], 'id' => $sid))); //获取所有用户信息 $keys = $redis->keys('chatuser:*'); $users = array(); foreach ($keys as $k) { $u = $redis->hgetAll($k); $users[] = $u; } //设置当前用户信息 $redis->hMset("chatuser:{$sid}", array("name" => $info['name'], 'id' => $sid)); //返回用户列表 $body = json_encode(array('type' => 'list', 'list' => $users)); header("Content-Length: " . strlen($body)); echo $body; } else { if ($info['type'] == 'join') { //加入分组 $router->addChannel('chat-channel-' . $info['channel'], $sid); } else { if ($info['type'] == 'msg') { //发送消息 $name = $redis->hget("chatuser:{$sid}", "name"); $info['text'] = str_replace(array('<', '>'), array('<', '>'), $info['text']); if ($info['channel']) { $router->publish('chat-channel-' . $info['channel'], json_encode(array('type' => 'msg', 'name' => $name, 'channel' => (int) $info['channel'], 'text' => $info['text'], 'time' => date('i:s'))));