How to stop python websocket connection after some seconds? - python

I am trying to develop a short script that connects to a real-time stock data provider through a websocket API, gets some data, makes some calculations, stores the results in a database and stops.
EDIT: I need to keep the connection alive for a few seconds until I get all required data. Thus, breaking the connection after the first message is not an option.
The problem I am facing is how to stop the run_forever() connection.
This is what I have so far:
import websocket
import json
def on_open(ws):
channel_data = {
"action": "subscribe",
"symbols": "ETH-USD,BTC-USD"
}
ws.send(json.dumps(channel_data))
def on_message(ws, message):
# Do some stuff (store messages for a few seconds)
print(message)
def on_close(ws):
print("Close connection")
socket = "wss://ws.url"
ws = websocket.WebSocketApp(socket, on_open=on_open, on_message=on_message)
ws.run_forever()
ws.close()
# Once the connection is closed, continue with the program
I do not want to stay connected after the "Do some stuff" is executed, how can I force the connection close?
Your help is much appreciated.

I managed how to solve this. I leave my solution in case it is useful to someone.
I just added some attributes to the ws object that allows me to track the number of messages received and store them into a list to work with once the connection is closed.
import websocket
import json
def on_open(ws):
channel_data = {
"action": "subscribe",
"symbols": "ETH-USD,BTC-USD"
}
ws.send(json.dumps(channel_data))
def on_message(ws, message):
ws.messages_count+=1
ws.messages_storage.append(message)
if ws.messages_count>50:
ws.close()
def on_close(ws):
print("Close connection")
socket = "wss://ws.url"
ws = websocket.WebSocketApp(socket, on_open=on_open, on_message=on_message)
# Create a counter and an empty list to store messages
ws.messages_count = 0
ws.messages_storage = []
# Run connection
ws.run_forever()
# Close connection
ws.close()
# Continue with the program

Related

Having trouble to get Binance's Websocket Market Streams

I am having a trouble getting some data from Binance Websocket.
The code is the following:
import websocket
import json
import pprint
SOCKET = "wss://stream.binance.com:9443/ws/ethusdt#kline_1m"
def on_open(ws):
print('opened connection')
def on_close(ws):
print('closed connection')
def on_message(ws, message):
print('received message')
json_message = json.loads(message)
pprint.pprint(json_message)
ws = websocket.WebSocketApp(SOCKET, on_open=on_open, on_close=on_close, on_message=on_message)
ws.run_forever()
In fact when I run the program there isn't any result printed on my screen.
I need help in spotting the mistake I have made in order for it to work properly.
Thanks!

Long-Lived Websocket connection not working when I have multiple requests

I'm using Python to connect to a websocket that generates real-time market data. In order to obtain my data I need to follow these 3 steps:
1 - Estabilish a connection with the websocket
2 - Insert the token using the message: {"action":"initialData", "token": "MY_TOKEN"}
3 - Execute the desired request which in my case is: {"action": "startStreamQuote","symbols":["PETR4"]}
This is what I've writen so far:
url = "wss://svc.aebroadcast.com.br/stock/ws"
ws = create_connection(url)
ws.recv()
ws.send(json.dumps({"action":"initialData", "token": "eY6Hw9olpa93......"}))
ws.recv()
ws.send(json.dumps({"action": "startStreamQuote","symbols":["PETR4"]}))
ws.recv()
print("Received" + ws.recv())
The following code creates the connection and pulls the information but then stops so I need to keep executing it if I wanna see more info, but if I execute 2 times and there's no new info, it gets duplicated. Anyway...
I was reading the websocket documentation and found this example for long-lived connections:
import websocket
import _thread
import time
import rel
def on_message(ws, message):
print(message)
def on_error(ws, error):
print(error)
def on_close(ws, close_status_code, close_msg):
print("### closed ###")
def on_open(ws):
print("Opened connection")
if __name__ == "__main__":
websocket.enableTrace(True)
ws = websocket.WebSocketApp("wss://api.gemini.com/v1/marketdata/BTCUSD",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.run_forever(dispatcher=rel) # Set dispatcher to automatic reconnection
rel.signal(2, rel.abort) # Keyboard Interrupt
rel.dispatch()
Although this example fits very well and succeeds in mainting an open connection running, I don't know where I should insert my two requests (2 and 3 of the list above) 'initialData' and 'startStreamQuote' into this structure. I've tried using ws.send(json.dumps('.....generical request.....')) and depending on the position inside the code it returns a connection closed error or simply doesn't return anything about the request.
Can someone help me with that?

Connection WebSocket with Session

good morning.
I'm trying to make an API for Quotex.com brokerage where your communication is done via websocket --> wss://ws.qxbroker.com/socket.io/?EIO=3&transport=websocket
To connect to the broker I'm using Selenium. I can recover the session, but the difficulty is to send this data back to the websocket.
My code is this, where I try to connect and then send an order to broker.
Could someone help me please.
order = '42["orders/open",{"asset":"AUDCAD_otc","amount":6,"time":1637893200,"action":"put","isDemo":1,"requestId":1637892541,"optionType":1}]'
order2 = json.dumps(order)
try:
import thread
except ImportError:
import _thread as thread
import time
def on_message(ws, message):
print(message)
def on_error(ws, error):
print(error)
def on_close(ws):
print("### closed ###")
def on_open(ws):
def run(*args):
for i in range(3):
time.sleep(1)
ws.send("""42["authorization",{"session":""" + session + ""","isDemo":1}]""")
time.sleep(1)
ws.send(order)
ws.send(order2)
ws.close()
print("thread terminating...")
thread.start_new_thread(run, ())
urlsocket = "wss://ws.qxbroker.com/socket.io/?EIO=3&transport=websocket"
ws = websocket.WebSocketApp(
urlsocket, on_message=on_message,
on_open=on_open)
ws.run_forever()
Example of analysis via google chrome devtools
Exemple Send Order for Broker

Subscribe to bitFlyer WebSocket

I have set up websocket connections to multiple cryptocurrency exchanges but I'm having difficulty connecting to bitFlyer's.
My code is as follows:
import websocket
import json
def on_message(ws, message):
msg = json.loads(message)
print(msg)
def on_error(ws, error):
print(error)
def on_close(ws):
print("### closed ###")
def on_open(ws):
ws.send(json.dumps({"method":"subscribe", "channel":"lightning_executions_FX_BTC_JPY"}))
while True:
if __name__ == "__main__":
#websocket.enableTrace(True)
ws = websocket.WebSocketApp("wss://ws.lightstream.bitflyer.com/json-rpc",
on_message=on_message,
on_error=on_error,
on_close=on_close)
ws.on_open = on_open
ws.run_forever()
I have tried many many variations of my on_open() message and most result in a ### closed ###
Invalid close opcode. error.
Unfortunately their documentation does not contain a Python sample located HERE.
Any help in sending the correct message is much appreciated.
I believe the format of message you sent was wrong, check the following reference from https://lightning.bitflyer.jp/docs/playgroundrealtime, guess it will solve.
# pip install websocket-client
import websocket
import json
CHANNEL = "lightning_board_snapshot_<productCode>"
def on_message(ws, message):
message = json.loads(message)
if message["method"] == "channelMessage":
print("{} {}".format(message["params"]["channel"], message["params"]["message"]))
def on_open(ws):
ws.send(json.dumps({"method": "subscribe", "params": {"channel": CHANNEL}}))
if __name__ == "__main__":
// note: reconnection handling needed.
ws = websocket.WebSocketApp("wss://ws.lightstream.bitflyer.com/json-rpc",
on_message = on_message, on_open = on_open)
ws.run_forever()

Python WebSocket Client connecting but not sending messages

While using websocket client to send test messages to a django server, I cannot get a script to work which can both send and receive messages.
The following python script is what I have attempted:
import websocket
import threading
import json
from time import sleep
# handle message event
def on_message(ws, message):
print("message recieved: %s" % message)
# handle close event
def on_close(ws):
print("channel closed")
# execute as main script
if __name__ == "__main__":
websocket.enableTrace(True)
# new app object connecting to headstation
ws = websocket.WebSocketApp("ws://192.168.0.106:8000/?testI123", on_message = on_message, on_close = on_close)
# run in a new thread - kill if script ends
ws_listener = threading.Thread(target=ws.run_forever())
ws_listener.daemon = True
# start second thread
ws_listener.start()
# attempt connection 5 times
timeout = 5
while not ws.sock.connected and timeout:
sleep(1)
timeout -= 1
# error on timeout
if (timeout == 0):
print("Connection to server timed out")
print("test 1")
# periodically send test message to server
message_num = 0
while ws.sock.connected:
# send node id and message
message = 'hello %d'%message_num
ws.send(message)
sleep(1)
message_num += 1
This connections successfully, indicted by the server, and receives messages sent from the server, but does not send anything.
Periodically, something like this is displayed on the terminal:
send: b'\x8a\x84\xe2\xe9\xa8\xe2\x8f\xdc\xe2\x84'
If I simply use
ws = websocket.WebSocket()
ws.connect(url)
ws.send("hello")
then this works perfectly. Suggesting it is something wrong with my little python script displayed above.
Found the problem, stupid mistake of course:
ws_listener = threading.Thread(target=ws.run_forever())
should be:
ws_listener = threading.Thread(target=ws.run_forever)
without parentheses.
First one passes result of ws.run_forever to the target, second one sets ws.run_forever as the target, which was the intended outcome.

Categories

Resources