Привет всем)) подскажите как идентифицировать пользователя через сокеты.. 1. Сокет сервер у меня на ПХП (можете кидать тапки) 2. Клиент как клиент.. создаю соединение вот так вот Код (Javascript): websocket = new WebSocket(wsUri); 3. При подключении клиента к серверу получаем что то типа такого Код (Text): $ php server.php GET /server.php HTTP/1.1 Host: smf2test.ru:9000 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36 Upgrade: websocket Origin: http://smf2test.ru Sec-WebSocket-Version: 13 Accept-Encoding: gzip, deflate Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,uk;q=0.6 Cookie: PHPSESSID=7f4b1f3662c0a4e69cb8a1fb250bff71 Sec-WebSocket-Key: fHbvcQskj/+QZXR+aaSNwA== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits 4. При отправке сообщения серверу мы получаем то что хотим отправить.. тут особо нечего показывать.. 5. В связи с этим вопрос.. мне нужно что бы пользователи были авторизированы.. так как будет 4 роли.. (администратор, модератор, авторизированый пользователь и не авторизированный пользователь). Могу ли я использовать Sec-WebSocket-Key? Или лучше ИД сессии? У меня на сервере есть массив $clients - где лежат все данные открытых сокетов.. но там ресурсы)) как это правильно делать?)) Спасибо) )
Предназначен для другого. Тебе же нужно получить пользователя. Для этого есть сессии или authorization bearer. Получаешь пользователя смотришь что ему разрешено и на основании этого уже принимаешь решения подписывать на канал или нет. user.1 личное для 1 пользователя chat.1 подписка на чат 1 и т.д --- Добавлено --- Если на 1 чат разрешено подписываться только админам значит остальных не подписывай если разрешено всем но админам нужна доп инфа значит нужно создать доп канал. И т.д
задумка такая что админы могут включать выключать чат.. делать объявления над чатом грубо говоря.. модераторы могут удалять сообщения и блокировать пользователей.. а насчет допканала не очень понял.. делать еще одно сокет подключение? --- Добавлено --- ПЫСЫ чего то мой сервер крашится постоянно))
Если ты делаешь на пыхе запросы НА сервер идут по ajax здесь сокеты и не нужны. Сокеты только для приема. Просто делаешь кнопку при нажатии на которую отправляется обычный ajax запрос Касательно доп канала chat.1 - общая инфа (сообщения кто пришел кто ушел и т.д) chat.1.admin доп инфа которая приходит только админам.
о.. а у меня и отправка через сокет соединение)) я просто боюсь что если 300-400 человек начнут писать то аяксом положат сервер..
Пых не асинхронный он так не сможет. Хотя смотря на чем и как делаешь. Тут лучше присмотреться к swoole А еще лучше делать все на node например sails.js это как yii но на ноде там и сокеты с коробки и орм и все остальное.
насколько я понял он последовательно сокеты опрашивает)) почему через него не принимать? отправляю с клиента так.. Код (Text): //convert and send data to server websocket.send(JSON.stringify(msg)); вроде работает..
@Алекс8 Сокет сервер у тебя какой? Ну адрес клиента это явно не куки сессии, весь вопрос отправить клиенту без его запроса.
на php написанный.. нашел пример на гите, сейчас допиливаю... идентифицирую по PHPSESSID.. при подключении клиента на сервер передается строка с куками.. оттуда беру PHPSESSID... у меня есть массив с клиентами, я ключом делаю значение PHPSESSID.. и потом когда приходит сообщение от какого то клиента - ищу ресурс сокета и смотрю какой там ИД сессии в качестве ключа указан.. . как то так... по хорошему надо было бы разобраться с нодой)) у меня поверхностные знания JS есть.. но тут сроки поджимают)) так что делаю на том что более менее хорошо знаю))
А ссылку мог-бы привести? Апач, nginx нужно к этому? Идентифицировать это понятно, но идея сокетов отправлять без опроса с клиента.
ссылку чего найти не могу.. в коде нет авторства и пруфа)) там кода совсем мало)) вот сервер собственно)) PHP: <?php $host = 'localhost'; //host $port = '9000'; //port $null = NULL; //null var //Create TCP/IP sream socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //reuseable port socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); //bind socket to specified host socket_bind($socket, 0, $port); //listen to port socket_listen($socket); //create & add listning socket to the list $clients = array($socket); //start endless loop, so that our script doesn't stop while (true) { //manage multipal connections $changed = $clients; //returns the socket resources in $changed array socket_select($changed, $null, $null, 0, 10); //check for new socket if (in_array($socket, $changed)) { $socket_new = socket_accept($socket); //accpet new socket $clients[] = $socket_new; //add socket to client array $header = socket_read($socket_new, 1024); //read data sent by the socket perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake socket_getpeername($socket_new, $ip); //get ip address of connected socket $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data send_message($response); //notify all users about new connection //make room for new socket $found_socket = array_search($socket, $changed); unset($changed[$found_socket]); } //loop through all connected sockets foreach ($changed as $changed_socket) { //check for any incomming data while(socket_recv($changed_socket, $buf, 1024, 0) >= 1) { $received_text = unmask($buf); //unmask data $tst_msg = json_decode($received_text, true); //json decode $user_name = $tst_msg['name']; //sender name $user_message = $tst_msg['message']; //message text $user_color = $tst_msg['color']; //color //prepare data to be sent to client $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color))); send_message($response_text); //send data break 2; //exist this loop } $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ); if ($buf === false) { // check disconnected client // remove client for $clients array $found_socket = array_search($changed_socket, $clients); socket_getpeername($changed_socket, $ip); unset($clients[$found_socket]); //notify all users about disconnected connection $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected'))); send_message($response); } } } // close the listening socket socket_close($socket); function send_message($msg) { global $clients; foreach($clients as $changed_socket) { @socket_write($changed_socket,$msg,strlen($msg)); } return true; } //Unmask incoming framed message function unmask($text) { $length = ord($text[1]) & 127; if($length == 126) { $masks = substr($text, 4, 4); $data = substr($text, 8); } elseif($length == 127) { $masks = substr($text, 10, 4); $data = substr($text, 14); } else { $masks = substr($text, 2, 4); $data = substr($text, 6); } $text = ""; for ($i = 0; $i < strlen($data); ++$i) { $text .= $data[$i] ^ $masks[$i%4]; } return $text; } //Encode message for transfer to client. function mask($text) { $b1 = 0x80 | (0x1 & 0x0f); $length = strlen($text); if($length <= 125) $header = pack('CC', $b1, $length); elseif($length > 125 && $length < 65536) $header = pack('CCn', $b1, 126, $length); elseif($length >= 65536) $header = pack('CCNN', $b1, 127, $length); return $header.$text; } //handshake new client. function perform_handshaking($receved_header,$client_conn, $host, $port) { $headers = array(); $lines = preg_split("/\r\n/", $receved_header); foreach($lines as $line) { $line = chop($line); if(preg_match('/\A(\S+): (.*)\z/', $line, $matches)) { $headers[$matches[1]] = $matches[2]; } } $secKey = $headers['Sec-WebSocket-Key']; $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'))); //hand shaking header $upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "WebSocket-Origin: $host\r\n" . "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n". "Sec-WebSocket-Accept:$secAccept\r\n\r\n"; socket_write($client_conn,$upgrade,strlen($upgrade)); } --- Добавлено --- да.. но мне надо понимать что за клиент соединился с сервером.. если это AJAX запрос то тут вопросов нет.. все видно кто что прислал... а с сокетами мне пока не понятно... тут соединение и при инициализации которого отправляется заголовок с куками.. а потом просто текст ходит и все.. и никаких больше заголовков))
Теперь понятно почему сервер крашится постоянно Я думаю лучше что-то посолиднее, есть же там свули, центрифуги ....
уже не крашится)) там проверок не было)) писало в сокеты в которые нельзя писать)) поэтому крашился)) а так то уже стабильно работает))
почему?)) я сейчас worker смотрю)) но искренне не понимаю почему те 50 строк кода должны покрашится)) пока вроде работает стабильно))
я тебе больше скажу, даже одна строка будет в цикле .... PHP: while(true) или ни одной - покрашится... вопрос времени
Я вот присматривался к экстеншину но им как то никто не пользуется никто его не советует. В той же ларке сервер на ноде поднят. Интересно в итоге узнать за результат. Можно доку глянуть http://fi2.php.net/manual/en/book.sockets.php Кто его знает как там все устроено.
Я вот когда начинал делать проект долго выбирал между ларкой и sails. С одной стороны для пыха все есть все продумано но везде костыли с другой нода для которой все есть без костылей но не до конца продумано. Даже сейчас довольно сомнительный выбор. В 10 ноде вреди mjx планируют добавить плюс декораторы если sails перепишут вообще прикольно будет
мне честно говоря синтаксис не нравится JS)) на код смотрю и он не красивый какой то)) если в пхп все по класса разложено)) все понятно))) автозагрузка)) то в JS как то все вечно одной портянкой))
@Алекс8 Ну потому я и говорю за mjs* с импортами с классами и т.д плюс с появлением async не все так плохо стало. В sails все c коробки на async. Тот же react давно на классах а нода все тормозит. А в остальном синтаксис прикольный можно все в одну строку писать
Ну справедливости ради, в NodeJS поддерживается последний стандарт JavaScript, а там и классы есть, и модули. --- Добавлено --- @Алекс8, php в один поток твой сервер выполняет по дефолту. Будет побольше нагрузка - будет трындец котёнку. Одного-то тебя, ясное дело, выдержит. Если swoole какую-нибудь прикрутить, там учтено это должно быть (она, в принципе, php в ноду практически превращает, насколько я понял).
я вот это https://github.com/walkor/Workerman уже запустил)) научился уже обмениваться соощениями) в две стороны)
Все это вопрос эстетики в js изначально все объект синтаксис es6 тоже не плох Код (Javascript): module.exports = { index: function (req, res) { ... }, show: function (req, res) { ... }, store: function (req, res) { ... }, }; Или даже так Код (Javascript): module.exports = { index: (req, res) => { ... }, show: (req, res) => { ... }, store: (req, res) => { ... }, }; С es2015 еще веселее..
А останавливать только перезагрузкой? Там же кодируется какая-то информация - имя, цвет и тп, не просто же текст приходит?