title: pyserial reading serial port in flask (maybe using gevent)
body: <p>I'm building a webserver that would need to read (and keep reading) the serial port of the machine it's running on.<br>
  The purpose is to be able to read a barcode scanner, and using Server-Sent Events to update a browser with the read barcode.  </p>
  
  <p>I'm using flask to do this. I've browsed around and some implementations require only flask, some say I would need an async library like Gevent, and some others even say I'd need Gevent and some sort of queue like Redis or RabbitMQ.  </p>
  
  <p>I've tried to base my code on a very simple example I found on stackoverflow <a href="https://stackoverflow.com/questions/12232304/how-to-implement-server-push-in-flask-framework">here</a>. I have it mostly working, but I am stuck with some questions;</p>
  
  <ul>
  <li>In Chrome there is a cross-origin error, by adding an
  Access-Control-Allow-Origin header I can get it to work in FireFox,
  but Chrome still doesn't work. Is it correct that only FF supports
  SSE cross-origin? I need it to support CORS because the browser will
  need to load the barcode data from a separate machine.</li>
  <li>After each message, the browser shows the barcode in the console, but
  it then closes the connection and only opens it again after about 3
  seconds. It seems that this originates in Flask, it gives me the data
  and then just stops.</li>
  <li>Also, I'm wondering how this will perform under load. I mean, flask
  keeps a connection open for the text/event-stream mimetype. If
  multiple clients connect, won't it block flask after a while, because
  all of the connections will be saturated?</li>
  </ul>
  
  <p>My code is as follow (shortened for clarity)</p>
  
  <p>Server-side:</p>
  
  <pre><code>from flask import Flask
  import flask
  import serial
  
  app = Flask(__name__)
  app.debug = True
  
  def event_barcode():
      ser = serial.Serial()
      ser.port = 0
      ser.baudrate = 9600
      ser.bytesize = 8
      ser.parity = serial.PARITY_NONE
      ser.stopbits = serial.STOPBITS_ONE
      ser.open()
      s = ser.read(7)
      yield 'data: %s\n\n' % s
  
  @app.route('/barcode')
  def barcode():
      newresponse = flask.Response(event_barcode(), mimetype="text/event-stream")
      newresponse.headers.add('Access-Control-Allow-Origin', '*')
      return newresponse
  
  if __name__ == '__main__':
      app.run(port=8080, threaded=True)
  </code></pre>
  
  <p>Client-side:</p>
  
  <pre><code>    &lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
      &lt;meta http-equiv=Content-Type content="text/html; charset=utf-8"&gt;
      &lt;title&gt;TEST&lt;/title&gt;
      &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js" type="text/javascript" charset="utf-8"&gt;&lt;/script&gt;
      &lt;script&gt;
  
          $(document).ready(function(){
              if (!!window.EventSource) {
                  console.log('SSE supported.');
                  var source = new EventSource('http://localhost:8080/barcode');
  
                  source.addEventListener('message', function(e) {
                    console.log(e.data);
                  }, false);
  
                  source.addEventListener('open', function(e) {
                    console.log('Connection was opened.');
                  }, false);
  
                  source.addEventListener('error', function(e) {
                    if (e.readyState == EventSource.CLOSED) {
                      console.log('Connection was closed.');
                    }
                  }, false);
  
              } else {
                  console.log('SSE notsupported.');
              }
          });
  
      &lt;/script&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>There is some more information I was looking at here:
  <a href="http://www.socketubs.net/2012/10/28/Websocket_with_flask_and_gevent/" rel="nofollow noreferrer">http://www.socketubs.net/2012/10/28/Websocket_with_flask_and_gevent/</a>
  <a href="http://sdiehl.github.com/gevent-tutorial/#chat-server" rel="nofollow noreferrer">http://sdiehl.github.com/gevent-tutorial/#chat-server</a></p>
  
  <p>I hope someone can clear up my questions, and maybe point me towards some solutions, for the cross-origin and the 3 second delay problem.</p>
  
  <p>Thanks.</p>