heroku-python / flask-sockets

[DEPRECATED] Alternative: https://github.com/miguelgrinberg/flask-sock
MIT License
1.74k stars 167 forks source link

Use socket object somewhere else in code #58

Open Tooblippe opened 6 years ago

Tooblippe commented 6 years ago

HI,

I have created the websocket as per the example :+1:

@sockets.route('/socket') def echo_socket(ws): while True: message = ws.receive() ws.send(message[::-1])

I have tested it from a page and it works fine.

My question. How do I use the websocket to send info from another function e.g.

def otherFunction(): do stuff ws.send("this is an update")

Alex-CodeLab commented 5 years ago

Have you ever found a solution for this?

driftregion commented 3 years ago

flask-sockets uses gevent, which is premised on the request-response model of HTTP. It perhaps wasn't designed with long running requests in mind.

To send outside of the request context, you can use something like websocket-server. It's possible to do this in a thread alongside an existing flask app. Here's a minimal example:

#!/usr/bin/env python3

import threading
from flask import Flask
from websocket_server import WebsocketServer
import logging
import time

app = Flask(__name__)

@app.route("/")
def hello_world():
    return """
<p id="counter">wating for server...</p>
<script>
var ws = new WebSocket("ws://" + document.domain + ":" + "13254" + "/json")
ws.onopen = function(event) {
    ws.send("Webpage opened at " + Date.now() );
}
var counter_txt = document.getElementById("counter");
ws.onmessage = function(event) {
    counter_txt.textContent = event.data;
}
</script>
"""

should_exit = threading.Event()

def onReceived(client, srv, msg):
    print(f"server received {msg}")

server = WebsocketServer(13254, host='127.0.0.1', loglevel=logging.INFO)
server.set_fn_message_received(onReceived)

def websocketPeriodicTask():
    i = 0
    while not should_exit.is_set():
        server.send_message_to_all(f"this is update number {i}")
        i += 1
        time.sleep(1)

def websocketServerTask():
    while not should_exit.is_set():
        server.run_forever()

threads =  [threading.Thread(target=t) for t in [websocketServerTask, websocketPeriodicTask]]
[t.start() for t in threads]

try:
    app.run(use_reloader=False)
except KeyboardInterrupt:
    should_exit.set()
    [t.join() for t in threads]