Im pretty new to Autobahn and WAMP (Web Apps Messaging Protocol).
Im just creating a simple Application Component based on http://autobahn.ws/python/wamp/programming.html and https://github.com/crossbario/crossbarexamples/blob/master/votes/python/votes.py
Below is my Server side Python
from autobahn.asyncio.wamp import (
ApplicationSession,
ApplicationRunner
)
from autobahn import wamp
from asyncio import coroutine
class MyComponent(ApplicationSession):
#wamp.register("com.myapp.add2")
def add2(self, x, y):
print("added 2")
return x + y
#wamp.register("com.myapp.add3")
def add3(self, x, y, z):
print("added 3")
return x + y + z
#coroutine
def onJoin(self, details):
res = yield from self.register(self)
print("{} procedures registered.".format(len(res)))
if __name__ == '__main__':
runner = ApplicationRunner(url="ws://localhost:8080/ws", realm="realm1")
runner.run(MyComponent)
and the Client side
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>AUTOBAHN_DEBUG = false;</script>
<script src="http://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz"></script>
<script>
var connection = new autobahn.Connection({
url: "ws://localhost:8080/ws",
realm: "realm1"
});
connection.onopen = function (session, details) {
session.call("com.myapp.add2", [2,3]).then(session.log);
session.call("com.myapp.add3", [2,3,4]).then(session.log);
};
connection.onclose = function (reason, details) {
console.log("Connection lost: " + reason);
};
connection.open();
</script>
</body>
</html>
Error
Looks like this is similar to https://github.com/hwmrocker/hextest/issues/2 but I can't get my head around. I can't even find a sample that works. This one (https://github.com/tavendo/AutobahnPython/tree/master/examples/asyncio/wamp/wamplet/wamplet1) is similar but it has the same issue as well.
Surprisingly, when I run an external Crossbar sample on the same Port and run the above example, it works like a magic and I can see the results on the console.
I found this one (https://github.com/tavendo/AutobahnPython/blob/master/examples/asyncio/wamp/basic/server.py) but it looks quite complicated.
Please help me out.
Thank you in Advanced.
Your code works for me without modification:
Your app consists of 2 WAMP application components: a browser side (using AutobahnJS), and a server side (using AutobahnPython/Python3/asyncio).
For these 2 components to talk to each other, both components need to connect to a WAMP router. I used Crossbar.io.
Note that your Python component is logically a server-side component, but it is not technically a server: it does not open a listening port or what, but it connects to a WAMP router.
Related
I have a flask app that is running selenium on a VM server. I am running a long looping function, and I want to alert the user on the client side if the driver have reached certain points while scrawling (because the function runs in a very long loop, it's not possible afaik to use flask flash without returning redirect or render_template)
This why I think socketio is my only option.
What I have currently is:
Snippet from routes.py (trying to connect a driver)
#app.route("/", methods=["GET", "POST"])
#login_required
def index():
if request.method == "POST":
try:
globals()["driver_" + str(user_id)] = uc.Chrome(options=chrome_options, use_subprocess=True)
What I want to achieve:
try:
globals()["driver_" + str(user_id)] = uc.Chrome(options=chrome_options, use_subprocess=True)
message = "Driver connected succssefully"
socket.emit('send-message', message)
I have the following in layout.html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf-8">
var socket = io();
socket.on('connect', function() {
console.log('initSocketIO');
});
socket.on('send-message', (message) => {
console.log(message);
});
</script>
I can see in the console initSocketIO but how do I set it up that I will also see send-message data ("Driver connected succssefully") on the console?
I 've searched here for similar problems but couldn't find an exact answer. I'm definately no socketio specialist, so please forgive me in advance...
To put it simple and in short: when I perform send() from my server (py script) preceded by a '#socket.on('message')' all is received fine on the client side. However when I use emit() on a manually triggered def, nothing is shown on client side.
Here is my simplified code:
server - app.py
app=Flask(__name__) app.config["SECRET_KEY"]="secretkey"
socket = SocketIO(app, logger=True)
somelist = ["el1", "el2", "el3", "el4"]
i=0
#app.route("/") def main():
return render_template("main.html")
#app.route("/test2")
def test2():
print("called test2")
manual_callback("note 1")
#socket.on('message')
def handlemsg(msg):
global i
if i < len(somelist):
socket.send(somelist[i] + " - " + msg)
i+=1
def manual_callback(note):
print("manual_callback triggered")
socket.emit('updateData', {"data": "this the data to show - " + note}, namespace="/test2")
print("trigger done")
if __name__ == "__main__":
socket.run(app)
Client - main.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js"></script>
<script>
socket = io();
socket.connect('http://' + document.domain + ':' + location.port);
socket.on('updateData',function(data){
console.log('called updateData');
console.log(data);
console.log('ended call');
})
socket.on('connect',function(){
console.log('CONNECT');
socket.send('a');
})
socket.on('message',function(msg){
console.log(msg);
socket.send('b');
})
</script>
</head>
<body>
<h1>test</h1>
</body>
</html>
What works fine:
After connecting, 'socket.on('connect',...) is triggered in main.html and 'CONNECT' is printed in the browser log followed by the 4 elements in somelist.
What doesn't work like I would expect:
After navigating to localhost/test2, def manual_callback() is called. So I would expect that on client side, 'socket.on('updateData'...)' gets triggered and messages 'called UpdateData', 'this the data to show - note 1' and 'ended call' appear in the browser's log. But the latter does not seem to happen.
What am I doing wrong here?
Thank you in advance.
So I'm trying to make a problem for a ctf, and for a problem, I need to send data from a python script to the javascript. Can anyone tell me how?
My html code is:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1 class="text">text</h1>
<script>
$.get("[website]/cgi-bin/challenge.py",
function(data) {
$(".text").html(data);
});
</script>
</body>
</html>
I replaced the website with [website].
The python code is like this:
#!/usr/bin/python
import json
print "Content-type: text/html\n\n"
json.dumps("It works!")
#!/usr/bin/python
import json
text = json.dumps("It works!")
print "Content-Type: application/json\n"
print text
you can try: https://www.zerorpc.io/ , zerorpc is a communication between server-side processes that lets you transfer data from a server to a client.
in your situation, if you want to transfer data from python to node.js you cand do it like this:
in your python file as a server do:
import zerorpc
class HelloRPC(object):
def hello(self, name):
return "Hello, %s" % name
s = zerorpc.Server(HelloRPC())
s.bind("tcp://0.0.0.0:4242")
s.run()
and in your node.js code as a client:
var zerorpc = require("zerorpc");
var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");
client.invoke("hello", "RPC", function(error, res, more) {
console.log(res);
});
this will print "hello RPC" on the console.
I'm trying to get Server Sent Events to work from Python, so I found a little demo code and to my surprise, it only partly works and I can't figure out why. I got the code from here and put in just a couple little changes so I could see what was working (I included a print statement, an import statement which they clearly forgot, and cleaned up their HTML to something I could read a little easier). It now looks like this:
# Bottle requires gevent.monkey.patch_all() even if you don't like it.
from gevent import monkey; monkey.patch_all()
from gevent import sleep
from bottle import get, post, request, response
from bottle import GeventServer, run
import time
sse_test_page = """
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js "></script>
<script>
var es = new EventSource("/stream");
es.onmessage = function(e) {
document.getElementById("log").innerHTML = e.data;
}
</script>
</head>
<body>
<h1>Server Sent Events Demo</h1>
<p id="log">Response Area</p>
</body>
</html>
"""
#get('/')
def index():
return sse_test_page
#get('/stream')
def stream():
# "Using server-sent events"
# https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events
# "Stream updates with server-sent events"
# http://www.html5rocks.com/en/tutorials/eventsource/basics/
response.content_type = 'text/event-stream'
response.cache_control = 'no-cache'
# Set client-side auto-reconnect timeout, ms.
yield 'retry: 100\n\n'
n = 1
# Keep connection alive no more then... (s)
end = time.time() + 60
while time.time() < end:
yield 'data: %i\n\n' % n
print n
n += 1
sleep(1)
if __name__ == '__main__':
run(server=GeventServer, port = 21000)
So here's what ends up happening: I can see the original header and paragraph on the website, but response area never changes. On the python side, it prints n once per second, but I never see that change on the web page. I get the feeling that I just lack a fundamental understanding of what I'm trying to do but I can't find anything missing.
I'm running Python 2.7, windows 7, chrome 43.0.2357.81 m.
EDIT: I got rid of the extra quotation mark. Now it only seems to update when it gets to 60 (which I guess is better than not at all...)
Why would it wait until the end of the function to send the event?
You've got 2 sets of quotes after p id="log""
Test case implemented with Python and CherryPy:
import cherrypy, time
class Root():
#cherrypy.expose
def index(self):
return r'''<!DOCTYPE html>
<html>
<head>
<title>Server-sent events test</title>
<style>html,body,#test{height:98%;}</style>
</head>
<body>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
var source = new EventSource('gettime');
source.addEventListener('time', function (event) {
document.getElementById('test').innerHTML += event.data + "\n";
});
source.addEventListener('error', function (event){
console.log('SSE error:', event);
console.log('SSE state:', source.readyState);
});
}, false);
</script>
<textarea id="test"></textarea>
</body>
</html>'''
#cherrypy.expose
def gettime(self):
cherrypy.response.headers["Content-Type"] = "text/event-stream"
def generator():
while True:
time.sleep(1)
yield "event: time\n" + "data: " + str(time.time()) + "\n\n"
return generator()
gettime._cp_config = {'response.stream': True}
if __name__ == '__main__':
cherrypy.config.update({'server.socket_host': '0.0.0.0'})
cherrypy.quickstart(Root())
After receiving some messages successfully I manually drop the connection, then in Firefox' web console appears JS Error: The connection to http://localhost:8080/gettime was interrupted while the page was loading.
According to the spec, Clients will reconnect if the connection is closed, but Firefox doesn't. Error event handler reports that the source is in CLOSED state.
CLOSED (numeric value 2)
The connection is not open, and the user agent is not trying to reconnect. Either there was a fatal error or the close() method was invoked.
So there was a fatal error?
In Chromium it works, error handler reports that the source is in CONNECTING (0) state (as it should) and connection is automatically restored within a few seconds
Have tried Firefox 26, Firefox 24 ESR and Iceweasel 17 on Linux and Windows platforms, all the same
Have checked raw protocol and headers, looks ok
Have tried to add retry: 3000 to each sent event
Have tried to move JavaScript out of event listener and wrapping it into setTimeout
The bug is fixed in Firefox 36.
The spec on this stuff is in flux and there is a number of open spec issues related to the reconnection behavior that the spec proposes. I wouldn't rely on any specific reconnection behavior until the spec stabilizes a lot more than it has so far.