使用 django 通道和 websockets
Working with django channels and websockets
我在 127.0.0.1:8000/dashboard/ 有一个用于输入线坐标的表单和一个用于提交坐标的 "Ok" 按钮。通过调用视图 LineDisplay()
,坐标发布在 127.0.0.1:8000/api/line/。这里我想把Line坐标推回127.0.01:8000/dashboard/.
到目前为止我做了以下事情:
urls.py:
from django.conf.urls import url,include
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^api/line/$',views.LineDisplay.as_view()),
]
view.py:
class LineDisplay(APIView):
"""
Display the most recent line
"""
def get(self, request, format=None):
lines = Line.objects.all()
serializer = LineSerializer(lines, many=True)
return Response(serializer.data)
def post(self, request, format=None):
lines = Line.objects.all()
for line in lines:
line.delete();
serializer = LineSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
info = ""
info += "Line Coordinates are: "
lines = Line.objects.all()
for line in lines:
info += "x1:" + str(line.x1)
info += " y1:" + str(line.y1)
info += " x2:" + str(line.x2)
info += " y2:" + str(line.y2)
print info
Channel('repeat-me').send({'info': info, 'status': True})
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
consumers.py
import json
# In consumers.py
from channels import Group
# Connected to websocket.connect
def ws_add(message):
Group("chat").add(message.reply_channel)
# Connected to websocket.receive
def ws_message(message):
print "Receive Message now"
Group("chat").send({
"text": json.dumps({'status': False})
})
# Connected to websocket.disconnect
def ws_disconnect(message):
Group("chat").discard(message.reply_channel)
def repeat_me(message):
Group("chat").send({
"text": json.dumps({'status': message.content['status'], 'info':
message.content['info']})
})
同样,我添加了以下代码:routing.py
from channels.routing import route
from .consumers import ws_add, ws_message, ws_disconnect, repeat_me
channel_routing = [
route("websocket.connect", ws_add),
route("websocket.receive", ws_message),
route("websocket.disconnect", ws_disconnect),
route("repeat-me", repeat_me),
]
已将以下行添加到 settings.py:
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgiref.inmemory.ChannelLayer",
"ROUTING": "TrainingInduct.routing.channel_routing",
},
}
目前不知道怎么跟群打交道"chat"。我什至不需要一个小组。为了让线坐标在新线发布后立即显示在 127.0.0.1:8000/dashboard/ 还需要做什么?
注意:线坐标已正确发布到 /api/line/ 我想我可能必须编写服务器代码才能从通道并将其推回,我说得对吗?谢谢。
您需要该组收集所有应该接收您的信息的频道。每个连接的设备都有一个频道。
设备的频道标识符在 message.reply_channel
中。群组只是收集所有 message.reply_channel
的一种方式。
因此,假设任何打开您的 /dashboard/
页面的用户都会收到发布的任何新 "info" 项目。首先,您需要记住新客户的频道。这就是你 ws_add
的目的
def ws_add(message):
Group("all-my-clients").add(message.reply_channel)
现在刚刚连接的客户端是 all-my-clients
组的一部分,您通过 all-my-clients
发送的任何消息也会自动发送到该客户端。
当然你想清理自己,所以这就是 ws_disconnect
的目的。在他们执行 WebSocket.close() 或关闭浏览器等后删除客户端
def ws_disconnect(message):
Group("all-my-clients").discard(message.reply_channel)
最后,还有你的 ws_message()
。它接收任何传入的消息。
def ws_message(message):
# Nothing to do here, because you only push, never receive.
pass
就是这样。现在您可以从 Django 中的任何地方向您在上面定义的组发送消息。只要确保您以正确的格式发送响应即可。 Group().send()
接受一个 dict
和一个具有字符串值的键 text
(见下文)。原因是您还可以发送其他数据类型,例如 blob。但是 "text" 最适合这个目的。
def post(self, request, format=None):
lines = Line.objects.all()
...
print info
response_data = {'info': info, 'status': True}
Group("all-my-clients").send({
'text': json.dumps(response_data)
})
return Response(serializer.data, status=status.HTTP_201_CREATED)
应该就这些了。
我在 127.0.0.1:8000/dashboard/ 有一个用于输入线坐标的表单和一个用于提交坐标的 "Ok" 按钮。通过调用视图 LineDisplay()
,坐标发布在 127.0.0.1:8000/api/line/。这里我想把Line坐标推回127.0.01:8000/dashboard/.
到目前为止我做了以下事情:
urls.py:
from django.conf.urls import url,include
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^api/line/$',views.LineDisplay.as_view()),
]
view.py:
class LineDisplay(APIView):
"""
Display the most recent line
"""
def get(self, request, format=None):
lines = Line.objects.all()
serializer = LineSerializer(lines, many=True)
return Response(serializer.data)
def post(self, request, format=None):
lines = Line.objects.all()
for line in lines:
line.delete();
serializer = LineSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
info = ""
info += "Line Coordinates are: "
lines = Line.objects.all()
for line in lines:
info += "x1:" + str(line.x1)
info += " y1:" + str(line.y1)
info += " x2:" + str(line.x2)
info += " y2:" + str(line.y2)
print info
Channel('repeat-me').send({'info': info, 'status': True})
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
consumers.py
import json
# In consumers.py
from channels import Group
# Connected to websocket.connect
def ws_add(message):
Group("chat").add(message.reply_channel)
# Connected to websocket.receive
def ws_message(message):
print "Receive Message now"
Group("chat").send({
"text": json.dumps({'status': False})
})
# Connected to websocket.disconnect
def ws_disconnect(message):
Group("chat").discard(message.reply_channel)
def repeat_me(message):
Group("chat").send({
"text": json.dumps({'status': message.content['status'], 'info':
message.content['info']})
})
同样,我添加了以下代码:routing.py
from channels.routing import route
from .consumers import ws_add, ws_message, ws_disconnect, repeat_me
channel_routing = [
route("websocket.connect", ws_add),
route("websocket.receive", ws_message),
route("websocket.disconnect", ws_disconnect),
route("repeat-me", repeat_me),
]
已将以下行添加到 settings.py:
CHANNEL_LAYERS = {
"default": {
"BACKEND": "asgiref.inmemory.ChannelLayer",
"ROUTING": "TrainingInduct.routing.channel_routing",
},
}
目前不知道怎么跟群打交道"chat"。我什至不需要一个小组。为了让线坐标在新线发布后立即显示在 127.0.0.1:8000/dashboard/ 还需要做什么?
注意:线坐标已正确发布到 /api/line/ 我想我可能必须编写服务器代码才能从通道并将其推回,我说得对吗?谢谢。
您需要该组收集所有应该接收您的信息的频道。每个连接的设备都有一个频道。
设备的频道标识符在 message.reply_channel
中。群组只是收集所有 message.reply_channel
的一种方式。
因此,假设任何打开您的 /dashboard/
页面的用户都会收到发布的任何新 "info" 项目。首先,您需要记住新客户的频道。这就是你 ws_add
的目的
def ws_add(message):
Group("all-my-clients").add(message.reply_channel)
现在刚刚连接的客户端是 all-my-clients
组的一部分,您通过 all-my-clients
发送的任何消息也会自动发送到该客户端。
当然你想清理自己,所以这就是 ws_disconnect
的目的。在他们执行 WebSocket.close() 或关闭浏览器等后删除客户端
def ws_disconnect(message):
Group("all-my-clients").discard(message.reply_channel)
最后,还有你的 ws_message()
。它接收任何传入的消息。
def ws_message(message):
# Nothing to do here, because you only push, never receive.
pass
就是这样。现在您可以从 Django 中的任何地方向您在上面定义的组发送消息。只要确保您以正确的格式发送响应即可。 Group().send()
接受一个 dict
和一个具有字符串值的键 text
(见下文)。原因是您还可以发送其他数据类型,例如 blob。但是 "text" 最适合这个目的。
def post(self, request, format=None):
lines = Line.objects.all()
...
print info
response_data = {'info': info, 'status': True}
Group("all-my-clients").send({
'text': json.dumps(response_data)
})
return Response(serializer.data, status=status.HTTP_201_CREATED)
应该就这些了。