Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.06.2020, 13:49   #1
Максим Королев
Пользователь
 
Регистрация: 02.09.2018
Сообщений: 22
Сообщение Реализация личной переписки на RatChet

Доброе время суток товарищи.
В начале того месяца решил сделать чат на своем сайте(пока что локальном), посёрфил инет, выбрал язык в котором более менее разбираюсь, и приступил к работе, все шло отлично до момента пока я не догадался что сообщение отправляется на сервер ко всем пользователям, и опять я начал искать решение в интернете нашел парочку решений углубился но так ничего и не понял
Инфу брал от сюда:
https://github.com/luschenko/js_resh.../26_js_reshaet
https://qna.habr.com/q/692275
https://overcoder.net/q/336409/%D0%B...-php-websocket
https://github.com/cboden/Ratchet-ex...e/ChatRoom.php

Вот как я реализовывал это:
Файл сервера
Код:
<?php
require 'vendor/autoload.php';

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;


class Chat implements MessageComponentInterface {
    protected $clients;
    protected $clientids;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
        $this->clientids = array(); 

    }

    public function multicast($msg) {
        foreach ($this->clients as $client) $client->send($msg);
    }

    public function send_to($to,$msg) {
        if (array_key_exists($to, $this->clientids)) $this->clientids[$to]->send($msg);
    }

    public function onOpen(ConnectionInterface $conn) {
        $socket_name = "name";
        echo $socket_name;
        $this->clients->attach($conn,$socket_name);
        $this->clientids[$socket_name] = $conn;
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $this->multicast($msg);
    }

    public function onClose(ConnectionInterface $conn) {
        unset($this->clientids[$this->clients[$conn]]);
        $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        $conn->close();
    }
}


    $server = IoServer::factory(
        new HttpServer(
            new WsServer(
                new Chat()
            )
        ),
        8777
    );

    $server->run();
Сам скрипт:
Код:
<script>
		var message = document.querySelector('.text-message');
		var btn = document.getElementById('btn');
		var dialog = document.querySelector('.dialog');
		var id_ex = "<?=$_GET['id_ex']?>";
		var type = "<?=$_SESSION['type']?>";
		var id_messanger = "<?=$_SESSION['id']?>";
		var page = "<?=$page?>"
		var conn = new WebSocket('ws://127.0.0.1:8777');
		
		conn.onopen = function(e) {
		    console.log("Connection established!");
		};

		conn.onmessage = function(e) {
		    console.log(e.data);
			dialog.innerHTML+= e.data;
			
		};
		
		btn.onclick = function(){
    	var msg = message.value
    	if (type == 'customer'){
    		conn.send('<div class="block text-right"><span class=" border border-light">'+(msg)+'</span></div>');	
    	}else{
    	conn.send('<div class="block text-left"><span class=" border border-light">'+(msg)+'</span></div>');
    	}
    	conn.send(id_ex);
    	document.getElementById("message").value = "";
    };

	</script>
На странице со скриптом есть переменная $_GET , я использую её для того чтобы создавалось что-то на подобии диалога, но работает только с базой данных, я думаю есть какая-нибудь возможность передать эту переменную на сервер, и уже там через какой-то код код отправлять пользователям у которых есть эта переменная. Есть какой-нибудь пример?Буду очень благодарен за любую помощь. Заранее спасибо
Максим Королев вне форума Ответить с цитированием
Старый 02.06.2020, 16:10   #2
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,150
По умолчанию

сейчас то что не устраивает? Использование БД?
Полюбому надо где то будет хранить сообщения
ADSoft вне форума Ответить с цитированием
Старый 03.06.2020, 15:37   #3
Максим Королев
Пользователь
 
Регистрация: 02.09.2018
Сообщений: 22
По умолчанию

ADSoft, Хранение в базе данных это обязательно, здесь проблема в том, что когда пользователь пишет сообщение оно попадает ко всем кто сейчас находится на сервере, а не конкретному. Есть мысль как это реализовать но на стороне кода не понимаю как это сделать.В RatChet есть Rooms , если придать room параметр $_GET['id_ex'], и потом пропускать туда пользователей у которых тоже будет передаваться этот параметр. Но как перередать это знаиние либо как придать его к Rooms не понимаю.
Максим Королев вне форума Ответить с цитированием
Старый 03.06.2020, 20:31   #4
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,150
По умолчанию

так зачем тогда multicast ?
отправляй конкретно 1 пользователю
ADSoft вне форума Ответить с цитированием
Старый 04.06.2020, 00:30   #5
Максим Королев
Пользователь
 
Регистрация: 02.09.2018
Сообщений: 22
По умолчанию

ADSoft,Я понял что нужно, отправлять через send_to(), но как именно выбрать именно того пользователя которому нужно отослать это сообщение. Мне нужно сделать что то подобное:
Код:
class Chat implements MessageComponentInterface {
 private $room;
  public function __construct() {
    $this->room = array();
  }
  public function onOpen(ConnectionInterface $conn) {
        $room_id = $_GET['id_room'];
        $this->room[$room_id] = $conn;
  }
  public function send_to($to,$msg) {
        if (array_key_exists($to, $this->room)) $this->room[$to]->send($msg);
    }
  public function onMessage(ConnectionInterface $from, $msg) {
        $this->send_to($to,$msg);
    }
Типо переменной room должна присваиваться в параметр room_id ($_GET['id_room']), и потом в функции send_to делать отбор, если у пользователя такой то айди комнаты отсылать это сообщение ему, то есть допустим, на страницу попадают 2 пользователя и у них у обоих будет переменная $GET['id_room'] = 3 , значит только они будут получать сообщения.Проблема в том что я не понимаю какой проходит выбор пользователя в функции send_to и как мне придать переменной $room_id значение gett , либо как-то передать его со страницей скрипта.

Последний раз редактировалось Максим Королев; 04.06.2020 в 03:20. Причина: Усовершенстововал слегка)
Максим Королев вне форума Ответить с цитированием
Старый 04.06.2020, 08:04   #6
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,150
По умолчанию

да что вы то к широковещанию для всех, теперь к комнатам привязались?
У вас нужно отправлять конкретному клиенту - так и отправляйте
Код:
public function onMessage(ConnectionInterface $to, $msg) {
foreach ($this->clients as $client) {
	if ($to== $client) {	
		$client->send();
       }
}
}
ADSoft вне форума Ответить с цитированием
Старый 05.06.2020, 07:22   #7
Максим Королев
Пользователь
 
Регистрация: 02.09.2018
Сообщений: 22
По умолчанию

Цитата:
Сообщение от ADSoft Посмотреть сообщение
да что вы то к широковещанию для всех, теперь к комнатам привязались?
У вас нужно отправлять конкретному клиенту - так и отправляйте
Код:
public function onMessage(ConnectionInterface $to, $msg) {
foreach ($this->clients as $client) {
	if ($to== $client) {	
		$client->send();
       }
}
}
ADSoft, Да вы правильно все сделали, только теперь нужно чтобы пользователя выбрать знать хотя бы его айди, но получается так что у каждого пользователя , каждый раз разный айди. Как мне отловить именно того пользователя которому нужно отослать это сообщение?
Максим Королев вне форума Ответить с цитированием
Старый 05.06.2020, 07:54   #8
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,150
По умолчанию

ну у меня так было реализовано:
- при первом коннекте, пользователь должен залогиниться
- на стороне сервера проверяем лог/пасс, или ключ ..смотря как регался, после чего у нас есть id пользователя, присоединеям К $client->id_user и еще - все что хотим.
- после чего у нас есть нужная информация
- сама отправка сообщений шла через очереди ZeroMQ и PHP, то есть в сервере был обработчик поступления данных из очереди - как данные поступали - тут же по вебсокету отправлялись
ADSoft вне форума Ответить с цитированием
Старый 05.06.2020, 08:42   #9
Максим Королев
Пользователь
 
Регистрация: 02.09.2018
Сообщений: 22
По умолчанию

Цитата:
Сообщение от ADSoft Посмотреть сообщение
ну у меня так было реализовано:
- на стороне сервера проверяем лог/пасс, или ключ ..смотря как регался, после чего у нас есть id пользователя, присоединеям К $client->id_user и еще - все что хотим.
То есть получается у вас был прямой доступ к базе, либо вы через сессию все делали?
Максим Королев вне форума Ответить с цитированием
Старый 05.06.2020, 12:22   #10
ADSoft
Старожил
 
Регистрация: 25.02.2007
Сообщений: 4,150
По умолчанию

был доступ конечно
через сессию тут не сделаешь, это ж сокеты
ну у меня было не сдеалать - ибо у меня общение было и с мобильных и с сайтов
ADSoft вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шифрование переписки в любом окне Norkus Безопасность, Шифрование 3 24.08.2017 10:13
Компонент личной страницы для пользователей mila_serdnaya Фриланс 0 04.11.2016 08:13
Софт для переписки с большого количества аккаунтов ВК Primo13 Фриланс 0 14.09.2015 13:51
CMS с личной страницей Green4el WordPress и другие CMS 0 04.06.2013 10:52
Конференц-чат с поддержкой истории почтовой переписки Рыбёшка Помощь студентам 0 13.02.2013 15:57