Google Apps HTTP Streaming with Python question - javascript

I got a little question here:
Some time ago I implemented HTTP Streaming using PHP code, something similar to what is on this page:
http://my.opera.com/WebApplications/blog/show.dml/438711#comments
And I get data with very similar solution. Now I tried to use second code from this page (in Python), but no matter what I do, I receive responseText from python server after everything completes. Here are some python code:
print "Content-Type: application/x-www-form-urlencoded\n\n"
i=1
while i<4:
print("Event: server-time<br>")
print("data: %f<br>" % (time.time(),))
sys.stdout.flush()
i=i+1
time.sleep(1)
And here is Javascript Code:
ask = new XMLHttpRequest();
ask.open("GET","/Chat",true);
setInterval(function()
{
if (ask.responseText) document.write(ask.responseText);
},200);
ask.send(null);
Anyone got idea what I do wrong ? How can I receive those damn messages one after another, not just all of them at the end of while loop? Thanks for any help here!
Edit:
Main thing I forgot to add: server is google app server (i'm not sure is that google own implementation), here is a link with some explanation (i think uhh):
http://code.google.com/intl/pl-PL/appengine/docs/python/gettingstarted/devenvironment.html
http://code.google.com/intl/pl-PL/appengine/docs/whatisgoogleappengine.html

Its highly likely App Engine buffers output. A quick search found this: http://code.google.com/appengine/docs/python/tools/webapp/buildingtheresponse.html
The out stream buffers all output in memory, then sends the final output when the handler exits. webapp does not support streaming data to the client.

That looks like a cgi code - I imagine the web server buffers the response from the cgi handlers. So it's really a matter of picking the right tools and making the right configuration.
I suggest using a wsgi server and take advantage of the streaming support wsgi has.
Here's your sample code translated to a wsgi app:
def app(environ, start_response):
start_response('200 OK', [('Content-type','application/x-www-form-urlencoded')])
i=1
while i<4:
yield "Event: server-time<br>"
yield "data: %f<br>" % (time.time(),)
i=i+1
time.sleep(1)
There are plenty of wsgi servers but here's an example with the reference one from python std lib:
from wsgiref.simple_server import make_server
httpd = make_server('', 8000, app)
httpd.serve_forever()

Related

How do I get my Python file to print in the terminal instead of in the server it sets up?

I am running a bit of a complicated setup where several files interact with each other:
a python file, setting up a server, which is used to connect two users online
a combination of js and html files to set up the web page that each user interacts with
So each user interacts with the js files, which in turn send a message to the python file, which reacts by sending the appropriate response to the js files on the other user’s end, etc.
To launch all this, I simply open the python file in my terminal — thus opening up the websockets — and then I type in the address of my html file on my browser. I know the functions in my python file are executing correctly because the interaction does work on my browser, however, none of the prints in the functions show up on my terminal…
So for example, in the python file:
def message_received(client, server, message):
print("Client(%d) said: %s" % (client['id'], message))
response = json.loads(message)
response_code = response['response_type']
handle_client_response(client['id'], response_code, response)# another function defined elsewhere
PORT = 9004
print('starting up')
server = WebsocketServer(PORT, '0.0.0.0')# this is calling the actual server set up from another file, which I didn 't write myself.
server.set_fn_message_received(message_received)
server.run_forever()
The "starting up" is the only thing that will actually print, the print in message_received doesn't show up, even though I know for a fact the function is working because handle_client_response is called correctly.
My guess is this is because the function are not actually executed on the terminal, but on the server that I set up, so python is trying to print in the server instead of the terminal. But also I have no idea what I’m talking about — first time I ever do this type of complicated files interaction so I’m very confused!
Am I guessing the problem correctly? Any fix for it?
Try maybe using a library like logging to handle the print of messages. That way, you can specify where the log messages should be written to.
import logging
logging.basicConfig(level=logging.DEBUG)
def message_received(client, server, message):
logging.debug("Client(%d) said: %s" % (client['id'], message))
response = json.loads(message)
response_code = response['response_type']
handle_client_response(client['id'], response_code, response)
Hopefully this will fix it.

Saving a socket that connected to later send them a message

I have set up a Flask server with JavaScript browser clients connecting to it via websockets.
I am curious for if I can save a certain socket somewhere in python so that I can emit messages to it specifically.
I haven't tried doing anything, but I can't find any info on what I would like to do.
There's no code to provide...
I expected to be able to do something like:
all_sockets = []
#socketio.on('connection')
def on_connect(socket, json, methods=['GET', 'POST']):
all_sockets.append(socket)
def whisper(socket, message)
socket.emit({"data": message})
whisper(all_sockets[1], "Test")
Much like in node.js's version of websockets it is...
The answer which pretty much solves this I feel is here: flask socketio emit to specific user
I thought I would be able to save the "socket", but that was a somewhat weird line of thought.
I need some more text so I can reply to myself and mark this as a solution to this question so nobody else has to reply to this emberassment.

Keeping Web Socket Server Alive

Zup coders. I've implemented a simple website that uses Web Sockets PHP (Consik Yii2 solution: https://github.com/consik/yii2-websocket) vs JS (Html5).
Everything is working fine, I only have one issue with my solution, making sure the server is always alive.
I though about saving the WebSocket Instance into Cache and throw a cron that checks the state of the instance. I installed memcached and found out that i can´t save a serialized version of the WebSocket Server instance. ¿Is this a good solution? ¿Would Redis Caché fix this?
I also thought about using client side JS to react to "Error during WebSocket handshake: Unexpected response code: 200" but i can't seem to get it working. I also don't like making the URL that starts websockets public.
Ex:
connect = function(){
websocket = new WebSocket(webSocketURL);
websocket.onerror = function(){
$.get( "/startWebSocketServer",
function(data){
connect();
}
);
};
};
connect();
Thanks!
I think that as matter of fact you need a process supervisor who takes care to "supervise" your server process and do actions in response of process/system events like crash, restart etc..
There are several solutions for each case (standard OS implementations, personal preferences, fit your need), here a list http://without-systemd.org/wiki/index.php/Init , Service managers section could best fit your needs.
Supervisord is easy to setup and configure, it could be a good start thanks to a good bunch of examples around the net.
Solution 1: using a cache could not be the most orthodox way to implement a custom-made supervisor.
Solution 2: is legit as long as it informs user about a problem, the call to an exposed endpoint to start a service IMHO could be a security flaw.

Calling node.js script from PHP returns nothing

What I want to do is simple in theory, but I cannot quite get it to work.
I wrote a simple node.js script that uses the request package to asynchronously fetch some data, parse it, and spit it out as html. I wanted to integrate this script in my client's php and apache based website which is on a shared host, and ran into some snags:
There is no mod_proxy, so I can't simply run my node script as a server and proxy through Apache
I don't want to run node on port 80 and proxy to apache from node. It's just way too much overkill for what I need to do, and would introduce too many headaches for me. My particular shared host is known to have trouble keeping node server instances up, and I can't justify potential downtime just for this script to run.
I tried the node-cgi package but it didn't work for me. I got errors about internal node methods not existing, I think this package is just out of date.
So what I have landed on is trying to simply call node from PHP. My whole index.php file is:
<?php
header("Content-Type: text/html");
exec("node beerlist.nd", $output);
echo implode('', $output);
When I execute php index.php on the command line, I get my expected output, however, when I try to access this from the browser, I get nothing ie Content-Length: 0. Why?
I thought maybe it had to do with the async nature of my node script but it seems like the process stays alive until it finishes all the async calls. So shouldn't my php snippet send the output to the browser without any trouble? What am I missing here?
Edit: This gist of my node script is
var req = require('request')
req("http://mywebsite.com", function(err, resp, body) {
var output = // pull some interesting pieces out of the whole body
console.log(output);
});
The generation of my output variable is not central to the issue here. The relevant parts are that I use request to make an asynchronous call and use console.log to output my results... maybe this is a problem?
I suppose Apache user doesn't know what node command is. If I'm right try to write in php file:
<full path to node> beerlist.nd
instead of
node beerlist.nd
To get full path to node run in terminal which node

PHP minimal working example of Web Sockets

I'm trying to determine how to setup a web socket for the first time ever so a working minimal example with static variables (IP address for example instead of getservbyname) will help me understand what is flowing where.
I want to do this the right way so no frameworks or addons for both the client and the server. I want to use PHP's native web sockets as described here though without over-complicating things with in-depth classes...
http://www.php.net/manual/en/intro.sockets.php
I've already put together some basic JavaScript...
window.onload = function(e)
{
if ('WebSocket' in window)
{
var socket = new WebSocket('ws://'+path.split('http://')[1]+'mail/');
socket.onopen = function () {alert('Web Socket: connected.');}
socket.onmessage = function (event) {alert('Web Socket: '+event.data);}
}
}
It's the PHP part that I'm not really sure about. Presuming we have a blank PHP file...
If necessary how do I determine if my server's PHP install has this socket functionality already available?
Is the request essentially handled as a GET or POST request in
example?
Do I need to worry about the port numbers? e.g. if
($_SERVER['SERVER_PORT']=='8080')
How do I return a basic message on the initial connection?
How do I return a basic message say, five seconds later?
It's not that simple to create a simple example, I'm afraid.
First of all you need to check in php configuration if the server is configured for sockets with the setting enable-sockets
Then you need to implement (or find) a websocket server that at least follows the Hybi10 specification (https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10) of websockets. If you find the "magic number" 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 in the code for the header, you can be sure it does follow at least Hybi06 ...
Finally, you need to have access to an admin console on the server in order to execute the PHP websocket server using php -q server.php
EDIT: This is the one I've been using a year ago ... it might still work as expected with current browsers supporting Websockets: http://code.google.com/p/phpwebsocket/source/browse/trunk/+phpwebsocket/?r=5

Categories