Не удается связаться с веб-сокетом. Автобан: получено сообщение HELLO, сессия еще не установлена

Я пытаюсь создать сеанс WebSocket, используя Python 3.4, Django, Autobahn и JS. Я успешно запустил сервер websocket на стороне python, но не могу подписаться или получать какие-либо данные, опубликованные сервером.

Мой код довольно прост:

class TestAppWS(ApplicationSession):
    """
    An application component that publishes an event every second.
    """
    def onConnect(self):
        self.join(u"realm1")

    @asyncio.coroutine
    def onJoin(self, details):
        counter = 0
        while True:
            self.publish('com.myapp.topic1', counter)
            counter += 1
            yield from asyncio.sleep(1)


def start_ws():
    print("Running")
    session_factory = ApplicationSessionFactory()
    session_factory.session = TestAppWS
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    # factory = WebSocketServerFactory("ws://localhost:8090", debug=False)
    # factory.protocol = MyServerProtocol

    server = None
    try:
        transport_factory = WampWebSocketServerFactory(session_factory, debug_wamp=True)
        loop = asyncio.get_event_loop()
        coro = loop.create_server(transport_factory, 'localhost', 8090)
        server = loop.run_until_complete(coro)
        loop.run_forever()
    except OSError:
        print("WS server already running")
    except KeyboardInterrupt:
        pass
    finally:
        if server:
            server.close()
        loop.close()

start_ws() запускается внутри отдельного объекта Thread. Если я захожу на localhost:8090 в своем браузере, я вижу приветственное сообщение Autobahn.

На фронтенде у меня есть

var connection = new autobahn.Connection({
   url: 'ws://localhost:8090/',
   realm: 'realm1'}
);
connection.onopen = function (session) {    
   var received = 0;

   function onevent1(args) {
      console.log("Got event:", args[0]);
      received += 1;
      if (received > 5) {
         console.log("Closing ..");
         connection.close();
      }
   }

   session.subscribe('com.myapp.topic1', onevent1);
};

connection.open();

Кажется, это не работает, когда я пытаюсь подключить интерфейс, я получаю следующую ошибку на стороне сервера:

Failing WAMP-over-WebSocket transport: code = 1002, reason = 'WAMP Protocol Error (Received <class 'autobahn.wamp.message.Hello'> message, and session is not yet established)'
WAMP-over-WebSocket transport lost: wasClean = False, code = 1006, reason = 'connection was closed uncleanly (I failed the WebSocket connection by dropping the TCP connection)'
TX WAMP HELLO Message (realm = realm1, roles = [<autobahn.wamp.role.RolePublisherFeatures object at 0x04710270>, <autobahn.wamp.role.RoleSubscriberFeatures object at 0x047102B0>, <autobahn.wamp.role.RoleCallerFeatures object at 0x047102D0>, <autobahn.wamp.role.RoleCalleeFeatures object at 0x047102F0>], authmethods = None, authid = None)
RX WAMP HELLO Message (realm = realm1, roles = [<autobahn.wamp.role.RoleSubscriberFeatures object at 0x04710350>, <autobahn.wamp.role.RoleCallerFeatures object at 0x04710330>, <autobahn.wamp.role.RoleCalleeFeatures object at 0x04710390>, <autobahn.wamp.role.RolePublisherFeatures object at 0x04710370>], authmethods = None, authid = None)
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\autobahn\wamp\websocket.py", line 91, in onMessage
    self._session.onMessage(msg)
  File "C:\Python34\lib\site-packages\autobahn\wamp\protocol.py", line 429, in onMessage
    raise ProtocolError("Received {0} message, and session is not yet established".format(msg.__class__))
autobahn.wamp.exception.ProtocolError: Received <class 'autobahn.wamp.message.Hello'> message, and session is not yet established

в консоли javascript я вижу:

Uncaught InvalidAccessError: Failed to execute 'close' on 'WebSocket': The code must be either 1000, or between 3000 and 4999. 1002 is neither.

Есть идеи? Похоже сессия не запущена, честно говоря не понятно как эта сессия работает. Не следует ли инициализировать сеанс после установления соединения с клиентом?


person Simone Zandara    schedule 31.12.2014    source источник


Ответы (1)


Ваш TestAppWs и код вашего браузера являются компонентами приложения WAMP. Оба они должны быть подключены к маршрутизатору WAMP. Тогда они могут свободно общаться друг с другом (как если бы между ними не было маршрутизатора .. прозрачно).

Вот как бегать.

Запустите маршрутизатор WAMP.

Используя Crossbar.io (но вы можете использовать другие WAMP-маршрутизаторы), это тривиально. Сначала установите Crossbar.io:

pip install crossbar

Crossbar.io (в настоящее время) работает на Python 2, но это не имеет значения, поскольку компоненты вашего приложения могут работать на Python 3 или любом другом поддерживаемом WAMP языке/времени выполнения. Думайте о Crossbar.io как о черном ящике, внешней инфраструктуре, как о системе баз данных.

Затем создайте и запустите маршрутизатор Crossbar.io по умолчанию:

cd $HOME
mkdir mynode
cd mynode
crossbar init
crossbar start

Запустите компонент Python 3/asyncio

import asyncio
from autobahn.asyncio.wamp import ApplicationSession


class MyComponent(ApplicationSession):

   @asyncio.coroutine
   def onJoin(self, details):
      print("session ready")

      counter = 0
      while True:
         self.publish('com.myapp.topic1', counter)
         counter += 1
         yield from asyncio.sleep(1)


if __name__ == '__main__':
   from autobahn.asyncio.wamp import ApplicationRunner

   runner = ApplicationRunner(url = "ws://localhost:8080/ws", realm = "realm1")
   runner.run(MyComponent)

Запустите компонент браузера

var connection = new autobahn.Connection({
   url: 'ws://localhost:8080/ws',
   realm: 'realm1'}
);

connection.onopen = function (session) {    
   var received = 0;

   function onevent1(args) {
      console.log("Got event:", args[0]);
      received += 1;
      if (received > 5) {
         console.log("Closing ..");
         connection.close();
      }
   }

   session.subscribe('com.myapp.topic1', onevent1);
};

connection.open();
person oberstet    schedule 31.12.2014
comment
Спасибо oberstet, я уже заметил Crossbar.io в Интернете, но подумал, что смогу реализовать его без дополнительного работающего узла. Я пытаюсь упростить развертывание. Однако похоже, что у меня нет другого выбора :) Я попробую ваше решение - person Simone Zandara; 02.01.2015
comment
FWIW, мы хотим сделать развертывание Crossbar.io максимально простым, как yum/apt-get install crossbar. Маршрутизатор WAMP должен быть черным ящиком, как брокер AMQP, а не зависимостью библиотеки в приложении. - person oberstet; 02.01.2015
comment
В конце концов я решил использовать параллельный NodeJS для веб-сокетов. Я думаю, что идея автобана хороша, но у меня были проблемы из-за перекладины. Я использую Python 3.4, а crossbar работает только на Python 2, для которого требуется установка обеих версий Python. Также для полной установки crossbar в Windows требуется слишком много пакетов. Это делает развертывание слишком сложным. Простая установка перекладины решила бы проблему, но пока я нахожу это слишком сложным. - person Simone Zandara; 28.01.2015