django-channels 實現網頁聊天(基於websocket)的demo

前端

  • 建立ws連接
    封裝一個ws類,建立ws每次只需要實例化這個即可

 var NEW_WEBSOCKET = function (room) {
            var self = this
            self.url = 'ws://' + window.location.host + '/ws/chat/' + room + '/';
            self.be_ws_name = '';
            self.servce_id = ''
            //初始化websocket, 建立連接, 定義各個函數
            self.init_ws = function (fun) {
                self.msg_fun = fun
                window.WebSocket = window.WebSocket || window.MozWebSocket;

                if (!window.WebSocket) { // 檢測瀏覽器支持
                    console.error('錯誤: 瀏覽器不支持websocket');
                    return;
                }
                self.ws = new WebSocket(self.url);
                console.log('連接已建立,房間:', room);

                self.ws.onopen = function (res) {
                    console.log('連接成功');
                };

                self.ws.onclose = function (res) {
                    console.log("連接已斷開");
                };

                self.ws.onmessage = function (res) {
                    var data = JSON.parse(res.data);
                    console.log('data--------', data, typeof (data))
                    let message = data.message.text;
                    if (data.message.sender_type == 4) {
                        self.close_connect();
                        return
                    }
                    if (data.message.sender_type == 2 && data.message.to_user == app.username) {
                        console.log(app.username, '收到', data.message.promoter, '的chat消息')
                        if (self.be_ws_name != data.message.promoter) {
                            self.be_ws_name = data.message.promoter
                            app.ws_passageway = true
                            app.chat_ws_connect(data.message.promoter)
                        }

                    }
                    if (data.message.sender_type != 2 && data.message.sender_type != 3) {
                        if (data.message.username == app.username) {
                            app.append_msg_node(data.message.text, 'me')
                        } else {
                            app.append_msg_node(data.message.text, 'he')
                        }
                        return
                    }


                };
                self.ws.onerror = function (err) {
                    console.log("連接WebSocket失敗:", err)
                };

                window.onbeforeunload = function (e) {
                    try {
                        console.log("頁面退出,關閉連接");
                        self.close_connect()
                    } catch (e) {
                        console.log("關閉連接出錯:", e)
                    }
                    e.returnValue = ''
                }

            };
            self.article_send_msg = function (msg_obj) {
                // 發送消息
                self.ws.send(JSON.stringify({
                    message: msg_obj
                }));


            };

            self.close_connect = function () {
                self.ws.close();
                console.log('斷開連接...');

            }


        };

示例:

 // 公共房間  傳入的參數爲ws連接的標誌
  self.ws_obj = new NEW_WEBSOCKET(self.public_room)
  self.ws_obj.init_ws()
後端交給channels處理

這裏是它的官網
裏面有一個教程 就是實現基本的聊天

# chat/consumers.py
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json


class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name
        print('房間', self.room_name)

        # Join room group
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )

        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        async_to_sync(self.channel_layer.group_discard)(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']
        print('收到的消息:',message)

        # Send message to room group
        async_to_sync(self.channel_layer.group_send)(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )
        print(f'{self.room_group_name}發送的消息:',message)

    # Receive message from room group
    def chat_message(self, event):
        message = event['message']

        # Send message to WebSocket
        self.send(text_data=json.dumps({
            'message': message
        }))

效果如下
  • 用戶lufy好友niko在線
    在這裏插入圖片描述

  • lufy收到niko的消息
    在這裏插入圖片描述

  • 互相發送消息

在這裏插入圖片描述

  • 這裏的消息 做了sessionStorage消息存儲 刷新後會顯示歷史消息

tips

  • 這裏的用戶頭像我在前端寫死的(本來想自定義的,但畢竟是一個demo,就沒有做)
  • 這裏的好友列表是存在redis裏的
  • redis裏的數據沒有刪除,所以一直會有用戶。。。
  • 代碼已放置GitHub
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章