-2

I am using the following code to implement a web server using Flask and socketio.

app = Flask(__name__, static_url_path = '', static_folder = 'static', template_folder = 'templates')
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins = '*', ping_timeout = 10, ping_interval = 1)
CORS(app)

USE_ENCRYPTION = False

class Server():

    def __init__(self):
        pass
    
    @app.route("/", methods = ['GET'])
    def index():
        return render_template('index.html')
    
    @socketio.on('connect', namespace = '/home')
    def messaging():
        #print('User connected')
        pass

    @socketio.on('disconnect')
    def messagingOf():
        #print('User disconnected')
        pass

    @socketio.on('my recon', namespace = '/home')
    def getmes(message, methods = ['GET', 'POST']):
        self.SendMessageToClient('home event', messages.messages.home_page_message, '/home')

    
    def SendMessageToClient(self, event, message, namespace_):
        if (USE_ENCRYPTION):
            socketio.emit(event, crypto.Crypto.Encrypt(message), namespace = namespace_)
        else:
            socketio.emit(event, message, namespace = namespace_)
    
    def ReceiveMessageFromClient(self, message):
        if (USE_ENCRYPTION):
            return crypto.Crypto.Decrypt(message)
        return message

    def Start(self):
        socketio.run(app, host = '0.0.0.0', port = 5000, debug = False)

The problem is that I get the error:

line 55, in getmes
    self.SendMessageToClient('home event', messages.messages.home_page_message, '/home')
NameError: name 'self' is not defined

If I use static methods instead, it works. E.g.:

@staticmethod
def SendMessageToClient(event, message, namespace_):
    if (USE_ENCRYPTION):
        socketio.emit(event, crypto.Crypto.Encrypt(message), namespace = namespace_)
    else:
        socketio.emit(event, message, namespace = namespace_)

Server.SendMessageToClient('home event', messages.messages.home_page_message, '/home')

Why do I get the NameError? Also, how can I avoid using static methods in this case?

Cristian M
  • 195
  • 1
  • 1
  • 15
  • 2
    Where do you think `self` is defined in the first case? It's not in the method's argument list, and the method doesn't define it, so it's an undefined name. There's nothing magic about the name `self`, and Python will never automatically define it for you. It's undefined because *you* didn't define it. – Tom Karzes Aug 12 '21 at 11:31
  • It's also missing from almost all of your methods. – Thierry Lathuille Aug 12 '21 at 11:33
  • 1
    Did you mean to use [Class-Based Namespaces](https://python-socketio.readthedocs.io/en/latest/client.html#class-based-namespaces)? It seems that is the way to allow methods to keep the `self` parameter. – quamrana Aug 12 '21 at 11:36
  • @quamrana Thanks. So it is due to the decorator style of defining methods imposed by the socket.io library. In this case it is easier for me to use static methods. You can post this answer. – Cristian M Aug 12 '21 at 11:44

1 Answers1

1

Did you mean to use Class-Based Namespaces? It seems that is the way to allow methods to keep the self parameter.

I found this link and I reproduce the code below:

class MyCustomNamespace(socketio.ClientNamespace):
    def on_connect(self):
        pass

    def on_disconnect(self):
        pass

    def on_my_event(self, data):
        self.emit('my_response', data)

sio.register_namespace(MyCustomNamespace('/chat'))

I know nothing about socketio, but it seems to me that you pick the name of the method from the event you need to handle. All the methods being ordinary instance methods means that they have to have the self parameter, which means that you can refer to other attributes through self.

quamrana
  • 37,849
  • 12
  • 53
  • 71