Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML form data not received by Tornado class

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>
like image 792
user94628 Avatar asked Nov 10 '12 17:11

user94628


1 Answers

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.

like image 110
Cristian Ciupitu Avatar answered Sep 23 '22 19:09

Cristian Ciupitu