When I log in to my front end, my self.scope['user'] call in my friends.consumer.py in django channels returns AnonymousUser but when login and call self.scope['user'] in my chat.consumer.py it shows up as the logged in user. For some reason the scope['user'] in one of my apps work and the other one does not. I do not understand what the problem is. I have the routing set up in my django project as this
routing.py
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import chat.routing
import friends.routing
application = ProtocolTypeRouter ({
'websocket': AuthMiddlewareStack(
URLRouter(
friends.routing.websocket_urlpatterns + chat.routing.websocket_urlpatterns
)
)
})
I structure my second consumer.py similarly to my first consumer.py. This is my consumer.py where the scope['user'] works (I didn't need the scope['user'] in the first consumer but I just wanted to test to see if it works
chat.consumer.py
class ChatConsumer(WebsocketConsumer):
...
def connect(self):
print(self.scope['user'])
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
async_to_sync (self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
This code is the consumer where my scope['user'] shows up as anonymous user even after I have logged in.
friends.consumers.py
class FriendRequestConsumer(JsonWebsocketConsumer):
def connect(self):
user = self.scope['user']
grp = 'notifications_{}'.format(user.username)
self.accept()
async_to_sync(self.channel_layer.group_add(grp, self.channel_name))
Here are also my routing.py for each app
friends.routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'^ws/friend-request-notification/$', consumers.FriendRequestConsumer),
]
chat.routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
]
I was able to connected to the websocket for both of them in my reactjs frontend. I know that the AuthMiddlewareStack allows us to pull the scope['user'], I just don't understand why one works and one does. Can it be that I did not connect to the websocket properly in the frontend or I am missing something on one of my consumers? I appreciate the help and thanks in advance.
For connecting to the websocket in my js, I made a chat.js file and a notifications.js
chat.js
class Chat extends React.Component{
...
initialiseChat() {
this.waitForSocketConnection(()=> {
WebSocketInstance.fetchMessages(
this.props.username,
this.props.match.params.id
)
})
WebSocketInstance.connect(this.props.match.params.id)
}
constructor(props){
super(props)
this.initialiseChat()
}
notifications.js
class Notifications extends React.Component{
...
initialiseNotification(){
this.waitForSocketConnection(() => {
NotificationWebSocketInstance.fetchFriendRequests(
this.props.id
)
})
NotificationWebSocketInstance.connect()
}
constructor(props){
super(props)
this.initialiseNotification()
}
Here are my websocket actions:
webosocket.js (this connect function gets called in the chat.js)
class WebSocketService {
...
connect(chatUrl) {
const path ='ws://127.0.0.1:8000/ws/chat/'+chatUrl+'/';
console.log(path)
this.socketRef = new WebSocket(path)
this.socketRef.onopen = () => {
console.log('websocket open')
}
...
const WebSocketInstance = WebSocketService.getInstance();
export default WebSocketInstance;
Here is the websocket for the notification.js
notificationWebsocket.js
class WebSocketNotifications {
...
connect(){
const path = 'ws://127.0.0.1:8000/ws/friend-request-notification/'
console.log(path)
this.socketRef = new WebSocket(path)
this.socketRef.onopen = () =>{
console.log('websocket open')
}
...
const NotificationWebSocketInstance =
WebSocketNotifications.getInstance();
export default NotificationWebSocketInstance;
And here are the routes.js
class BaseRouter extends React.Component {
<Route exact path = '/chat/:id' render={(props) => <Chat {...props}
{...this.props} isAuthenticated={this.props.isAuthenticated} />}
/>
<Route exact path = '/notifications/' render={(props) =>
<Notifications {...props} {...this.props} isAuthenticated=
{this.props.isAuthenticated} />} />