Simple synchronous sending of one message

32 views
Skip to first unread message

Stephan Schmidt

unread,
Nov 22, 2016, 11:23:01 AM11/22/16
to Autobahn
Hey,

I have an application with typical publish / subscribe pattern. Clients are subscribing using a browser and javascript. I'd like to have a command line utility which sends messages to a topic. I do not need any asynchronous messaging. I just want to send simple object updates (sth. like "order 123 has been shipped").

The problem I had so far is not being able to close the connection correctly. Is it possible to write a small function which does everything?

>>> send("com.myapp.topic", {"order": 123, "status": "shipped"})

where send() opens a connections, sends the data and closes the connection accordingly.

I am not very familiar with asyncio. I hope you can help me. Thx.

David Ford

unread,
Nov 22, 2016, 1:33:23 PM11/22/16
to Autobahn
try session.call(...).then(...), and your .then() will fire when complete and you can cleanly shut down and exit. your .then() should have 1+ arguments which are called for success, error, and progress.

here's an example snippet:

    session.call('com.example.foo', [your_data], {}, {receive_progress:true}).then(
      function(res) {
        close_session_stuff();
      },

      function(err) {
        handle_error();
      },

      function (progress) {
        /* progressive result returned until success/error */
        console.log("Progress:",progress);
      }
    );



--
You received this message because you are subscribed to the Google Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/271d2480-a4ac-41fc-be78-d1f29f3836e7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Stephan Schmidt

unread,
Nov 23, 2016, 9:24:47 AM11/23/16
to Autobahn
Hey David,

thank you for the reply. Do you have a similar approach for a python based server?

David Ford

unread,
Nov 23, 2016, 12:55:32 PM11/23/16
to Autobahn
the semantics are different because the python objects don't chain like this utilizing promises. you can utilize the yield foo() semantics in which python performs foo as a coroutine, or you can use the asyncio eventloop to juggle multiple tasks yourself.

the yield foo() semantics make things appear to run inline as linear code but it's important to note that coroutines can pause at the yield line and resume context at the line that called the coroutine. here's some actual code from one of my classes that does ButterflyDNS.

    @asyncio.coroutine
    def _get_zone_soa(self, zone):
        with (yield from self.pool.cursor()) as cur:
            yield from cur.execute('''SELECT  c.content as zone,
                                 r.created,r.updated,r.data,r.type,r.host,r.priority,r.ttl
                           FROM  record r,
                                 canonical c
                          WHERE  c.content = %(zone)s
                            AND  r.zone=c.domain
                            AND  r.type='SOA'
                           ''', {'zone':zone})

            _ = yield from cur.fetchone()
            _ = (yield from self._make_dict_list(cur, [_]))[0]

            # note, SOA updates go to everyone
            return ('org.head.butterflydns.zone.records.get.soa', _)

    @wamp.register('org.head.butterflydns.zone.records.send')
    def send_records(self, *args, **detail):
        for e in args:
            print('send_records received args: {}'.format(args))
        for k,v in detail.items():
            print('send_records: k={} v={}'.format(k,v))

        zone = args[0]

        if not zone:
            return

        def process_runner(zone):
            # run all of these concurrently
            tasks = [
                self._get_zone_soa(zone),
                self._get_zone_local(zone),
                self._get_zone_registrar(zone),
                self._get_zone_transfer_acl(zone),
                self._get_zone_resourcerecords(zone),
                self._get_zone_ns_glue(zone),
                ]

            for f in asyncio.as_completed(tasks):
                topic, result = yield from f

                self.push_pub(topic, result)

        yield from process_runner(zone)

i've only included _get_zone_soa(), but all of the tasks are semantically the same. the wamp call for zone.records.send will run quickly and the browser client will get a success promptly. as each of the tasks complete, they'll publish their results to a crafted uri and vanish. the webpage UI for managing the zone will respond to the publish and update the appropriate block of HTML as it receives each result.


On Wed, Nov 23, 2016 at 9:24 AM 'Stephan Schmidt' via Autobahn <autob...@googlegroups.com> wrote:
Hey David,

thank you for the reply. Do you have a similar approach for a python based server?

--
You received this message because you are subscribed to the Google Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.

Tobias Oberstein

unread,
Nov 23, 2016, 1:15:55 PM11/23/16
to autob...@googlegroups.com
Hi Stephan,

Crossbar.io has a built-in REST/HTTP to WAMP two-way bridge.

Eg you can publish a WAMP event from command line using plain old curl:

http://crossbar.io/docs/HTTP-Bridge-Publisher/#try-it

Will this do?

Cheers,
/Tobias

Stephan Schmidt

unread,
Nov 24, 2016, 10:35:14 AM11/24/16
to Autobahn
Tobias,

that is exactly what I was looking for. How could I miss this?

Thank you very much for this info. It helped a lot.
Reply all
Reply to author
Forward
0 new messages