guozewei0 2020-04-26
在原有的Django项目中,增加实时通信的功能,用websocket实现,简单记录一下过程,备忘。
1、安装channels、channels-redis、django-redis。
2、在主应用magic_chat目录下新建rounting.py,配置application值。
3、在应用chat_msg目录下新建rounting.py,配置websocket_urlpatterns。
4、在应用chat_msg目录下新建consumers.py,主要逻辑处理都是在这里,相当于views.py。
5、settings里面设置:APP中加入channels;REDIS_HOST、REDIS_PORT;ASGI_APPLICATION、CHANNEL_LAYERS。
6、在主应用magic_chat目录下新建utils目录,在utils目录下新建token_auth.py,放token鉴权的代码(针对websocket);能生效是因为magic_chat/rounting.py里面配置了application的属性。
7、开始编写consumers.py代码。consumers.py主要就是ChatConsumer类,里面有connect\disconnect\receive等函数。
(1)connect函数,Websocket连接。用到了redis.set_user_status函数(在magic_chat/utils新建redis.py,里面是读写redis数据库的代码)。
(2)disconnect函数,断开Websocket连接。
(3)receive函数,服务端接收到消息后的处理;写入长期数据库,并发送websocket消息,即兼容离线和在线用户的使用;用到了下面写的chat_message函数(发送实时消息)。
(4)chat_message函数,给 group 中的用户发送一次消息。
8、开启服务(runserver),开始测试。
9、需要用chrome浏览器的扩展程序smart web client来测,下载安装此插件。
10、smart web client中输入地址,格式如下:ws://127.0.0.1:8000/ws/chat/?token=bc1190581ede19fb34b84ead5faf1a2452b1e13e
点“connect”连接。
11、ws连接不上的原因:
(1)报错:“Failure instance: Traceback: <class ‘ValueError‘>: dictionary update sequence element #0 has length 1; 2 is required”,
原因:token没给出或错误;
解决办法:拿到正确token,以正确格式输入
(2)报错:“redis.exceptions.ConnectionError:”,
原因:redis服务没启动;
解决办法:a.(貌似很麻烦,而且得在linux下)
<1>装docker,
<2>下镜像https://hub.docker.com/_/redis/,
<3>起redis服务:
$ docker run --name some-redis -d redis
b. <1>下载并安装Redis-x64-3.0.503.msi,地址:https://github.com/MicrosoftArchive/redis/releases
<2>安装完成后,启动服务(找到安装路径,双击redis-cli.exe文件即可)
12、在smart web client发送的字段类似下面(注意必须用双引号):
{"message":"Are you busy today?","to_user_id":"222"}