I'm using WebSockets in the Tornado Framework and can't get the data in a html form to be sent to a tornado class.
This is my code:
class MainHandler(tornado.web.RequestHandler):
event = []
def get(self):
self.render('main.html')
def post(self):
MainHandler.event = self.get_argument('event')
When I try and send event to a WebSocketHandler class. no data is received from the form:
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print "tailing..."
db = Connection().blah
coll = db.blah_tail
event = MainHandler.event
print 'Filtered', event
'Filtered' just prints an empty list: "Filtered []".
The html form:
<form action="/" method="post">
<input type="text" name="event" />
<input type="submit" id="open" value="Submit Query" />
</form>
How could you send the form data to the WSHandler class?
Thanks
The js for creating the websocket:
<script>
$(document).ready(function() {
var ws;
$("#open").click(function(evt){
evt.preventDefault();
ws = new WebSocket("ws://" + "localhost" + ":" + "8888" + "/ws");
ws.onmessage = function(evt) $("#display").append(evt.data + "<br />");
ws.onclose = function(evt) {alert("Server connection terminated");};
});
});
</script>
Just like in the example from the Tornado documentation, I'll use a set
for the WebSocket clients. Improving this is left as an exercise for the reader.
# clients listing on the WebSocket
clients = set()
class MainHandler(tornado.web.RequestHandler):
def get(self):
return self.render("index.html")
def post(self):
global clients
event = self.get_argument("event")
print "got event", event
if not clients:
print "No WebSockets, no point in querying the database"
return
for coordinate in self.get_coordinates(event):
for client in clients:
print "sending coordinate", coordinate, "to client", client
client.write_message(json.dumps(coordinate,
default=json_util.default))
def get_coordinates(self, event):
# replace with a real database query
for coordinate in ("No", "man's", "land"):
time.sleep(1)
yield coordinate
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
global clients
print "WebSocket opened..."
clients.add(self)
def on_close(self):
global clients
print "WebSocket closed..."
clients.remove(self)
The relevant part of the index.html
template:
<script type="text/javascript">
$(document).ready(function() {
var ws;
// open WebSocket for getting the results
ws = new WebSocket("ws://" + location.host + "/ws");
ws.onmessage = function(evt) {
$("#display").append(evt.data + "<br>");
};
ws.onclose = function(evt) {alert("Server connection terminated");};
$("#open").click(function(evt) {
evt.preventDefault();
$.post("/", $("#eventForm").serialize());
});
});
</script>
</head>
<body>
<h1>Event follower</h1>
<h2>Enter the event you would like to follow</h2>
<form id="eventForm" action="/" method="post">
<input type="text" name="event" />
<input type="submit" id="open" value="Submit Query" />
</form>
<h2>Coordinates</h2>
<div id="display">
</div>
</body>
When the page is loaded, a WebSocket connection is made to the server to the WSHandler
class and the client is added to the clients
set. When the page is closed, the WebSocket connection is closed and the server will remove it from the set.
When the open submit button is clicked, the form will be submitted asynchronously using AJAX to MainHandler.post
. The method will find out the coordinates related to that event and send them to the listening clients as they come it. The browser receives each coordinate and it appends it to the display div
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With