Let's say I have a vue client trying to receive an event from a private channel using pusher
services.
This client autenticates using pusher auth secuence:
Here are the docs: https://pusher.com/docs/channels/server_api/authenticating-users/
Seems I need to provide an endpoint on my server in order to autenticate the user.
So, as the docs says, since my server is in a different domain to the front-end app, I need to use CORS
or JSONP
, I choose JSONP.
My server (backend) is made in Django
using django-rest-framework
and it provides an endpoint that is responsible to process the socket_id
, the channel_name
and the callback
that the pusher-js
(which is a pusher frontend library) generates.
Something alike to a javascript code is sent to the frontend, so the response needs to be content-type:application/javascript
.
In order to test the event, I made a simple python script which I will later integrate to my bussiness logic. This script is the responsible to trigger the event.
The problem: The main problem is the event never arrives. I looked up into the web-console (frontend) to check the correct function of the requests. The ws protocol
requests responds with status 101
and the endpoint /auth/pusher
with status 200
. So they seem to work correctly.
/auth/pusher
endpoint:def get(self, request): pusher_client = pusher.Pusher( app_id = settings.P_APP_ID, key = settings.P_APP_KEY, secret = settings.P_APP_KEY_SECRET, cluster = settings.P_REGION_CLUSTER, ssl = True ) auth = pusher_client.authenticate( channel=request.query_params.get('channel_name'), socket_id=request.query_params.get('socket_id') ) callback_query_params = request.query_params.get('callback') callback = re.sub(r'/\\"/g', '', callback_query_params) + "(" + str(auth) + ");"; return Response(callback, content_type = 'application/javascript')
var pusher = new Pusher(env.pusher_app_key, { cluster: 'us2', authTransport: "jsonp", authEndpoint: "http://localhost:8000/pusher/auth", }); var channel = pusher.subscribe('private-cesar'); channel.bind('my-event', function(data) { console.log(data); this.messages.push(JSON.stringify(data)); });
import pusher pusher_client = pusher.Pusher( app_id = settings.P_APP_ID, key = settings.P_APP_KEY, secret = settings.P_APP_KEY_SECRET, cluster = settings.P_REGION_CLUSTER, ssl = True ) while True: option = input("Send? (Y/N)") if option.lower() == "y": pusher_client.trigger('private-cesar', 'my-event', {'message': 'test from python'}) print("Sent") else: break
So, what seems to be the problem here, is there something I'm missing?
I already figured out how to use it without auth, And it works as expected, but in that case I don't need to have a auth/pusher
endpoint.
SOLUTION:
Finally, I solved this. Turns out I needed to return an HttpResponse
object, which is provided by django.http
, not the Response
that rest_framework.response
provides.
My mistake: believing that rest_framework.response
is implicit an http response.
imports:
from django.http import HttpResponse
So the endpoint ended like this:
def get(self, request):
pusher_client = pusher.Pusher(
app_id = settings.P_APP_ID,
key = settings.P_APP_KEY,
secret = settings.P_APP_KEY_SECRET,
cluster = settings.P_REGION_CLUSTER,
ssl = True
)
auth = pusher_client.authenticate(
channel=request.query_params.get('channel_name'),
socket_id=request.query_params.get('socket_id')
)
callback_query_params = request.query_params.get('callback')
callback = re.sub(r'/\\"/g', '', callback_query_params) + "(" + str(auth) + ");";
return HttpResponse(callback, content_type = 'application/javascript')