pyserial reading serial port in flask (maybe using gevent)

后端 未结 2 1903
予麋鹿
予麋鹿 2021-02-06 18:48

I\'m building a webserver that would need to read (and keep reading) the serial port of the machine it\'s running on.
The purpose is to be able to read a barcode scanner, an

2条回答
  •  南笙
    南笙 (楼主)
    2021-02-06 19:42

    Answering my own questions

    1. It seems that indeed only Firefox supports CORS for SSE for now -> article
    2. With help from Janus Troelsen I figured out how to keep the connection open and send several barcodes across the line (see code below)
    3. Performance-wise it seems that I can only make one connection, but that might be because I have only one serial port, the subsequent connections can't open the serial port anymore. I think it will work from flask, but something with socketio and gevents will perfom better because it's more suited for the job. There's an interesting article here.

    For the code:

    import flask
    import serial
    from time import sleep
    
    app = flask.Flask(__name__)
    app.debug = True
    
    def event_barcode():
        messageid = 0
        ser = serial.Serial()
        ser.port = 0
        ser.baudrate = 9600
        ser.bytesize = 8
        ser.parity = serial.PARITY_NONE
        ser.stopbits = serial.STOPBITS_ONE
        ser.timeout = 0
        try:
            ser.open()
        except serial.SerialException, e:
             yield 'event:error\n' + 'data:' + 'Serial port error({0}): {1}\n\n'.format(e.errno, e.strerror)
             messageid = messageid + 1
        str_list = []
        while True:
            sleep(0.01)
            nextchar = ser.read()
            if nextchar:
                str_list.append(nextchar)
            else:
                if len(str_list) > 0:
                    yield 'id:' + str(messageid) + '\n' + 'data:' + ''.join(str_list) + '\n\n'
                    messageid = messageid + 1
                    str_list = []
    
    @app.route('/barcode')
    def barcode():
        newresponse = flask.Response(event_barcode(), mimetype="text/event-stream")
        newresponse.headers.add('Access-Control-Allow-Origin', '*')
        newresponse.headers.add('Cache-Control', 'no-cache')
        return newresponse
    
    if __name__ == '__main__':
        app.run(port=8080, threaded=True)
    

    Because I want to support multiple browsers, SSE is not the way to go for me right now. I will look into websockets and try and work from that.

提交回复
热议问题