Websocket closes immediately - javascript

https://github.com/tiasimoneriley/pulse
So i am trying to make this code run to get the pulses, however the connection to Websocket is immediatly closed and I don't understand why.
It closing right away is not letting the frames of the video get computed to get the pulses.
Also, I am new to this whole thing so if anyone can figure it out please tell me whats wrong.
Thank you.
This is what my console shows
websocket open! websocket.js:5
closed websocket.js:22
T1 camera.js:70
T2 camera.js:76
T3 camera.js:82
T4 camera.js:84
T5 camera.js:86
begin startCapture() camera.js:397
T6 camera.js:88
WebSocket is already in CLOSING or CLOSED state. websocket.js:18
WebSocket is already in CLOSING or CLOSED state. websocket.js:18
Here is the
app.py
import json
import os
from flask import Flask, render_template
from flask_sockets import Sockets
import model
app = Flask(__name__)
sockets = Sockets(app)
#app.route("/")
def index():
return render_template("splash.html")
#app.route("/begin")
def get_heartrate():
return render_template("index.html")
#sockets.route('/echo')
def echo_socket(ws):
while True:
message = json.loads(ws.receive())
signals = model.parse_RGB(message)
ws.send(signals)
if __name__ == "__main__":
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler
port = int(os.environ.get('PORT', 5000))
print("Hosting on port {}".format(port))
server = pywsgi.WSGIServer(('', port), app, handler_class=WebSocketHandler)
server.serve_forever()
and this is the websocket.js
var dataSocket = new WebSocket(location.protocol.replace("http", "ws") + location.host + "/echo");
dataSocket.onopen = function(){
console.log("websocket open!");
console.log(dataSocket);
}
dataSocket.onmessage = function(e){
var data = JSON.parse(e.data);
if (data.id === "ICA"){
camera.cardiac(data.array, data.bufferWindow);
}
}
function sendData(data){
dataSocket.send(data);
}
dataSocket.onclose = function(){
console.log('closed');
}

Related

Video is freezed while video streaming

I find the following code for streaming video over a socket in python2.7. When I run it, the video will be freeze at the beginning in the server-side (It shows the video in a web browser). I debugged the code and understood that in the streamer.py, the third while loop condition creates an infinite loop because of the condition while len(data) < msg_size: is always satisfied. In other words, len(data) is always less than msg_size.So, the streamer.py does not return the image to the server.py. Could anyone help me to solve this issue?
The server.py is:
from flask import Flask, render_template, Response
from streamer import Streamer
app = Flask(__name__)
def gen():
streamer = Streamer('localhost', 8089)
streamer.start()
while True:
if streamer.client_connected():
yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' +
streamer.get_jpeg() + b'\r\n\r\n')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/video_feed')
def video_feed():
return Response(gen(), mimetype='multipart/x-mixed-replace;
boundary=frame')
if __name__ == '__main__':
app.run(host='localhost', threaded=True)
The streamer.py is:
import threading
import socket
import struct
import StringIO
import json
import numpy
class Streamer (threading.Thread):
def __init__(self, hostname, port):
threading.Thread.__init__(self)
self.hostname = hostname
self.port = port
self.connected = False
self.jpeg = None
def run(self):
self.isRunning = True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.bind((self.hostname, self.port))
print 'Socket bind complete'
data = ""
payload_size = struct.calcsize("L")
s.listen(10)
print 'Socket now listening'
while self.isRunning:
conn, addr = s.accept()
print 'while 1...'
while True:
data = conn.recv(4096)
print 'while 2...'
if data:
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:# the infinite loop is here(my problem)!
data += conn.recv(4096)
print ("lenght of data is " , len(data) )
print ("message size is " , msg_size )
frame_data = data[:msg_size]
#frame_data = data[:len(data)]
memfile = StringIO.StringIO()
memfile.write(json.loads(frame_data).encode('latin-1'))
memfile.seek(0)
frame = numpy.load(memfile)
ret, jpeg = cv2.imencode('.jpg', frame)
self.jpeg = jpeg
self.connected = True
print 'recieving...'
else:
conn.close()
self.connected = False
print 'connected=false...'
break
self.connected = False
def stop(self):
self.isRunning = False
def client_connected(self):
return self.connected
def get_jpeg(self):
return self.jpeg.tobytes()
Client.py is:
import socket
import sys
import pickle
import struct
import StringIO
import json
import time
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while(cap.isOpened()):
ret,frame=cap.read()
memfile = StringIO.StringIO()
np.save(memfile, fravidme)
memfile.seek(0)
data = json.dumps(memfile.read().decode('latin-1'))
clientsocket.sendall(struct.pack("L", len(data))+data)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
I want to show the video captured by my laptop's camera on a client machine in the same network. I expect video stream but in the browser, I just watch an image and it does not update continuously.
As I analyzed this code I noticed that the default implementation for sending OpenCV frames over the network was not working. I decided to replace it with ZeroMQ implementation I have used before. You can check out the linked question for a deeper explanation of how the streaming works. I have neatly packaged it into classes, with unit tests and documentation as SmoothStream check it out too.
Coming back to the question, here is the working code.
client.py
import base64
import cv2
import zmq
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.connect('tcp://localhost:5555')
camera = cv2.VideoCapture(0) # init the camera
while True:
try:
grabbed, frame = camera.read() # grab the current frame
frame = cv2.resize(frame, (640, 480)) # resize the frame
encoded, buffer = cv2.imencode('.jpg', frame)
jpg_as_text = base64.b64encode(buffer)
footage_socket.send(jpg_as_text)
except KeyboardInterrupt:
camera.release()
cv2.destroyAllWindows()
break
server.py
from flask import Flask, render_template, Response
from streamer import Streamer
app = Flask(__name__)
def gen():
streamer = Streamer('*', 5555)
streamer.start()
while True:
if streamer.client_connected():
yield (b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + streamer.get_jpeg() + b'\r\n\r\n')
#app.route('/')
def index():
return render_template('index.html')
#app.route('/video_feed')
def video_feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='localhost', threaded=True)
streamer.py
import base64
import threading
import cv2
import numpy as np
import zmq
class Streamer(threading.Thread):
def __init__(self, hostname, port):
threading.Thread.__init__(self)
self.hostname = hostname
self.port = port
self.connected = False
self.jpeg = None
def run(self):
self.isRunning = True
context = zmq.Context()
footage_socket = context.socket(zmq.SUB)
footage_socket.bind('tcp://{}:{}'.format(self.hostname, self.port))
footage_socket.setsockopt_string(zmq.SUBSCRIBE, np.unicode(''))
while self.isRunning:
frame = footage_socket.recv_string()
img = base64.b64decode(frame)
npimg = np.fromstring(img, dtype=np.uint8)
source = cv2.imdecode(npimg, 1)
ret, jpeg = cv2.imencode('.jpg', source)
self.jpeg = jpeg
self.connected = True
self.connected = False
def stop(self):
self.isRunning = False
def client_connected(self):
return self.connected
def get_jpeg(self):
return self.jpeg.tobytes()
I understand that copy-pasting entire .py files are probably not the best way to post an answer here, but this is a complex question with a lot of moving parts and I honestly could not think of a better way to help the OP.

Session.cookies.get_dict() return an empty dictionary

So I'm setting a cookie on every page with this javascript code:
setTimeout(function(){
var pageStats = getCookie('PageStats');
var currentPage = {
"url": window.location.href,
"render_time": $('.render_time').html(),
"queries_number": $('.queries_number').html(),
"queries_time": $('.queries_time').html()
}
document.cookie = "PageStats=" + JSON.stringify(currentPage) + ";path=/";
}, 1000);
Then I try to get it via my python script:
import requests
session = requests.Session()
response = session.get('http://127.0.0.1:800/')
print(response.cookies.get_dict())
This returns {}, though I can see all cookies via browser.
What's wrong?
The cookies that you are trying to get are from the session of requests.Session(), not the browser. The reason this happens is because that JavaScript is only executed when the HTML is rendered by your browser. As requests does not render the HTML, but just sends a simple HTTP request, those cookies are not being set. The only way that I could see this working is if you set the cookies on the server-side. Here's a simple example using Python 3's Flask:
from flask import Flask, make_response
app = Flask(__name__)
#app.route("/")
def index():
r = make_response("Hello World")
r.set_cookie("flask-cookie", "this is some data in a cookie")
return r
if __name__ == "__main__":
app.run(port=8080)
Or if you use NodeJS's ExpressJS:
var express = require("express");
var app = express();
app.get("/", function(req, res) {
res.cookie("express-cookie", "this is some data in a cookie").send("Hello World");
});
app.listen(8080);

Trying to port my socketio client from js to python but it is not working

I have the following JS code that works great to connect to a socket via the socketio client library:
userApi = 'userapiaccesfskdglk';
userAccess = 'useaccesfjkasdfdlkf2';
var axios = require('axios');
var socket = require('socket.io-client')('wss://test-meownow12345.com:4566');
socket.emit('Authenticate', {api: userApi, access: userAccess});
socket.on('Party', function(party) {
console.log('party', party)
})
These are not the actual userApi, userAccess, or urls used, but using them still gets the same point across.
This is what i have in python, that to me looks like an exact port but is not working:
from socketIO_client import SocketIO, LoggingNamespace
import logging
logging.basicConfig(level=logging.DEBUG)
def on_party():
print('connect')
userApi = 'userapiaccesfskdglk'
userAccess = 'useaccesfjkasdfdlkf2'
with SocketIO('wss://test-meownow12345.com', 4566, LoggingNamespace) as socketIO:
socketIO.emit('Authenticate', {'api': userApi, 'access': userAccess})
socketIO.on('Party', on_party)
It seems like it is equivalent but it is clearly not as the code cannot get past the following line that opens the socket.io connection:
with SocketIO('wss://test-meownow12345.com', 4566, LoggingNamespace) as socketIO:
In my console it prints out the following log errors that just repeat:
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): wss
WARNING:socketIO-client:wss:4566//test-meownow12345.com/socket.io [engine.io waiting for connection] HTTPConnectionPool(host='wss', port=4566): Max retries exceeded with url: //test-meownow12345.com/socket.io/?EIO=3&transport=polling&t=1523668232386-0 (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x105000278>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known',))
I'm not really sure what this means.
I have tried changing the line giving this message and drop the 'wss://' part to make it:
with SocketIO('test-meownow12345.com', 4566, LoggingNamespace) as socketIO:
but this still fails, albeit with a new message in the logs that repeats:
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): test-meownow12345.com
WARNING:socketIO-client:test-meownow12345.com:4566/socket.io [engine.io waiting for connection] ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
DEBUG:urllib3.connectionpool:Starting new HTTP connection (2): test-meownow12345.com
DEBUG:urllib3.connectionpool:Starting new HTTP connection (3): test-meownow12345.com
Any help is really appreciated, this is quite a frustrating problem.
If you look at SocketIO class
class SocketIO(EngineIO):
It inherits from EngineIO which has __init__ as
class EngineIO(LoggingMixin):
def __init__(
self, host, port=None, Namespace=EngineIONamespace,
wait_for_connection=True, transports=TRANSPORTS,
resource='engine.io', hurry_interval_in_seconds=1, **kw):
self._is_secure, self._url = parse_host(host, port, resource)
self._wait_for_connection = wait_for_connection
And definition of parse_host is
def parse_host(host, port, resource):
if not host.startswith('http'):
host = 'http://' + host
url_pack = parse_url(host)
is_secure = url_pack.scheme == 'https'
port = port or url_pack.port or (443 if is_secure else 80)
url = '%s:%s%s/%s' % (url_pack.hostname, port, url_pack.path, resource)
return is_secure, url
This indicates that the usage should be like below
with SocketIO('https://test-meownow12345.com', 4566, LoggingNamespace) as socketIO:
socketIO.emit('Authenticate', {'api': userApi, 'access': userAccess})
socketIO.on('Party', on_party)

how to call python script from javascript?

I have a backend python script where it retrieves the data from the sqlalchemy engine. And I would like to show the data in a search box where you can scroll down the list of data and select it. I read some answers to the similar questions like mine, (use ajax to call python script). But I'm still not clear about this. Here is my python script.
# models.py
from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.ext.declarative import declarative_base
import pandas as pd
aURL = URL(drivername='mysql', username='chlee021690', database = 'recommender')
engine = create_engine(aURL, echo=True)
sql_command = 'SELECT product_id FROM bestbuy_data'
results = pd.read_sql(sql = sql_command, con = engine)
Can anybody tell me how to create javscript code to retrieve that results and render it in my form? Thanks.
Step 1: make your script available as a web service. You can use CGI, or you can use one of the cool server frameworks that will run standalone or WSGI like CherryPy, web.py or Flask.
Step 2: make an AJAX call to the URL served by step 1, either manually (look for XmlHttpRequest examples), or easily using jQuery or another framework (jQuery.ajax(), jQuery.get()).
These are two separate tasks, both are well documented on the web. If you have a more specific question, I suggest you ask again, showing what you are stuck on.
There are also many examples for the complete package available ("python ajax example"), for example this.
Your Python server needs to do 2 things:
Serve up the AJAX javascript file itself (via GET)
respond to calls from the web client (via POST).
Also it should be threaded to support multiple simultaneous connections.
Below is an example showing how to do all of the above with the built-in BaseHTTPServer.
JS (put in static/hello.html to serve via Python):
<html><head><meta charset="utf-8"/></head><body>
Hello.
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "/postman", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
value: 'value'
}));
xhr.onload = function() {
console.log("HELLO")
console.log(this.responseText);
var data = JSON.parse(this.responseText);
console.log(data);
}
</script></body></html>
Python server (for testing):
import time, threading, socket, SocketServer, BaseHTTPServer
import os, traceback, sys, json
log_lock = threading.Lock()
log_next_thread_id = 0
# Local log functiondef
def Log(module, msg):
with log_lock:
thread = threading.current_thread().__name__
msg = "%s %s: %s" % (module, thread, msg)
sys.stderr.write(msg + '\n')
def Log_Traceback():
t = traceback.format_exc().strip('\n').split('\n')
if ', in ' in t[-3]:
t[-3] = t[-3].replace(', in','\n***\n*** In') + '(...):'
t[-2] += '\n***'
err = '\n*** '.join(t[-3:]).replace('"','').replace(' File ', '')
err = err.replace(', line',':')
Log("Traceback", '\n'.join(t[:-3]) + '\n\n\n***\n*** ' + err + '\n***\n\n')
os._exit(4)
def Set_Thread_Label(s):
global log_next_thread_id
with log_lock:
threading.current_thread().__name__ = "%d%s" \
% (log_next_thread_id, s)
log_next_thread_id += 1
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self):
Set_Thread_Label(self.path + "[get]")
try:
Log("HTTP", "PATH='%s'" % self.path)
with open('static' + self.path) as f:
data = f.read()
Log("Static", "DATA='%s'" % data)
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(data)
except:
Log_Traceback()
def do_POST(self):
Set_Thread_Label(self.path + "[post]")
try:
length = int(self.headers.getheader('content-length'))
req = self.rfile.read(length)
Log("HTTP", "PATH='%s'" % self.path)
Log("URL", "request data = %s" % req)
req = json.loads(req)
response = {'req': req}
response = json.dumps(response)
Log("URL", "response data = %s" % response)
self.send_response(200)
self.send_header("Content-type", "application/json")
self.send_header("content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)
except:
Log_Traceback()
# Create ONE socket.
addr = ('', 8000)
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(addr)
sock.listen(5)
# Launch 10 listener threads.
class Thread(threading.Thread):
def __init__(self, i):
threading.Thread.__init__(self)
self.i = i
self.daemon = True
self.start()
def run(self):
httpd = BaseHTTPServer.HTTPServer(addr, Handler, False)
# Prevent the HTTP server from re-binding every handler.
# https://stackoverflow.com/questions/46210672/
httpd.socket = sock
httpd.server_bind = self.server_close = lambda self: None
httpd.serve_forever()
[Thread(i) for i in range(10)]
time.sleep(9e9)
Console log (chrome):
HELLO
hello.html:14 {"req": {"value": "value"}}
hello.html:16
{req: {…}}
req
:
{value: "value"}
__proto__
:
Object
Console log (firefox):
GET
http://XXXXX:8000/hello.html [HTTP/1.0 200 OK 0ms]
POST
XHR
http://XXXXX:8000/postman [HTTP/1.0 200 OK 0ms]
HELLO hello.html:13:3
{"req": {"value": "value"}} hello.html:14:3
Object { req: Object }
Console log (Edge):
HTML1300: Navigation occurred.
hello.html
HTML1527: DOCTYPE expected. Consider adding a valid HTML5 doctype: "<!DOCTYPE html>".
hello.html (1,1)
Current window: XXXXX/hello.html
HELLO
hello.html (13,3)
{"req": {"value": "value"}}
hello.html (14,3)
[object Object]
hello.html (16,3)
{
[functions]: ,
__proto__: { },
req: {
[functions]: ,
__proto__: { },
value: "value"
}
}
Python log:
HTTP 8/postman[post]: PATH='/postman'
URL 8/postman[post]: request data = {"value":"value"}
URL 8/postman[post]: response data = {"req": {"value": "value"}}
Also you can easily add SSL by wrapping the socket before passing it to BaseHTTPServer.

connecting python to javascript for two-direction communication

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?
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)

Categories

Resources