Показать сообщение отдельно
  #1 (permalink)  
Старый 02.05.2014, 12:36
Интересующийся
Отправить личное сообщение для Arhangel64 Посмотреть профиль Найти все сообщения от Arhangel64
 
Регистрация: 06.10.2013
Сообщений: 20

Socket IO + History API проблема с мультиплексированием и переподключением
Здравствуйте.
Ситуация следующая. существует несколько страниц сайта, переключающиеся с помощью AJAX + History API по следующей схеме
<html>
<head>
</head>
<body>
    //некоторые заголовки, навигационная панель
    <script>
        //глобальный скрипт
    </script>
    <div id='pseudoBody'>
        //Страница сайта
        <script>
            //локальный скрипт
        </script>
    </div>
</body>
</html>


В глобальном скрипте происходит подключение к socket.io всех пользователей. Для них будут выводиться какие-то глобальные события.
В локальном скрипте происходит подключение к socket.io всех пользователей просматривающих данную страницу. Сообщения этой страницы должны приходить только этим пользователям. Например, страница с чатом.
То есть, на деле должно происходить следующее. Пользователь открывает любую страницу, подключается к глобальному сокету. Пользователь переходит на страницу с локальным сокетом, подклчается к нему. Когда выходит - отключается. Если захочет вернуться - снова подключается.
На деле выходит не совсем так.
Существует, так называемое, мультиплексирование соединений, то есть все открытые сокеты, по сути, передаются через один. При подключении первого сокета - открывается соединение, при подключении второго - второй сокет мультиплексируется в первое подключение, все корректно. При отключении локальный сокет отключается вроде корректно. Но при подключении обратно открывается новый сокет, который работает некорректно.
реализовано следующим образом.
На сервере:
var io = require('socket.io').listen(server)
io.set(... некоторые опции ...)
	
io.set('authorization', function(handshake, callback) {
... процесс авторизации из сессий экспресса ...
}


var chat = io
  .of('/chat') // локальный сокет
  .on('connection', function (socket) {
    ... Обработчики событий ...		
    socket.on('disconnect', function () {
      socket.broadcast.emit('leave', username);
    });
  });

var main = io
  .of('/main') // глобальный сокет
  .on('connection', function(socket) {
    ... обработчики событий  ...
  })


На клиенте в глобальном скрипте

var main = io.connect(location.host+'/main');
main
  .on('connection', function (){
    ... обработчики ...
  })

var socket; // переменная для локального сокета


В локальном

socket = io.connect(location.host+'/chat');
socket
  .on('connect', function() {

    ... обработчики ...
    
    socket.on('disconnect', function() {
    });
});


И, наконец функция, отвечающая за смену фрагмента документа, которая должна запускать новые скрипты и бивать старые сокеты

$.ajax({
      url: link,  //link ссылка на локальный документ
      method: "GET",
      data: null,
      statusCode: {
        200: function(jqXHR) {
		  if (socket) {
			socket.disconnect();
			socket = undefined;
		  }
          pseudobody.innerHTML = jqXHR;
		  var start = new Function ('callback', $('#pseudoBody script').get(0).innerHTML+'callback();');
		  start(function (){
			if (socket) socket.socket.connect();
		  });
        }
      }
});


Подскажите пожалуйста, где я ошибся? Почему переподключение мало того, происходит в новый сокет, так еще и висит мертвое - события по нему не приходят?

Последний раз редактировалось Arhangel64, 02.05.2014 в 12:40. Причина: Правка оформления кода
Ответить с цитированием