How do I serve a Websocket Application written in Python using Twisted Framework

218 Views Asked by At

I have written a websocket server application using the Twisted Framework. I am new to this and am trying to figure out how to serve it as an application so I can use NGINX to reverse proxy it.

The main body of the application looks as below:

if __name__ == "__main__":
    #Clear redis cache
    R.flushdb()
    log.startLogging(sys.stdout)
    contextFactory = ssl.DefaultOpenSSLContextFactory('keys/server.key',
                                                          'keys/server.crt')
    ServerFactory = BroadcastServerFactory
    factory = BroadcastServerFactory("wss://127.0.0.1:8080")
    factory.protocol = BroadcastServerProtocol
    resource = WebSocketResource(factory)
    root = File(".")
    root.putChild(b"ws", resource)
    site = Site(root)
    reactor.listenSSL(8080, site, contextFactory)
    reactor.run()

My understanding is that I need to create a WSGI application, but I am confused as how to do this. I am not sure how I change this program into WSGI. When I have worked with Django and Flash they have a WSGI file, but this new project is just a single python file using the Twisted Framework.

Sorry as I am struggling a bit to explain this.

1

There are 1 best solutions below

0
OptimusPrime On

What I have done is change the code so it doesn't have the if statement anymore and looks as below:

#New imports
from twisted.application import internet,service

#Bottom of file
R.flushdb()
log.startLogging(sys.stdout)
contextFactory = ssl.DefaultOpenSSLContextFactory('keys/server.key',
                                                        'keys/server.crt')
ServerFactory = BroadcastServerFactory
factory = BroadcastServerFactory("wss://127.0.0.1:8080")
factory.protocol = BroadcastServerProtocol
resource = WebSocketResource(factory)
application = service.Application("picserver")
service = internet.TCPServer('8080', factory) 
resource = WSGIResource(reactor, reactor.getThreadPool(), factory)
root = File(".")
root.putChild(b"ws", resource)
site = Site(root)
reactor.listenSSL(8080, site, contextFactory)
service.setServiceParent(application)
reactor.run()

I renamed the file to 'server.tap', but I don't think this is necessary. The code changes then allow me to then run the program as a a daemon using:

twistd -y server.py 

I then created a .service file in /etc/systemd/system as below:

[Unit]
Description=picserver startup script 
After=network.target

[Service]
User=django
Group=www-data
Environment="DBNAME=mydb"
Environment="DBUSER=dbuser"
Environment="DBPASSWORD=password"
ExecStart=/home/<username>/Documents/python/environments/gameservertest/bin/python /home/<username>/Documents/python/environments/gameservertest/bin/twistd -y /home/<username>/Documents/python/picturegameserver/server.tap
WorkingDirectory=/home/<username>/Documents/python/picturegameserver/
Restart=always

[Install]
WantedBy=multi-user.target

I am now able to use "systemctl" to run this as a service and can connect the front end running locally on the server. At the moment, I don't think I will need to configure Nginx to reverse proxy it as I can just have the front end running on the same server.