2014-12-31 4 views
2

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

Мой код достаточно прост:

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() выполняется в отдельном потоке объект. Если я получаю доступ к 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. 

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

ответ

1

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

Вот как работать.

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

Использование Crossbar.io (но вы также можете использовать other WAMP routers), это тривиально. Сначала установите 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(); 
+0

Спасибо, оберстет, я уже заметил Crossbar.io через Интернет, но я думал, что смогу реализовать его без дополнительного ходового узла. Я пытаюсь упростить развертывание. Однако, похоже, у меня нет другого выбора :) Я попробую ваше решение –

+0

FWIW, мы хотим сделать развертывание Crossbar.io так же просто, как 'yum/apt-get install crossbar'. Маршрутизатор WAMP должен быть «черным ящиком», как брокером AMQP, а не зависимостью библиотеки от приложения. – oberstet

+0

В конце концов я решил использовать параллельный NodeJS для веб-сайтов. Я думаю, что идея Autobahn хороша, но у меня были проблемы из-за перекладины. Я использую Python 3.4, а crossbar работает только на Python 2, который требует установки обеих версий python. Кроме того, полная полная установка в Windows требует слишком большого количества пакетов. Это делает развертывание немного сложнее. Легкая установка перекладины решила бы проблему, но до сих пор я считаю ее слишком сложной. –

Смежные вопросы