Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request object has no attribute namespace/Client says its connected but server doesn't #40

Closed
collinalexbell opened this issue Jul 7, 2014 · 7 comments
Labels

Comments

@collinalexbell
Copy link

Here is my code:

from flask import Flask
from flask import render_template, redirect, url_for
from flask import request
from flask import Response
from flask.ext.socketio import SocketIO, emit
import os
import workout as w

tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(file)), 'templates')
app = Flask(name, template_folder=tmpl_dir)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route('/')
def home():
print ("Home")
return render_template('home.html')

@app.route('/workout', methods = ['POST'])
def workout():
emit('movement', 'That worked')
w.start_workout(5, 10)
return redirect(url_for('home'))

@socketio.on('connect', namespace='/')
def connect():
print ("We have connected to socketio")

if (name == "main"):
app.debug = True
socketio.run(app)

My Summary

we_are_connected is not firing although socket.on(connect, ....) in the client is executing the callback

Error(The part of it that matters)

emit('movement', 'That worked')
File "/usr/lib/python2.7/site-packages/flask_socketio/init.py", line 230, in emit
return request.namespace.emit(event, _args, *kwargs)
File "/usr/lib/python2.7/site-packages/werkzeug/local.py", line 338, in getattr
return getattr(self.get_current_object(), name)
AttributeError: 'Request' object has no attribute 'namespace'
{'CONTENT_LENGTH': '23',
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,
/
;q=0.8',
'HTTP_ACCEPT_ENCODING': 'gzip,deflate,sdch',
'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8',
'HTTP_CACHE_CONTROL': 'max-age=0',
'HTTP_CONNECTION': 'keep-alive',
'HTTP_HOST': 'localhost:5000',
'HTTP_ORIGIN': 'http://localhost:5000',
'HTTP_REFERER': 'http://localhost:5000/',
'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36',
'PATH_INFO': '/workout',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '52426',
'REQUEST_METHOD': 'POST',
'SCRIPT_NAME': '',
'SERVER_NAME': 'localhost.localdomain',
'SERVER_PORT': '5000',
'SERVER_PROTOCOL': 'HTTP/1.1',
'SERVER_SOFTWARE': 'gevent/1.0 Python/2.7',
'werkzeug.request': <Request 'http://localhost:5000/workout' [POST]>,
'wsgi.errors': <open file '', mode 'w' at 0xb73780d0>,
'wsgi.input': <gevent.pywsgi.Input object at 0xb6872c8c>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)} failed with AttributeError

@collinalexbell collinalexbell changed the title Request object has no attribute namespace/Client says we connect but server doesn't Request object has no attribute namespace/Client says its connected but server doesn't Jul 7, 2014
@miguelgrinberg
Copy link
Owner

When you want to emit from a regular route you have to use socketio.emit(), only socket handlers have the socketio context necessary to call the plain emit().

@seandmatthews
Copy link

Hey Miguel, I love your work, but as a first time user of this library this issue did catch me.
It's mentioned briefly in your documentation, here,

"Note that socketio.send() and socketio.emit() are not the same functions as the context-aware send() and emit()."

and obviously I found this answer in Google, but it may be worth it to make a small note in the flask-socketio documentation highlighting this potential stumbling block.

Anyway, I'm looking forward to your new flask mega-tutorial, and thanks again for all you do.

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Nov 7, 2017

@NotLeet If you are working with Flask, then you should, in general, use emit(), which is context-aware, so it works well in a Flask event handler. If you want to emit from a background thread, you can copy the request context and still use emit().

The socketio.emit() method gives you direct access to the Socket.IO engine, without the Flask wrapper. You may want to use this function, I guess, but you don't really need to. You make it sound like these two emit options are at the same level but they are not. The emit() function is Flask specific, socketio.emit() is not, and in fact, emit() is implemented by calling the lower level socketio.emit().

So what do you think the documentation should say? I would rather you always use emit(), there is no use case where emit() wouldn't work, as long as you have a Flask request context.

@linuxson27
Copy link

linuxson27 commented May 17, 2018

Hi, been struggling with whether to use socketio.emit() and emit() myself...have a Flask application where I am just trying to emit a signal server side to the client to confirm that a MongoDB insert() method has indeed fired and completed. After hours of pulling my hair out, I finally came across this thread, and noticed the use of just emit(), which I have implemented (see below):

@app.route('/', methods=['GET', 'POST'])
def home():
    register_form = RegisterForm()

    if register_form.validate_on_submit():
        users = mongo.db.users

        users.insert({
            'user': register_form.name.data,
            'password': register_form.password.data,
            'role': register_form.role.data})

        def ack():
            print('Message was received')

        emit('name_added', 'User has been added', namespace='/', callback=ack)

    return render_template('index.html', register_form=register_form)

Still finding my feet with Flask, so pardon any bad coding on my behalf. This emit signal is however returning an error: AttributeError: 'Request' object has no attribute 'sid'
How do I fix this?

PS: This is my code client side...

<body>
    <div class="container">
        <div class="d-flex justify-content-center mt-5">
            <div class="w-25 text-center mt-5">
                <form method="POST" action="{{url_for('home')}}">
                    {{register_form.csrf_token}}
                    {{register_form.name(class_='form-control font-weight-light mb-4', type='text', placeholder='username')}}
                    {{register_form.password(class_='form-control font-weight-light mb-4', type='password', placeholder='password')}}
                    {{register_form.role(class_='custom-select mt-2 mb-4')}}
                    <button type="submit" id="sendButton" class="btn btn-raised btn-info mt-4 w-100 rounded-0">Send</button>
                </form>
            </div>
        </div>
    </div>

    <script>
        $(document).ready(function() {
            var socket = io.connect('http://127.0.0.1:5000');

            socket.on('name_added', function(data) {
                console.log(data)
            })
        });
    </script>
</body>

@miguelgrinberg
Copy link
Owner

@linuxson27 the emit function tries to send the event back to the sender of an originating event. Since there is no originating event in this case, you have to indicate who the addressee is.

Are you storing the sid value for your clients? You need to add room=sid to the call, with the sid for the client you want to address. You can also pass the name of a room you created, or if you prefer, pass broadcast=True to send the event to all clients.

@tahir80
Copy link

tahir80 commented Dec 3, 2018

Hi Miguel,

I am trying to call socketio.emit function but it did not work.

here is the code:

from app import socketio
from flask_socketio import SocketIO, emit, join_room, leave_room, \
    close_room, rooms, disconnect


def msg_process(msg, tstamp):
     socketio.emit('start_your_task', {'message': [worker.AMT_worker_id]})


@main.route('/api/from', methods = ['GET', 'POST', 'PUT'])
     msg_process(js['Message'], js['Timestamp'])

what I am doing wrong? I did not share the complete code

@miguelgrinberg
Copy link
Owner

@tahir80 what do you mean by "it didn't work"? There isn't anything obviously wrong in the code that you are showing me, the problem must be somewhere else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants