最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

connecting python to javascript for two-direction communication - Stack Overflow

programmeradmin0浏览0评论

I would like to serve queries from a javascript code by python. But I am not experienced in this field at all. What I would like to build is something like this:

1. request.js:

open_connection('server.py');
for (var i=0; i<10; i++)
    document.write(request_next_number());
close_connection('server.py')

2. server.py

x = 0
while connected:
    if request:
        send(x)
        x = x + 1

I heard about JSON, but don't know if I should use it. (?)

Could you please give me some code examples or guides how to implement the two files above?

I would like to serve queries from a javascript code by python. But I am not experienced in this field at all. What I would like to build is something like this:

1. request.js:

open_connection('server.py');
for (var i=0; i<10; i++)
    document.write(request_next_number());
close_connection('server.py')

2. server.py

x = 0
while connected:
    if request:
        send(x)
        x = x + 1

I heard about JSON, but don't know if I should use it. (?)

Could you please give me some code examples or guides how to implement the two files above?

Share Improve this question asked Aug 14, 2013 at 13:42 gengen 10k14 gold badges37 silver badges66 bronze badges 4
  • 2 You're looking for websockets. – SLaks Commented Aug 14, 2013 at 13:43
  • Why would you use python? Use node.js. – user1786283 Commented Aug 14, 2013 at 14:09
  • @enginefree - you may prefer node.js but many people use python as the back end. – tdelaney Commented Aug 14, 2013 at 15:53
  • @enginefree Yes, I might use that, however the core part of my code which is course not what the example is here, has been already written, thus I wouldn't change to node.js, which I don't know at all – gen Commented Aug 14, 2013 at 16:02
Add a comment  | 

2 Answers 2

Reset to default 10

What you need is a socket server on the python end and a client/request server on the javascript end.

For the python server side, refer to SocketServer, (example taken from there as well), one thing you have to make sure is to have the socket go past NAT (possibly port forwarding). One other alternative is Twisted which is a very powerful framework, i believe it has functionality to send data through NAT.

import SocketServer

class MyTCPHandler(SocketServer.BaseRequestHandler):
    """
    The RequestHandler class for our server.

    It is instantiated once per connection to the server, and must
    override the handle() method to implement communication to the
    client.
    """

    def handle(self):
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        print "{} wrote:".format(self.client_address[0])
        print self.data
        # just send back the same data, but upper-cased
        self.request.sendall(self.data.upper())

if __name__ == "__main__":
    HOST, PORT = "localhost", 9999

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    server.serve_forever()

On the JavaScript there are many frameworks that allow socket connections, here are a few

  • Socket IO

Example:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>
  • You can even use HTML5 Web Sockets

Example:

var connection = new WebSocket('ws://IPAddress:Port');
connection.onopen = function () {
  connection.send('Ping'); // Send the message 'Ping' to the server
};
  • Also, take a look at a part of this book , Chapter 22 of Javascript: The Definitive Guide , https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-22/web-sockets

  • Finally, take a look at jssockets

Example:

_jssocket.setCallBack(event, callback);
_jssocket.connect(ip,port);
_jssocket.write(message);
_jssocket.disconnect();

Hope this help!

An example with Web Socket that i have used to transfer image to a web server and stream my screen.

stream.html

<!DOCTYPE HTML>
<meta charset = utf-8>

<html>
    <header>
        <title>Stream</title>
        <script type="text/javascript" src="js/request.js"></script>
    </header>
    <body onload="doLoad()">
        <div id="canvasWrapper">
            <canvas id="display"></canvas>
        </div>
    </body>
</html>

request.js

var disp;
var dispCtx;
var im;
var ws;

function doLoad() {
    disp = document.getElementById("display");
    dispCtx = disp.getContext("2d");
    im = new Image();
    im.onload = function() {
    disp.setAttribute("width", im.width);
    disp.setAttribute("height", im.height);
    dispCtx.drawImage(this, 0, 0);
  };
    im.src = "img/img_not_found.png";
    ws = new WebSocket("ws://127.0.0.1:50007");
    ws.onmessage = function (evt) {
        im.src = "data:image/png;base64," + evt.data;
    }
}

server.py

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
import base64
import sys
from twisted.python import log
from twisted.internet import reactor

class MyServerProtocol(WebSocketServerProtocol):

    def onConnect(self, request):
        print("Client connecting: {}".format(request.peer))

    def onOpen(self):
        print("WebSocket connection open.")

        def hello():
            with open("/var/www/html/img/image.png", "rb") as image_file:
                encoded_string = base64.b64encode(image_file.read())
            self.sendMessage(encoded_string.encode('utf8'))
            self.factory.reactor.callLater(0.2, hello)

        # start sending messages every 20ms ..
        hello()

    def onMessage(self, payload, isBinary):
        if isBinary:
            print("Binary message received: {} bytes".format(len(payload)))
        else:
            print("Text message received: {}".format(payload.decode('utf8')))

        # echo back message verbatim
        self.sendMessage(payload, isBinary)

    def onClose(self, wasClean, code, reason):
        print("WebSocket connection closed: {}".format(reason))


if __name__ == '__main__':
    log.startLogging(sys.stdout)

    factory = WebSocketServerFactory(u"ws://127.0.0.1:50007")
    factory.protocol = MyServerProtocol
    # factory.setProtocolOptions(maxConnections=2)

    # note to self: if using putChild, the child must be bytes...

    reactor.listenTCP(50007, factory)
    reactor.run()

You will need autobahn (you can install it with pip install autobahn)

发布评论

评论列表(0)

  1. 暂无评论