I'm currently trying to understand how sockets work. I'm using Flask-socketio and a python socketio client and running through a basic example. Here is what I have done so far
Usage Module
-i https://pypi.org/simple
certifi==2019.6.16
chardet==3.0.4
click==7.0
confluent-kafka==1.1.0
dependency-injector==3.14.7
docker==4.0.2
flask-socketio==4.2.1
flask==1.1.1
idna==2.8
itsdangerous==1.1.0
jinja2==2.10.1
markupsafe==1.1.1
python-engineio==3.10.0
python-socketio==4.4.0
requests==2.22.0
six==1.12.0
urllib3==1.25.3
websocket-client==0.56.0
werkzeug==0.15.5
server.py
import json
import logging
import os
import sys
import threading
from threading import Lock
from containers import Configs, Consumers, Managers
from errors import ObjectNotFound
from flask import Response
from flask_socketio import SocketIO, emit, join_room, leave_room, \
close_room, rooms, disconnect
from flask import Flask, render_template, session, request, \
copy_current_request_context
import sys, traceback
# Configure logger
logging.basicConfig(
level=logging.ERROR,
format='%(name)s - %(levelname)s - %(message)s'
)
broker = 'localhost:9092'
# Check environment variable
if 'KAFKA_BROKER' in os.environ:
broker = os.environ['KAFKA_BROKER']
elif len(sys.argv) > 1 and sys.argv[1]:
node_id = sys.argv[1]
# Override configuration
Configs.config.override({
'broker': broker,
'groupId': 'grpactconsumer'
})
async_mode = None
api = Flask(__name__)
api.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(
api,
async_handlers=False,
ping_timeout=60,
async_mode=async_mode,
cors_allowed_origins="*",
always_connect=True,
engineio_logger=True
)
thread = None
thread_lock = Lock()
logging.getLogger('engineio').setLevel(logging.ERROR)
stat_consumer = Consumers.consumer()
def worker(topic):
def on_receive(value):
socketio.sleep(0)
socketio.emit('object_stat', value, namespace='/event')
stat_consumer.consume([topic], on_receive)
worker_thread = threading.Thread(target=worker, args=['Stats'])
worker_thread.start()
def on_event_received():
socketio.emit('object_event', {}, namespace='/event')
# Start listening events
object_manager = Managers.object_manager()
object_manager.listen_events(['Events'], on_event_received)
#socketio.on('disconnect', namespace='/event')
def test_disconnect():
print('Client disconnected', request.sid)
#socketio.on('my event')
def handle_my_custom_event(json):
logging.error('received json: ' + str(json))
print('received json: ' + str(json))
# CORS Policy handlers
#api.after_request
def after_request(response):
header = response.headers
header['Access-Control-Allow-Origin'] = '*'
return response
# Object not found error handler for api
#api.errorhandler(ObjectNotFound)
def not_found_exception(error):
return json.dumps({}), 404, {'ContentType': 'application/json'}
# Unhandled error handler for api
#api.errorhandler(Exception)
def unhandled_exception(error):
return json.dumps({}), 500, {'ContentType': 'application/json'}
# Node Endpoints
#api.route('/node/list', methods=['GET'])
def list_nodes():
nodes = object_manager.node.list()
objects = {'nodes': nodes}
return json.dumps(objects, indent=4), 200, {'ContentType': 'application/json'}
# Service Endpoints
#api.route('/service', methods=['POST'])
def create_service():
service_id = object_manager.service.create(
request.json['name'],
request.json['image'],
request.json['command'],
request.json['node_labels'],
request.json['customer_id'],
request.json['application_id'],
request.json['limit']
)
return json.dumps({'success': True, 'id': service_id}), 200, {'ContentType': 'application/json'}
#api.route('/service/<service_id>', methods=['GET'])
def get_service(service_id):
service = object_manager.service.get(service_id)
return Response(json.dumps(service, indent=4), mimetype='application/json')
#api.route('/service/<service_id>/migrate', methods=['PUT'])
def migrate_service(service_id):
object_manager.service.migrate(
service_id,
request.json['node_labels']
)
return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
#api.route('/service/<service_id>/scale', methods=['PUT'])
def scale_service(service_id):
object_manager.service.scale(
service_id,
request.json['replica_count']
)
return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
#api.route('/service/<service_id>', methods=['DELETE'])
def remove_service(service_id):
object_manager.service.remove(service_id)
return json.dumps({'success': True}), 200, {'ContentType': 'application/json'}
#api.route('/service/list', methods=['GET'])
def list_services():
services = object_manager.service.list()
objects = {'services': services}
return json.dumps(objects, indent=4), 200, {'ContentType': 'application/json'}
# Container Endpoints
#api.route('/container/list', methods=['GET'])
def list_containers():
containers = object_manager.container.list()
objects = {'containers': containers}
return json.dumps(objects, indent=4), 200, {'ContentType': 'application/json'}
# Start flask server
socketio.run(api, debug=True, use_reloader=False, host='0.0.0.0')
client.js
/**
* This file is used for socket connection. Any data received by this class is only shared with data.js.
*/
let namespace = 'http://0.0.0.0:5000/event';
let socket = io.connect(namespace, {'forceNew': true });
socket.on('object_event', function (msg, cb) {
$.get('http://0.0.0.0:5000/node/list', function (response) {
node_data_source = JSON.parse(response)['nodes'];
for (let data_table_id of Object.keys(data_table_listeners)) {
if ($.fn.DataTable.isDataTable('#' + data_table_id)) {
data_table_listeners[data_table_id]();
}
}
});
if (cb)
cb();
});
socket.on('object_stat', function (msg, cb) {
let data = JSON.parse(msg);
if (stat_data_source) {
let node_stats = stat_data_source[data['node']];
node_stats = ( typeof node_stats != 'undefined' && node_stats instanceof Array ) ?
node_stats : [];
node_stats[data['container']] = data;
stat_data_source[data['node']] = node_stats;
}
console.log("Object_stats Socket.js");
console.log(data);
for (let stat_listener of Object.keys(stat_data_listeners)) {
if (stat_data_listeners[stat_listener]) {
stat_data_listeners[stat_listener]();
}
}
if (cb)
cb();
});
Errors
linkp-master.0.dey9j12wugl1#vm | INFO:engineio.server:3f2175ed5d72425da816e24ffeddb275: Sending packet MESSAGE data 2/event,["object_stat","{\"ram_limit\": 61254823575.552, \"customer_id\": \"-\", \"time\": 1575638732170, \"io_limit\": 0.0, \"container\": \"b703eadb700f\", \"node\": \"953mxmlwyvltfrx88ujlpkx3k\", \"io_usage\": 0.0, \"application_id\": \"-\", \"cpu_percent\": \"1.38\", \"ram_usage\": 407266918.4, \"network_limit\": 6144000.0, \"network_usage\": 3768000.0, \"pids\": \"25\"}"]
linkp-master.0.dey9j12wugl1#vm | f603fce7e2464586ab77636d127d92dc: Client is gone, closing socket
linkp-master.0.dey9j12wugl1#vm | INFO:engineio.server:f603fce7e2464586ab77636d127d92dc: Client is gone, closing socket
linkp-master.0.dey9j12wugl1#vm | f603fce7e2464586ab77636d127d92dc: Client is gone, closing socket
linkp-master.0.dey9j12wugl1#vm | INFO:engineio.server:f603fce7e2464586ab77636d127d92dc: Client is gone, closing socket
linkp-master.0.dey9j12wugl1#vm | emitting event "object_stat" to all [/event]
linkp-master.0.dey9j12wugl1#vm | INFO:socketio.server:emitting event "object_stat" to all [/event]
Related
I'm trying to deploy a python app on heroku, but heroku returned a H10 error. Here is my code python code:
import os
import requests
import random
from flask import Flask, jsonify, request
from flask_cors import CORS
from system.backend.data import Data
from system.backend.folder import Folder
from system.wallet.data_pool import DataPool
from system.wallet.exchange import Exchange
from system.pubsub import PubSub
app = Flask(__name__)
CORS(app, resources={ r'/*': { 'origins': 'http://localhost:8080' } })
data = Data()
data_pool = DataPool()
folder = Folder(data)
pubsub = PubSub(data, data_pool)
#app.route('/')
def default():
return 'Welcome to mypython app'
#app.route('/main')
def route_mainn():
return jsonify(data.to_json())
#app.route('/main/range')
def route_main_range():
start = int(request.args.get('start'))
end = int(request.args.get('end'))
return jsonify(data.to_json()[::-1][start:end])
#app.route('/main/datalength')
def route_main_datalength():
return jsonify(len(data.length))
#app.route('/myapp/data')
def route_myapp_data():
app_data = data_pool.app_data()
exchange_data.append(Exchange.reward_exchange(folder).to_json())
data.add_data(exchange_data)
folder = data.length[-1]
pubsub.broadcast_folder(folder)
data_pool.clear_data_exchange(data)
return jsonify(data.to_json())
#app.route('/folder/exchange', methods=['POST'])
def route_folder_exchange():
exchange_data = request.get_json()
exchange = data_pool.existing_exchange(folder.address)
if exchange:
exchange.update(
folder,
exchange_data['recipient'],
exchange_data['sender']
)
else:
exchange = Exchange(
folder,
exchange_data['recipient'],
exchange_data['sender']
)
pubsub.broadcast_exchange(exchange)
data_pool.set_exchange(exchange)
return jsonify(exchange.to_json())
#app.route('/folder/info')
def route_folder_info():
return jsonify({'address': folder.address, 'data': folder.balance})
#app.route('/known-addresses')
def route_known_addresses():
known_addresses = set()
for data in main.length:
for exchange in main.data:
exchange['output'].keys()
known_addresses.update(exchange['output'].keys())
return jsonify(list(known_addresses))
#app.route('/exchange')
def route_exchanges():
return jsonify(exchange_pool.exchange_data())
ROOT_PORT = 8080
PORT = ROOT_PORT
if os.environ.get('PEER') == 'True':
PORT = random.randint(8081, 9000)
result = requests.get(f'http://localhost:{ROOT_PORT}/main')
print(f'result.json(): {result.json()}')
result_main = Data.from_json(result.json())
try:
data.replace_length(result_data.length)
print('\n -- Successfully synchronized the local data')
except Exception as e:
print(f'\n -- Error synchronizing: {e}')
if os.environ.get('SEED_DATA') == 'True':
for i in range(10):
main.add_folder([
Exchange(Folder(), Folder().address, random.randint(500, 1000)).to_json(),
Exchange(Folder(), Folder().address, random.randint(500, 1000)).to_json()
])
for i in range(3):
data_pool.set_exchange(
Exchange(Folder(), Folder().address, random.randint(500, 1000))
)
app.run(port=PORT)
I also made a worker.py file with the code as follows:
import os
import redis
from rq import Worker, Queue, Connection
listen = ['high', 'default', 'low']
redis_url = os.getenv('REDIS_URL', 'redis://localhost:8080')
conn = redis.from_url(redis_url)
if __name__ == '__main__':
with Connection(conn):
worker = Worker(map(Queue, listen))
worker.work()
The mac terminal recommended to use waitress for python deployment, but I'm not sure on how to implement waitress within the code shown on the above.
To use waitress:
Just do pip install waitress
And add this snippet:
if __name__ == '__main__':
from waitress import serve
serve(app, host='0.0.0.0', port=8000)
I am trying to make a video streamer to stream client camera using socket.io and flask, but my socket io seems not responding at all as it is not returning log on my console Connected..! What is the cause of this please help thanks.
Here is my app.py
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
socketio = SocketIO(app)
#app.route('/', methods=['POST', 'GET'])
def index():
return render_template('index.html')
#socketio.on('image')
def image(data_image):
sbuf = StringIO()
sbuf.write(data_image)
# decode and convert into image
b = io.BytesIO(base64.b64decode(data_image))
pimg = Image.open(b)
## converting RGB to BGR, as opencv standards
frame = cv2.cvtColor(np.array(pimg), cv2.COLOR_RGB2BGR)
# Process the image frame
frame = imutils.resize(frame, width=700)
frame = cv2.flip(frame, 1)
imgencode = cv2.imencode('.jpg', frame)[1]
# base64 encode
stringData = base64.b64encode(imgencode).decode('utf-8')
b64_src = 'data:image/jpg;base64,'
stringData = b64_src + stringData
# emit the frame back
emit('response_back', stringData)
if __name__ == "__main__":
socketio.run(app, host='127.0.0.1')
and here is my index.html. I plan to have the response to be put on img with id image by using javascript socket io in my client side.
<div class = 'video'>
<img id="image">
</div>
<script>
var socket = io('http://localhost:5000');
socket.on('connect', function(){
console.log("Connected...!", socket.connected)
});
const video = document.querySelector("#videoElement");
video.width = 500;
video.height = 375; ;
if (navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia({ video: true })
.then(function (stream) {
video.srcObject = stream;
video.play();
})
.catch(function (err0r) {
console.log(err0r)
console.log("Something went wrong!");
});
}
let src = new cv.Mat(video.height, video.width, cv.CV_8UC4);
let dst = new cv.Mat(video.height, video.width, cv.CV_8UC1);
let cap = new cv.VideoCapture(video);
const FPS = 22;
setInterval(() => {
cap.read(src);
var type = "image/png"
var data = document.getElementById("canvasOutput").toDataURL(type);
data = data.replace('data:' + type + ';base64,', ''); //split off junk
at the beginning
socket.emit('image', data);
}, 10000/FPS);
socket.on('response_back', function(image){
const image_id = document.getElementById('image');
image_id.src = image;
});
</script>
This is the only response that my flask server give. It is strange that my flask server completely stop after that get. What I expected is for the server to emit back the response but nothing happen
* Serving Flask app "app.py" (lazy loading)
* Environment: development
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 268-223-757
127.0.0.1 - - [25/Mar/2021 09:41:49] "GET / HTTP/1.1" 200 -
I am trying to connect my local backend and front end together using okhttp and flask, however i am getting java.net.ConnectException: failed to connect to /127.0.0.1 (port 5000) after 10000ms: isConnected failed: ECONNREFUSED (Connection refused) exception
Now that API does work correctly as i can reach it in postman where it returns values, here is the code
from flask import request, Flask
import getMovie
import getUser
api = Flask(__name__)
#Movie Endpoints
#api.route('/Movies/GetMovieById', methods=['GET'])
def get_movie_by_id():
id = str(request.args['id'])
return getMovie.getById(id)
#api.route('/Movies/All', methods=['GET'])
def get_all_movies():
return getMovie.getAll()
#User Endpoints
#api.route('/Users/All', methods=['GET'])
def get_all_users():
return getUser.getAll()
#api.route('/Users/GetUserById', methods=['GET'])
def get_user_by_id():
id = str(request.args['id'])
return getUser.getById(id)
if __name__ == '__main__':
api.run()
Then here is the mainactivity for the android app
package com.example.moviebuffs
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.moviebuffs.ui.main.*
import kotlinx.android.synthetic.main.main_activity.*
import okhttp3.*
import java.io.IOException
class MainActivity : AppCompatActivity() {
private lateinit var movieListAdapter: MovieListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
movieListAdapter= MovieListAdapter(mutableListOf())
rvFilmList.adapter = movieListAdapter
rvFilmList.layoutManager = LinearLayoutManager(this)
var testMovie = Movie(1,"Jurassic Park","Action | Dinosaurs")
for (i in 1..100) {
movieListAdapter.addMovie(testMovie)
}
fetchTest()
}
fun fetchTest() {
print("Trying to connect....")
val url: HttpUrl = HttpUrl.Builder()
.scheme("http")
.host("127.0.0.1")
.port(5000)
.addPathSegment("Movies")
.addPathSegment("All")
.build()
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response?.body?.string()
print(body)
}
override fun onFailure(call: Call, e: IOException) {
val x = 0
}
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main_menu, menu)
return true
}
fun toGenreActivity(item: MenuItem?): Boolean {
val intent = Intent(this, GenreActivity::class.java)
startActivity(intent)
return true
}
fun toUserActivity(item: MenuItem?): Boolean {
val intent = Intent(this, UserActivity::class.java)
startActivity(intent)
return true
}
fun toMovieActivity(v: View?) {
val intent = Intent(this, MovieActivity::class.java)
startActivity(intent)
}
}
And here is the manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.moviebuffs">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.main.GenreActivity">
</activity>
<activity android:name=".ui.main.MovieActivity">
</activity>
<activity android:name=".ui.main.UserActivity">
</activity>
</application>
</manifest>
Any ideas?
Localhost loopback address 127.0.0.1 refers to the device itself. You don't have the server running on your Android emulator.
Use 10.0.2.2 instead to connect to the host where the emulator is running on.
More info: https://developer.android.com/studio/run/emulator-networking
I have a gRPC server implemented in python and I am calling an RPC from NodeJS but it gives an error "Method not found". When I call using the python client, the request is successful.
stream_csv.proto
syntax = "proto3";
package csv;
service Stream {
rpc csvToObject(CSVDataRequest) returns (stream CSVDataResponse) {};
rpc sayHello(HelloRequest) returns (HelloReply);
}
message CSVDataRequest{
string url = 1;
enum Protocol {
HTTP = 0;
HTTPS = 1;
FTP = 2;
SFTP = 3;
}
Protocol protocol = 2;
}
message CSVDataResponse{
repeated string row = 1;
}
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
client.js
var PROTO_PATH = '../stream_csv.proto';
var grpc = require('grpc');
var protoLoader = require('#grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var proto = grpc.loadPackageDefinition(packageDefinition).csv;
function main() {
var client = new proto.Stream('localhost:5000',
grpc.credentials.createInsecure());
var user;
if (process.argv.length >= 3) {
user = process.argv[2];
} else {
user = 'world';
}
console.log(user);
client.sayHello({name: user}, function(err, response) {
console.log(err);
});
}
main();
server.py
import grpc
import stream_csv_pb2
import urllib.request
from urllib.error import HTTPError, URLError
from concurrent import futures
class DataService:
def csv_to_object(self, request, context):
url = request.url
protocol = stream_csv_pb2.CSVDataRequest.Protocol.Name(
request.protocol)
fetch_url = protocol.lower() + "://"+url
try:
with urllib.request.urlopen(fetch_url) as data:
for line in data:
decoded_line = line.decode()
val = decoded_line.split(',')
print(val)
print("Data send")
yield stream_csv_pb2.CSVDataResponse(row=val)
print("Sending finished!")
except URLError as e:
context.abort(grpc.StatusCode.UNKNOWN,
'Randomly injected failure.')
# return stream_csv_pb2.CSVDataResponse(row=[], error=e.reason)
def SayHello(self, request, context):
name = request.name
print(name)
return stream_csv_pb2.HelloReply(message='Hello %s' % (name))
def add_DataServicer_to_server(servicer, server):
rpc_method_handlers = {
'CSVToObject': grpc.unary_stream_rpc_method_handler(
servicer.csv_to_object,
request_deserializer=stream_csv_pb2.CSVDataRequest.FromString,
response_serializer=stream_csv_pb2.CSVDataResponse.SerializeToString,
),
'SayHello': grpc.unary_unary_rpc_method_handler(
servicer.SayHello,
request_deserializer=stream_csv_pb2.HelloRequest.FromString,
response_serializer=stream_csv_pb2.HelloReply.SerializeToString,
)
}
generic_handler = grpc.method_handlers_generic_handler(
'stream_csv.Stream', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
add_DataServicer_to_server(DataService(), server)
server.add_insecure_port('[::]:5000')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
Error
Error: 12 UNIMPLEMENTED: Method not found!
at Object.exports.createStatusError (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/common.js:91:15)
at Object.onReceiveStatus (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:1209:28)
at InterceptingListener._callNext (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:568:42)
at InterceptingListener.onReceiveStatus (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:618:8)
at callback (/home/shantam/Documents/grepsr/client/node_modules/grpc/src/client_interceptors.js:847:24) {
code: 12,
metadata: Metadata { _internal_repr: {}, flags: 0 },
details: 'Method not found!'
}
I wrote a simpler variant of your Python (and Golang) server implementations.
Both work with your Node.JS client as-is.
I think perhaps your issue is as simple as needing to name the rpc sayHello (rather than SayHello).
from concurrent import futures
import logging
import grpc
import stream_csv_pb2
import stream_csv_pb2_grpc
class Stream(stream_csv_pb2_grpc.StreamServicer):
def sayHello(self, request, context):
logging.info("[sayHello]")
return stream_csv_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
logging.info("[serve]")
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
stream_csv_pb2_grpc.add_StreamServicer_to_server(Stream(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
And:
node client.js
Greeting: Hello, Freddie!
null
Conventionally (!) gRPC follows Protobufs style guide of CamelCasing service, rpc and message names and using underscores elsewhere see Style Guide. When protoc compiles, the results don't always match perfectly (e.g. Python's CamelCased functions rather than lowercased with underscores).
Conventionally, your proto would be:
service Stream {
rpc CsvToObject(CSVDataRequest) returns (stream CSVDataResponse) {};
rpc SayHello(HelloRequest) returns (HelloReply);
}
...and then the Python generated function would be (!) SayHello too.
I've written some api to communicate with a website using websocketapp. It works fine only on 2 pc. If i put my code on every other pc the websocket doesnt receive any message and closes. I've tried a lot of different machines and operating systems, many version of python (included the same that works), wireless and wired connection but nothing changed. There's no error or exception. What can it be?
EDIT: i don't own the website or the server. All other methods send messages and parse the response in on_socket_message
import requests
import websocket
import time
from threading import Thread
from datetime import datetime
import json
from position import Position
from constants import ACTIVES
class IQOption():
practice_balance = 0
real_balance = 0
server_time = 0
positions = {}
instruments_categories = ["cfd","forex","crypto"]
top_assets_categories = ["forex","crypto","fx-option"]
instruments_to_id = ACTIVES
id_to_instruments = {y:x for x,y in ACTIVES.items()}
market_data = {}
binary_expiration_list = {}
open_markets = {}
digital_strike_list = {}
candle_data = []
latest_candle = 0
position_id = 0
quotes =[]
position_id_list=[]
def __init__(self,username,password,host="iqoption.com"):
self.username = username
self.password = password
self.host = host
self.session = requests.Session()
self.generate_urls()
self.socket = websocket.WebSocketApp(self.socket_url,on_open=self.on_socket_connect,on_message=self.on_socket_message,on_close=self.on_socket_close,on_error=self.on_socket_error)
def generate_urls(self):
"""Generates Required Urls to operate the API"""
#https://auth.iqoption.com/api/v1.0/login
self.api_url = "https://{}/api/".format(self.host)
self.socket_url = "wss://{}/echo/websocket".format(self.host)
self.login_url = self.api_url+"v1.0/login"
self.profile_url = self.api_url+"profile"
self.change_account_url = self.profile_url+"/"+"changebalance"
self.getprofile_url = self.api_url+"getprofile"
def login(self):
"""Login and set Session Cookies"""
print("LOGIN")
data = {"email":self.username,"password":self.password}
self.log_resp = self.session.request(url="https://auth.iqoption.com/api/v1.0/login",data=data,method="POST")
requests.utils.add_dict_to_cookiejar(self.session.cookies, dict(platform="9"))
self.__ssid = self.log_resp.cookies.get("ssid")
print(self.__ssid)
self.start_socket_connection()
time.sleep(1) ## artificial delay to complete socket connection
self.log_resp2 = self.session.request(url="https://eu.iqoption.com/api/getprofile",method="GET")
ss = self.log_resp2._content.decode('utf-8')
js_ss=json.loads(ss)
self.parse_account_info(js_ss)
self.balance_id = js_ss["result"]["balance_id"]
self.get_instruments()
self.get_top_assets()
self.setOptions()
#self.getFeatures()
time.sleep(1)
print(js_ss["isSuccessful"])
return js_ss["isSuccessful"]
def on_socket_message(self,socket,message):
#do things
def on_socket_connect(self,socket):
"""Called on Socket Connection"""
self.initial_subscriptions()
print("On connect")
def initial_subscriptions(self):
self.send_socket_message("ssid",self.__ssid)
self.send_socket_message("subscribe","tradersPulse")
def on_socket_error(self,socket,error):
"""Called on Socket Error"""
print(message)
def on_socket_close(self,socket):
"""Called on Socket Close, does nothing"""
def start_socket_connection(self):
"""Start Socket Connection"""
self.socket_thread = Thread(target=self.socket.run_forever)
self.socket_thread.start()
def send_socket_message(self,name,msg):
#print(msg)
data = {"name":name,"msg":msg}
self.socket.send(json.dumps(data))
Here is an example running under Gevent Websockets. This makes it ASYNC (which I suspect is part of your problem) and allows for bidirectional communication.
import gevent
from gevent import monkey, signal, Timeout, sleep, spawn as gspawn
monkey.patch_all()
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from geventwebsocket import WebSocketError
import bottle
from bottle import get, route, template, request, response, abort, static_file
import ujson as json
#route('/static/<filepath:path>')
def server_static(filepath):
return static_file(filepath, root='static')
#route('/ws/remote')
def handle_websocket():
wsock = request.environ.get('wsgi.websocket')
if not wsock:
abort(400, 'Expected WebSocket request.')
while 1:
try:
message = ''
with Timeout(2, False) as timeout:
message = wsock.receive()
if message:
message = json.loads(message)
if 'command' in message:
r.command(message['command'])
except WebSocketError:
break
except Exception as exc:
print(str(exc))
#get('/')
def remote():
return template('templates/remote.tpl', title='WebsocketTest', websocket=WEBSOCKET, command='command', status=status)
if __name__ == '__main__':
r=None
status="Connecting..."
gspawn(initialize)
print 'Started...'
HOST = socket.gethostbyname(socket.gethostname())
HOST = 'localhost'
WEBSOCKET = 'ws://{}/ws/remote'.format(HOST)
botapp = bottle.app()
server = WSGIServer(("0.0.0.0", 80), botapp, handler_class=WebSocketHandler)
def shutdown():
print('Shutting down ...')
server.stop(timeout=60)
exit(signal.SIGTERM)
gevent.signal(signal.SIGTERM, shutdown)
gevent.signal(signal.SIGINT, shutdown) #CTRL C
server.serve_forever()
Then in your HTML you really should use reconnecting websocket library
https://github.com/joewalnes/reconnecting-websocket
<button id="TRIGGERED" type="button" class="btn btn-outline-primary">TRIGGER</button>
<script type="text/javascript" src="/static/reconnecting-websocket.min.js"></script>
<script>
var ws = new ReconnectingWebSocket('{{websocket}}');
ws.reconnectInterval = 3000;
ws.maxReconnectAttempts = 10;
ws.onmessage = function (evt) {
var wsmsg = JSON.parse(evt.data);
console.log(evt.data)
};
$("button").click(function() {
<!--console.log(this.id);-->
ws.send(JSON.stringify({'{{command}}': this.id}));
});
</script>