fanout / django-eventstream

Server-Sent Events for Django
MIT License
650 stars 85 forks source link

send_event function does not work on linux server #41

Open Moshikol opened 4 years ago

Moshikol commented 4 years ago

Hi guys,
I'm using Django-eventstream over Django channels to send an event to my client app,
on my local machine, the events are sent correctly to the client.
but when I upload the app to my Linux server the webhook just getting open and 'keep-alive' but the events won't get to the client at all. I use daphne to deploy my Asgi app and use Nginx as my getaway.
when I use python manage.py runserver (on the Linux server) the client is getting the messages.
I don't see the events trying to be sent in the daphne logs as well.
does anyone have a clue why this is happening? Thanks!

jkarneges commented 4 years ago

Make sure you're not using multiple daphne processes. Multiple threads is fine.

Moshikol commented 4 years ago

Make sure you're not using multiple daphne processes. Multiple threads is fine.

I have only one process of daphne running along side gunicorn which run my WSGI app. Here is the command i use for running my daphne server daphne --verbosity 3 -p 8001 my_project.asgi:application

here is my Daphne log:

06/12/2019 14:52:34] INFO [daphne.cli:287] Starting server at tcp:port=8001:interface=127.0.0.1
2019-12-06 14:52:34,376 INFO     Starting server at tcp:port=8001:interface=127.0.0.1
[06/12/2019 14:52:34] INFO [daphne.server:311] HTTP/2 support enabled
2019-12-06 14:52:34,377 INFO     HTTP/2 support enabled
[06/12/2019 14:52:34] INFO [daphne.server:311] Configuring endpoint tcp:port=8001:interface=127.0.0.1
2019-12-06 14:52:34,377 INFO     Configuring endpoint tcp:port=8001:interface=127.0.0.1
[06/12/2019 14:52:34] INFO [daphne.server:131] HTTPFactory starting on 8001
2019-12-06 14:52:34,378 INFO     HTTPFactory starting on 8001
[06/12/2019 14:52:34] INFO [daphne.server:131] Starting factory <daphne.http_protocol.HTTPFactory object at 0x7fb1fd600cf8>
2019-12-06 14:52:34,378 INFO     Starting factory <daphne.http_protocol.HTTPFactory object at 0x7fb1fd600cf8>
[06/12/2019 14:52:34] INFO [daphne.server:654] Listening on TCP address 127.0.0.1:8001
2019-12-06 14:52:34,379 INFO     Listening on TCP address 127.0.0.1:8001
[06/12/2019 14:52:38] DEBUG [daphne.http_protocol:160] HTTP b'GET' request for ['127.0.0.1', 49034]
2019-12-06 14:52:38,215 DEBUG    HTTP b'GET' request for ['127.0.0.1', 49034]
[06/12/2019 14:52:38] DEBUG [daphne.http_protocol:246
jkarneges commented 4 years ago

I just did some testing of the examples in this repo, and the chat example works fine with runserver or daphne, but I noticed the time example only works with runserver. For some reason time's background thread doesn't get triggered when running with daphne.

Are you doing something like the time example, where the events come from something in the background rather than triggered by a client request?

Moshikol commented 4 years ago

I just did some testing of the examples in this repo, and the chat example works fine with runserver or daphne, but I noticed the time example only works with runserver. For some reason time's background thread doesn't get triggered when running with daphne.

Are you doing something like the time example, where the events come from something in the background rather than triggered by a client request?

I call the send_event in django view ( with some logic) which triggered on an API call. Do you have any idea what the difference between the two repos?

jkarneges commented 4 years ago

Hard to say. You could try using the same dependency versions as the chat example (I just updated them to the latest), or deploy the chat example in an environment similar to your production environment to compare.

Moshikol commented 4 years ago

Maybe its related to the channel routing difference the chat app uses the formatted channel type and the time app uses channel. So my next move is to try to find the difference between my dependencies and the chat app dependencies hope it would help

Moshikol commented 4 years ago

If you have any other suggestions im open to hear Thanks

Moshikol commented 4 years ago

still no luck ..

jkarneges commented 4 years ago

What if you deploy the chat example as-is? Does it work for you?

Moshikol commented 4 years ago

@jkarneges can you guide me a bit on how to deploy it ? i tried doing it with daphne on my local machine and it did not work.. maybe im missing somthing

jkarneges commented 4 years ago

What problem did you get? Note that the static files won't be served if daphne is run directly. I tried first with runserver in order to load the page along with the static assets. Then specify a nickname to join the default room. Then once the room loaded, I ctrl-c the runserver and launch daphne:

daphne server.asgi:application

Then wait a moment and the room reconnects. If I send a message it works.

diogonfs commented 4 years ago

I know it is been a while, but i'm having the same problem here, my daphne is ok, the connection is ok, but the send_event never reach the client, the stream gets only keep-alive. It happens only in production, any help will be appreciated!

diogonfs commented 4 years ago

I have one daphne instance. My deploy is daphne + uwsgi with nginx, where certain urls are directed to daphne. Does the send_event code has to be executed from a view called by an asgi url?

jkarneges commented 4 years ago

Hi @diogonfs , it should be okay to call send_event from anywhere within the process, for example from a spawned thread rather than from a view.

diogonfs commented 4 years ago

Thanks for the help! My nginx redirects some url calls to daphne while the others are served by uwsgi, i think the problem is that my send_event is callled when one of my uwsgi urls is called (is not exactly in the view, but in a code that gets called when a view is executed) and so from another process. In this case, the send_event should have been called from the daphne served url to be executed from the same process, right?

jkarneges commented 4 years ago

Indeed, if you call send_event from the uwsgi process then nothing will happen.

paolodina commented 4 years ago

@Moshikol for reference, I also had the same issue in production while all the configurations were OK (or at least I think), but no luck. I solved using hypercorn instead of daphne and everything worked at the first time, I just had to disable gzip compression for the /events url. Using daphne I had another issue (for some reason the request object was an empty string in some view), also solved using the other server.

mando238 commented 4 years ago

@paolodina I'm having some similar issues though hypercorn alone didn't solve it for me - how did you disable gzip compression just just the /events url?

paolodina commented 4 years ago

@mando238 with Caddy2 the conf is

example.com {
    @notGzip {
        not path /events*
    }
    encode @notGzip gzip
    reverse_proxy 127.0.0.1:8000
    file_server
}
Kurloc commented 4 years ago

Indeed, if you call send_event from the uwsgi process then nothing will happen.

I might be dumber than the average Dev, but it took me a little while to figure out this was my issue on my production server. I had to redirect all the views that had send_event() in them to my Daphne server with Nginx.

What really threw me for a loop is it mysteriously worked when I first set it up and then it just stopped sending the messages the next day.

A note below, "To send data to clients, call send_event:", that says, "send_event() must be called from ASGI in production. Calling send_event() from uwsgi will cause messages to go no where without error.", would probably help :)

I know the ASGI server is implied since I was serving it through Channels but still it's a nice bit of text to be able to find with ctrl+f.

oruehenbeck commented 3 years ago

A note below, "To send data to clients, call send_event:", that says, "send_event() must be called from ASGI in production. Calling send_event() from uwsgi will cause messages to go no where without error.", would probably help :)

I run the same setup, including nginx + uwsgi and events views redirected to daphne. You need to install django-grip and a GRIP proxy like pushpin which will manage routing the events from your uwsgi processes to the proper channels. It works and there is a line in the docs that suggests as much. ;)