miguelgrinberg / Flask-SocketIO

Socket.IO integration for Flask applications.
MIT License
5.31k stars 888 forks source link

I'm getting error when using self signed SSL #1961

Closed shyam3089 closed 1 year ago

shyam3089 commented 1 year ago

I'm running app with self signed open SSL. There are multiple issues.

  1. It takes a long time to load html. Some time loads partially.
  2. Emit events are not being received in the server side and vice versa.
  3. Whenever there's an an emit event from the client side error given below appears: <Greenlet at 0x28cddf81a80: _handle_and_close_when_done(<bound method StreamServer.wrap_socket_and_handle , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket [closed] at 0x28cdd08e680)> failed with ConnectionAbortedError

    I'm running Flask app in a thread as it's included in another app. Flask app works as an interface for a voice assistant app. Note: when using eventlet as asyncmode the app doesn't even work in httpmode. What's wrong here?

    Code:

    import ssl
    from flask import Flask, render_template
    from flask_socketio import SocketIO, emit
    from threading import Thread
    from queue import Queue
    import os
    app = Flask(__name__)
    
    app.config['SECRET_KEY'] = 'secret!'
    # app.app_context().push()
    async_mode = "gevent"
    
    socketio = SocketIO(app, cors_allowed_origins="*", async_mode=async_mode)
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    @socketio.on('connect')
    def test_connect(data): 
        print("connected", data)
        socketio.emit('flaskMessage', {'data': "connected"})
    
    @socketio.on('disconnect')
    def test_disconnect():
        print('Client disconnected')
    
    def emitMessage(data):  
        print("Got", data)
        socketio.emit('optimusMsg', {'data': data})
    
    # for multi threading
    def wrapper(queue, func, arg=None):
        if type(arg) == list: 
            return queue.put(func(*arg))
        else: 
            if arg is None: 
                return queue.put(func())
            else: 
                return queue.put(func(arg))
    
    def runApp():
        certificatePath = os.getenv('BASE_URL')+"Flask/SSL/"
        key = certificatePath+"localhost.key"
        certificate = certificatePath+"localhost.crt"
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        context.load_cert_chain(certificate, key)
        socketio.run(app, host="192.168.1.5", port=3000,ssl_context=context)
    
    q1 = Queue()
    t = Thread(target=wrapper, args=(q1, runApp))
    t.start()

Client:

```

$(document).ready(function(){ var socket = io.connect("https://192.168.1.5:3000"); socket.on('flaskMessage', function(msg) { console.log("flaskMessage recieving: ", msg.data) $('#log').html(msg.data); });

socket.on('optimusMsg', function(msg) {
console.log("optimusMsg recieving: ", msg.data)
$('#log2').html("Got: "+msg.data);
});

});

miguelgrinberg commented 1 year ago

I think the problem here is that you are not following the rules for writing an asynchronous application, either with eventlet or gevent. My suggestion is that if you don't want to worry about learning a new programming paradigm you use the threading async mode, which should be compatible with your current design.

shyam3089 commented 1 year ago

Thank you for the response. With threadingas async mode application is working as expected. But I get this warning :- The WebSocket transport is not available, you must install a WebSocket server that is compatible with your async mode to enable it. See the documentation for details. (further occurrences of this error will be logged with level INFO). Is there any way to fix this?