moved to crossbarexamples repo

This commit is contained in:
Tobias Oberstein
2015-08-29 22:08:25 +02:00
parent 9d6b3ab26d
commit e48c09da11
22 changed files with 0 additions and 980 deletions

View File

@@ -36,15 +36,6 @@ For examples using RPC, you need to run the backend first, so that procedures ar
* [Options](pubsub/options): use of PublishOptions and SubscribeOptions
* [Unsubscribe](pubsub/unsubscribe): listen to events for a limited time
### WAMPlet Examples
These are some larger examples, implemented as pluggable "WAMPlets". These can also serve as skeletons to base your own WAMPlets from, should you wish to package components like this.
* [votegame](wamplet/votegame): a collaborative voting "game" to decide the most amazing fruit. Updates votes amongst all clients in realtime
* [wampirc](wamplet/wampirc): shows some simple bridging between IRC and WAMP, exporting private messages to the bot as WAMP publish()-es
* [wamplet1](wamplet/wamplet1): just a minimal skeleton
### App Examples
_We still need to explain these. For starters, here's the list:_

View File

@@ -1,5 +0,0 @@
*.pyc
*.egg-info
build
dist
*.db

View File

@@ -1 +0,0 @@
recursive-include votegame/web *

View File

@@ -1,11 +0,0 @@
test:
python votegame/backend.py
install:
python setup.py install
clean:
find . -name "*.pyc" -exec rm -f {} \;
rm -rf dist
rm -rf build
rm -rf *.egg-info

View File

@@ -1,31 +0,0 @@
This example demonstrates the use of databases (e.g. SQLite or PostgreSQL) from WAMP application components. The example is a simple voting app packaged up as a **WAMPlet** application component.
A **WAMPlet** can be thought of a reusable application component that can be deployed dynamically as needed.
Get started by copying this folder and it's contents and begin by modifying a working base line.
## Try it
All the interesting bits with our application component are in [here](votegame/backend.py).
For development, start a locally running WAMP router, e.g. **Crossbar**.io:
```shell
cd $HOME
crossbar init
crossbar start
```
and in a second terminal run the file containing the application component:
```shell
python votegame/backend.py
```
In your browser, open the file `votegame/web/index.html`.
## Deploying
You can deploy your WAMPlet to a WAMPlet container for production.
A configuration for [**Crossbar**.io](http://crossbar.io) which runs a WAMP router, loads the VoteGame backend component and serves static Web content from the VoteGame package can be found [here](config.json).

View File

@@ -1,60 +0,0 @@
{
"processes": [
{
"type": "worker",
"modules": [
{
"type": "router",
"realms": {
"realm1": {
"permissions": {
"anonymous": {
"create": true,
"join": true,
"access": {
"*": {
"publish": true,
"subscribe": true,
"call": true,
"register": true
}
}
}
},
"components": [
{
"type": "wamplet",
"dist": "votegame",
"entry": "backend",
"extra": {
"dbfile": "votegame.db",
"items": ["banana", "lemon", "grapefruit"]
}
}
]
}
},
"transports": [
{
"type": "web",
"endpoint": {
"type": "tcp",
"port": 8080
},
"paths": {
"/": {
"type": "static",
"module": "votegame",
"resource": "web"
},
"ws": {
"type": "websocket"
}
}
}
]
}
]
}
]
}

View File

@@ -1,42 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from setuptools import setup, find_packages
setup(
name='votegame',
version='0.0.2',
description='VoteGame Service WAMPlet',
platforms=['Any'],
packages=find_packages(),
include_package_data=True,
zip_safe=False,
entry_points={
'autobahn.twisted.wamplet': [
'backend = votegame.backend:make'
],
}
)

View File

@@ -1,160 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
import os
import datetime
import sqlite3
from twisted.python import log
from twisted.enterprise import adbapi
from twisted.internet.defer import inlineCallbacks
from autobahn import wamp
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError
from autobahn.wamp.types import PublishOptions
# WAMP application component with our app code.
##
class VoteGameBackend(ApplicationSession):
def __init__(self, config):
ApplicationSession.__init__(self)
self.config = config
self.init_db()
def init_db(self):
if not os.path.isfile(self.config.extra['dbfile']):
log.msg("Initializing database ..")
db = sqlite3.connect(self.config.extra['dbfile'])
cur = db.cursor()
cur.execute("""
CREATE TABLE votes (
item TEXT NOT NULL,
count NUMBER NOT NULL,
PRIMARY KEY (item))
""")
for item in self.config.extra['items']:
cur.execute("INSERT INTO votes (item, count) VALUES (?, ?)", [item, 0])
db.commit()
db.close()
log.msg("Database initialized.")
else:
log.msg("Database already exists.")
self.db = adbapi.ConnectionPool('sqlite3', self.config.extra['dbfile'], check_same_thread=False)
log.msg("Database opened.")
@wamp.register("com.votegame.get_votes")
def get_votes(self):
def run(txn):
txn.execute("SELECT item, count FROM votes")
res = {}
for row in txn.fetchall():
res[row[0]] = row[1]
return res
return self.db.runInteraction(run)
@wamp.register("com.votegame.vote")
def vote(self, item):
if item not in self.config.extra['items']:
raise ApplicationError("com.votegame.error.no_such_item", "no item '{}' to vote on".format(item))
def run(txn):
# FIXME: make the following into 1 (atomic) SQL statement
# => does SQLite feature "UPDATE .. RETURNING"?
txn.execute("UPDATE votes SET count = count + 1 WHERE item = ?", [item])
txn.execute("SELECT count FROM votes WHERE item = ?", [item])
count = int(txn.fetchone()[0])
self.publish("com.votegame.onvote", item, count,
options=PublishOptions(excludeMe=False))
return count
return self.db.runInteraction(run)
@inlineCallbacks
def onJoin(self, details):
def onvote(item, count):
print("New vote on '{}': {}".format(item, count))
yield self.subscribe(onvote, 'com.votegame.onvote')
try:
regs = yield self.register(self)
print("Ok, registered {} procedures.".format(len(regs)))
except Exception as e:
print("Failed to register procedures: {}".format(e))
print("VoteGame Backend ready!")
def onDisconnect(self):
reactor.stop()
def make(config):
##
# This component factory creates instances of the
# application component to run.
##
# The function will get called either during development
# using the ApplicationRunner below, or as a plugin running
# hosted in a WAMPlet container such as a Crossbar.io worker.
##
if config:
return VoteGameBackend(config)
else:
# if no config given, return a description of this WAMPlet ..
return {'label': 'VoteGame Service WAMPlet',
'description': 'This is the backend WAMP application component of VoteGame.'}
if __name__ == '__main__':
from autobahn.twisted.wamp import ApplicationRunner
extra = {
"dbfile": "votegame.db",
"items": ["banana", "lemon", "grapefruit"]
}
# test drive the component during development ..
runner = ApplicationRunner(
url="ws://127.0.0.1:8080/ws",
realm="realm1",
extra=extra,
debug=False, # low-level WebSocket debugging
debug_wamp=False, # WAMP protocol-level debugging
debug_app=True) # app-level debugging
runner.run(make)

View File

@@ -1,60 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<h1>Votes Frontend</h1>
<p>Open JavaScript console to watch output.</p>
<script>AUTOBAHN_DEBUG = true;</script>
<script src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz"></script>
<button onclick="vote('banana')">Banana</button>
<button onclick="vote('lemon')">Lemon</button>
<button onclick="vote('grapefruit')">Grapefruit</button>
<script>
// WebSocket (WAMP) server address
var wsuri;
if (document.location.origin == "file://") {
wsuri = "ws://127.0.0.1:8080/ws";
} else {
wsuri = (window.location.protocol === "http:" ? "ws:" : "wss:") + "//" + document.location.host + "/ws";
}
var connection = new autobahn.Connection({
url: wsuri,
realm: 'realm1'
});
connection.onopen = function (session) {
console.log("Connected to", wsuri);
session.subscribe('com.votegame.onvote', function (args) {
console.log("new votes for " + args[0] + " : " + args[1]);
});
session.call('com.votegame.get_votes').then(
function (votes) {
console.log("Current votes:", votes);
},
session.log
);
};
connection.open();
function vote(item) {
if (connection.session) {
connection.session.call('com.votegame.vote', [item]).then(
function (count) {
console.log("Ok, voted for " + item + " : " + count);
},
connection.session.log
);
} else {
console.log("can't vote: no connection");
}
}
</script>
</body>
</html>

View File

@@ -1,4 +0,0 @@
*.egg-info
build
dist
*.pyc

View File

@@ -1,14 +0,0 @@
all:
@echo "Targets: run, install, clean"
run:
PYTHONPATH="." python wampirc/service.py
install:
python setup.py install
clean:
find . -name "*.pyc" -exec rm -f {} \;
rm -rf dist
rm -rf build
rm -rf *.egg-info

View File

@@ -1,24 +0,0 @@
# WAMP IRC
WAMPlet that provides IRC bot services to applications.
The component bridges IRC and [WAMP](http://wamp.ws). It exposes IRC to WAMP, e.g. there are RPC endpoints for starting a bot, joining channels, listening for activity, and publishing IRC activity as WAMP PubSub events.
It is written as a WAMPlet, a reusable WAMP-based application component, that can be run connecting to any WAMP router (e.g. [**Crossbar**.io](https://github.com/crossbario/crossbar/wiki)). The component can be started directly, or WAMP routers capable of *hosting* WAMPlets can run the component under supervision.
## Try it
Start up a WAMP router in a first terminal - e.g. **Crossbar**.io:
```shell
crossbar init
crossbar start
```
Run the WAMPlet from the local directory:
```shell
PYTHONPATH="." python wampirc/service.py
```
Open the test console `test/index.html` in your browser to control the component.

View File

@@ -1,41 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from setuptools import setup, find_packages
setup(
name='wampirc',
version='0.0.1',
description='An IRC bot service component.',
platforms=['Any'],
packages=find_packages(),
entry_points={
'autobahn.twisted.wamplet': [
'bot = wampirc.service:make'
],
},
zip_safe=False,
)

View File

@@ -1,50 +0,0 @@
<!DOCTYPE html>
<html>
<body>
<h1>IRC Bot Test Frontend</h1>
<p>Open JavaScript console to watch output.</p>
<script>AUTOBAHN_DEBUG = true;</script>
<script src="https://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz"></script>
<button onclick="start_bot()">Start Bot</button>
<button onclick="stop_bot(1)">Stop Bot 1</button>
<script>
var connection = new autobahn.Connection({
url: 'ws://127.0.0.1:8080/ws',
realm: 'realm1'}
);
connection.onopen = function (session) {
session.subscribe('com.myapp.on_privmsg', function (args) {
console.log(args);
});
};
connection.open();
function start_bot() {
if (connection.session) {
connection.session.call("com.myapp.start_bot",
["bot23", ["autobahn"]]).then(
connection.session.log,
connection.session.log);
} else {
console.log("no connection");
}
}
function stop_bot(id) {
if (connection.session) {
connection.session.call("com.myapp.stop_bot",
[id]).then(
connection.session.log,
connection.session.log);
} else {
console.log("no connection");
}
}
</script>
</body>
</html>

View File

@@ -1,83 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from twisted.python import log
from twisted.internet import protocol
from twisted.words.protocols import irc
class IRCClientProtocol(irc.IRCClient):
def connectionMade(self):
irc.IRCClient.connectionMade(self)
print "connected"
def connectionLost(self, reason):
irc.IRCClient.connectionLost(self, reason)
print "lost", reason
def signedOn(self):
print "signedon"
for channel in self.channels:
print "joining", channel
self.join(channel)
def joined(self, channel):
print "joined", channel
def privmsg(self, user, channel, msg):
# privmsg oberstet!~vanaland@89.204.139.245 #autobahn bot23: test
print "privmsg", user, channel, msg
self.factory.session.publish('com.myapp.on_privmsg', user, channel, msg)
def action(self, user, channel, msg):
print "action", user, channel, msg
class IRCClientFactory(protocol.ClientFactory):
def __init__(self, session, nickname, channels):
self.session = session
self.proto = None
self.nickname = str(nickname)
self.channels = [str(c) for c in channels]
def buildProtocol(self, addr):
assert(not self.proto)
self.proto = IRCClientProtocol()
self.proto.factory = self
self.proto.nickname = self.nickname
self.proto.channels = self.channels
return self.proto
def clientConnectionLost(self, connector, reason):
# connector.connect()
self.proto = None
def clientConnectionFailed(self, connector, reason):
# from twisted.internet import reactor
# reactor.stop()
self.proto = None

View File

@@ -1,131 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from __future__ import absolute_import
from twisted.internet.defer import inlineCallbacks
from twisted.internet.endpoints import clientFromString
from twisted.words.protocols import irc
from autobahn import wamp
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError
from wampirc.client import IRCClientFactory
class Bot:
"""
Tracks currently running bot instances.
"""
def __init__(self, id, factory, client):
self.id = id
self.factory = factory
self.client = client
class IRCComponent(ApplicationSession):
"""
IRC bot services component.
"""
def __init__(self, config):
ApplicationSession.__init__(self)
self.config = config
self._bots = {}
self._bot_no = 0
@wamp.register('com.myapp.start_bot')
def start_bot(self, nick, channels):
self._bot_no += 1
id = self._bot_no
factory = IRCClientFactory(self, nick, channels)
from twisted.internet import reactor
client = clientFromString(reactor, self.config.extra['server'])
d = client.connect(factory)
def onconnect(res):
self._bots[id] = Bot(id, factory, client)
return id
d.addCallback(onconnect)
return d
@wamp.register('com.myapp.stop_bot')
def stop_bot(self, id):
if id in self._bots:
f = self._bots[id].factory
if f.proto:
f.proto.transport.loseConnection()
f.stopFactory()
del self._bots[id]
else:
raise ApplicationError('com.myapp.error.no_such_bot')
@inlineCallbacks
def onJoin(self, details):
try:
regs = yield self.register(self)
print("Ok, registered {} procedures.".format(len(regs)))
except Exception as e:
print("Failed to register procedures: {}".format(e))
print("IRC Bot Backend ready!")
def onDisconnect(self):
reactor.stop()
def make(config):
if config:
return IRCComponent(config)
else:
# if no config given, return a description of this WAMPlet ..
return {'label': 'An IRC bot service component',
'description': 'This component provides IRC bot services via WAMP.'}
if __name__ == '__main__':
from autobahn.twisted.wamp import ApplicationRunner
extra = {
"server": "tcp:irc.freenode.net:6667"
}
# test drive the component during development ..
runner = ApplicationRunner(
url="ws://127.0.0.1:8080/ws",
realm="realm1",
extra=extra,
debug=False, # low-level WebSocket debugging
debug_wamp=False, # WAMP protocol-level debugging
debug_app=True) # app-level debugging
runner.run(make)

View File

@@ -1,4 +0,0 @@
wamplet1.egg-info
build
dist
*.pyc

View File

@@ -1,11 +0,0 @@
test:
python wamplet1/component1.py
install:
python setup.py install
clean:
find . -name "*.pyc" -exec rm -f {} \;
rm -rf dist
rm -rf build
rm -rf *.egg-info

View File

@@ -1,52 +0,0 @@
This folder contains a minimal skeleton of a **WAMPlet** application component.
A **WAMPlet** can be thought of a reusable application component that can be deployed dynamically as needed.
Get started by copying this folder and it's contents and begin by modifying a working base line.
> This example is using **Twisted**. You can find the **asyncio** variant [here](https://github.com/tavendo/AutobahnPython/tree/master/examples/asyncio/wamp/wamplet/wamplet1)
>
## WAMPlet Development
All the interesting bits with our application component are in [here](wamplet1/component1.py).
For development, start a locally running WAMP router, e.g. **Crossbar**.io:
```shell
cd $HOME
crossbar init
crossbar start
```
and in a second terminal run the file containing the application component:
```shell
python wamplet1/component1.py
```
## WAMPlet Installation and Distribution
For installation as a local WAMPlet in your Python package directory
```shell
python setup.py install
```
Installation of the WAMPlet allows **Crossbar**.io to find your WAMPlet even if no explicit Python paths are configured.
Above will also leave you an **.egg** file with your WAMPlet packaged up as a redistributable egg file that can be installed on other hosts. You can even publish your WAMPlet on the [Python Package Index](https://pypi.python.org).
To make *automatic WAMPlet discovery* work, the [Setup file](setup.py) contains an item
```python
entry_points = {
'autobahn.twisted.wamplet': [
'component1 = wamplet1.component1:make'
],
},
```
where `entry_points` must have an entry `autobahn.twisted.wamplet` that lists application components the package exposes.
Here, the factory function `make()` in the module `component1` in the package `wamplet1` is to be exposed as the WAMPlet `component1`.

View File

@@ -1,41 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from setuptools import setup, find_packages
setup(
name='wamplet1',
version='0.0.1',
description='A demo WAMPlet.',
platforms=['Any'],
packages=find_packages(),
entry_points={
'autobahn.twisted.wamplet': [
'component1 = wamplet1.component1:make'
],
},
zip_safe=False,
)

View File

@@ -1,49 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
from autobahn import wamp
class Calculator(object):
"""
An application component registering RPC endpoints using decorators.
"""
@wamp.register('com.mathservice.add2')
def add2(self, x, y):
return x + y
@wamp.register('com.mathservice.mul2')
def mul2(self, x, y):
return x * y
@wamp.register('com.mathservice.div2')
def square(self, x, y):
if y:
return float(x) / float(y)
else:
return 0

View File

@@ -1,97 +0,0 @@
###############################################################################
#
# The MIT License (MIT)
#
# Copyright (c) Tavendo GmbH
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
###############################################################################
import datetime
from twisted.internet.defer import inlineCallbacks
from autobahn.twisted.wamp import ApplicationSession
from calculator import Calculator
# WAMP application component with our app code.
##
class Component1(ApplicationSession):
@inlineCallbacks
def onJoin(self, details):
# register a function that can be called remotely
##
def utcnow():
now = datetime.datetime.utcnow()
return now.strftime("%Y-%m-%dT%H:%M:%SZ")
reg = yield self.register(utcnow, 'com.timeservice.now')
print("Procedure registered with ID {}".format(reg.id))
# create an application object that exposes methods for remoting
##
self.calculator = Calculator()
# register all methods on the "calculator" decorated with "@wamp.register"
##
results = yield self.register(self.calculator)
for success, res in results:
if success:
print("Ok, registered procedure with registration ID {}".format(res.id))
else:
print("Failed to register procedure: {}".format(res.value))
def onDisconnect(self):
reactor.stop()
def make(config):
##
# This component factory creates instances of the
# application component to run.
##
# The function will get called either during development
# using the ApplicationRunner below, or as a plugin running
# hosted in a WAMPlet container such as a Crossbar.io worker.
##
if config:
return Component1(config)
else:
# if no config given, return a description of this WAMPlet ..
return {'label': 'Awesome WAMPlet 1',
'description': 'This is just a test WAMPlet that provides some procedures to call.'}
if __name__ == '__main__':
from autobahn.twisted.wamp import ApplicationRunner
# test drive the component during development ..
runner = ApplicationRunner(
url="ws://127.0.0.1:8080/ws",
realm="realm1",
debug=False, # low-level WebSocket debugging
debug_wamp=False, # WAMP protocol-level debugging
debug_app=True) # app-level debugging
runner.run(make)