当我登录到我的前端时,我在django channels中的www.example.com中的self.scope 'user ']调用friends.consumer.py将返回AnkaryousUser,但当登录并调用我在www.example.com中的self.scope 'user']chat.consumer.py,它将显示为登录的用户。由于某种原因,我的一个应用程序中的作用域“用户”可以工作,而另一个不能。我不明白有什么问题。我在我的Django项目中设置了如下路由:
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
)
)
})
我的第二个www.example.com的结构consumer.py与第一个consumer.py类似。这是我的consumer.py,其中作用域['user']工作(在第一个消费者中我不需要作用域['user'],但我只是想测试它是否工作
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()
这段代码是消费者,即使在我登录后,我的作用域[“user”]也显示为匿名用户。
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))
这里也是我的routing.py为每个应用程序
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),
]
我能够在我的reactjs前端连接到它们的WebSocket。我知道AuthMiddlewareStack允许我们拉范围['user'],我只是不明白为什么一个工作,一个做。可能是我没有在前端正确连接到WebSocket,或者我在某个消费者身上缺少了什么?我很感激你的帮助,并提前表示感谢。
为了在我的js中连接到WebSocket,我创建了一个chat.js文件和一个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()
}
以下是我的WebSocket操作:
webosocket.js(此连接函数在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;
下面是notification.js的WebSocket
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;
这里是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} />} />
5条答案
按热度按时间nx7onnlm1#
您可以看到这两个re_path之间
你用
(?P<room_name>\w+)
作为聊天消费者。但在
FriendRequestConsumer
的情况下,你没有使用。在我的情况下,我有同样的问题,我已经添加了一个房间名称没有理由,可以通过任何字符串在该房间名称。但无论如何,我现在可以访问self.scope['user']
。我的asgi.py是这样的
sg3maiej2#
您的令牌中间件一定存在一些问题
qmb5sa223#
虽然在这种情况下这可能不是问题的根源,但这可能有助于像我这样偶然发现这个问题的人。
我的令牌认证系统使用django_rest_knox,认证和登录过程一直运行良好,直到尝试访问
self.scope['user']
中的user值,返回AncourageousUser。事实证明,这就像从django添加登录方法一样简单。
dgiusagp4#
consumers.FriendRequestConsumer.as_asgi()
必须
WebSocket_urlpatterns = [ re_path(r'^ws/friend-request-notification/$',consumers.FriendRequestConsumer.as_asgi()),]
a8jjtwal5#
在脚本中使用此
websoket
路径: